UNRAID使用Traefik反向代理

前言

Traefik是反向代理、负载均衡工具,类似的工具还有nginx的Nginx Proxy Manager和nginxWebUI、SWAG等。

使用NPM对我而言最大的缺点就是不能在设置、变量上改容器http、https默认提供的80、443端口,只能通过端口映射,家宽无这两个端口情况下,想要访问https的页面,首次就只能完整输入https://xxx.com:[https端口];

而使用traefik则可以更改默认端口,且配合跳转实现输入xxx.com:[http端口],网页可以自动跳转到https且https端口。

还有其它优势,自动发现和配置(搭配容器编排工具);动态配置刷新等。

本篇教程为使用docker traefik配合ACME自动管理通过Let’s Encrypt提供的SSL/TLS证书,使用上http重定向到https,即https为主要访问方式。

请搭配自己情况(有无80/443端口、域名托管方)进行配置;

为了方便配置编辑,本篇编辑配置文件为主,权衡好再进行操作。


测试环境

traefik:v2.10.3(2.x与1.x版本差异大)

准备工作

  • cloudflare账号
  • 域名(建议托管到cloudflare)
  • 泛域名dns记录已经指向目标ip

创建cf的api令牌

访问API令牌页面,创建令牌,使用【编辑区域DNS】模板

区域资源,选择指定的域名(特定区域)或改为所有区域

继续,创建令牌,保存好api令牌


创建traefik目录

providers存放手动配置代理文件

logs存放traefik的日志和访问记录

mkdir -p /mnt/user/appdata/traefik/providers
mkdir -p /mnt/user/appdata/traefik/logs

创建ACME文件

为了方便,直接在traefik映射目录下创建acme.json,并给予600的权限,用于存储证书、私钥等信息。

touch /mnt/user/appdata/traefik/acme.json
chmod 600 /mnt/user/appdata/traefik/acme.json

代理通讯容器

默认访问主机上的docker容器如果通过映射/var/run/docker.sock目录的方式,会使对主机docker有完全控制权限,所以建议使用通过“代理”的方式,实现只读访问。

unraid应用搜索dockersocket,存储库为tecnativa/docker-socket-proxy

默认模板配置,其它系统可访问存储库参考

添加端口映射,2375:2375

docker run
  -d
  --name='dockersocket'
  --net='bridge'
  -e TZ="Asia/Shanghai"
  -e HOST_CONTAINERNAME="dockersocket"
  -e 'CONTAINERS'='1'
  -e 'POST'='0'
  -p '2375:2375/tcp'
  -v '/var/run/docker.sock':'/var/run/docker.sock':'ro'
  --restart unless-stopped 'tecnativa/docker-socket-proxy:latest'

应用


安装

unraid应用搜索traefik,点击安装

在默认模板的基础上

为了稳定,存储库建议改为指定tag版本

  1. 默认连接docker容器方式,建议移除,用代理通讯容器方式代替
  2. api变量的key和value根据域名托管方而定,cloudflare则填写上面获取的cf的api令牌
  3. 外网访问traefik面板的域名
  4. 是否开启traefik面板外网访问,true为开启,false为关闭

(此处我为了演示把映射目录改为了traefik_site,下面的traefik目录指的就是这个)

端口方面根据自己需求,确保不冲突,其余暂时不用管。

docker run
  -d
  --name='traefik'
  --net='bridge'
  -e TZ="Asia/Shanghai"
  -e 'CF_DNS_API_TOKEN'='xxx'
  -l 'traefik.http.routers.api.rule'='Host(traefik.example.com)'
  -l 'traefik.http.routers.api.entryPoints'='https'
  -l 'traefik.http.routers.api.service'='api@internal'
  -l 'traefik.enable'='true'
  -p '44301:44301/tcp'
  -p '8001:8001/tcp'
  -p '8185:8184/tcp'
  -p '9080:9080/tcp'
  -p '9443:9443/tcp'
  -p '8184:8080/tcp'
  -v '/mnt/user/appdata/traefik_site':'/etc/traefik':'rw' 'traefik:v2.10.3'

此处我添加映射了将需要使用的9080和9443作为http、https端口

应用运行容器后停止容器。


配置

当traefik启动时,会在下面目录中搜索静态配置文件,配置文件名为traefik.yml (traefik.yaml) 或 traefik.toml

  • /etc/traefik/
  • $XDG_CONFIG_HOME/
  • $HOME/.config/
  • . (工作目录)

所以在/etc/traefik映射目录下创建traefik.yml

nano /mnt/user/appdata/traefik/traefik.yml

内容可在官方提供的sample的基础上参考文档修改:

也可以直接复制这里的模板修改

# traefik.yml

################################################################
# Global configuration
################################################################
global:
  # 新版本检查
  checkNewVersion: true
  # 匿名发送使用统计信息
  sendAnonymousUsage: false

################################################################
# EntryPoints configuration
################################################################

# EntryPoints definition
#
# Optional
#
entryPoints:
  web:
    # http端口,默认80
    address: :80

    http:
      # 重定向,http→https
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    # https端口,默认443
    address: :443
    # tls
    http:
      tls:
        # certResolver为certificatesResolvers中自定义,例如myresolver
        # main为顶级域名,sans是二级域名,可以填泛域名(需要单引号)
        certResolver: myresolver
        domains:
          - main: example.com
            sans:
              - '*.example.com'

  # 除此以外还有tcp、udp、metrics(暴露traefik的数据,可用于显示数据请求,运行状态、流量统计等)
#  metrics:
#    address: :8082

#  tcp:
#    address: :8083

#  udp:
#    address: :8084

# 
serversTransport:
  # 是否跳过证书验证,false时注意连接情况
  # 为true时,traefik会忽略对服务器证书的验证,允许与不受信任或无效证书的服务器建立连接。
  insecureSkipVerify: true

# ssl
certificatesResolvers:
  # 名与上面同名
  myresolver:
    acme:
      email: [email protected]
      # 在traefik容器内acme.json文件目录
      storage: /etc/traefik/acme.json
      dnsChallenge:
        # 域名提供方(dns托管方)
        provider: cloudflare
        # 延迟验证TXT记录,秒
        delayBeforeCheck: 30
        # used during the challenge
#        entryPoint: web

################################################################
# Traefik logs configuration
################################################################

# Traefik logs
# Enabled by default and log to stdout
#
# Optional
# 日志
log:
  # Log level
  #
  # Optional
  # Default: "ERROR"
  #
  level: INFO

  # Sets the filepath for the traefik log. If not specified, stdout will be used.
  # Intermediate directories are created if necessary.
  #
  # Optional
  # Default: os.Stdout
  # 可设置日志输出到文件
  filePath: /etc/traefik/logs/traefik.log

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
#  format: json

################################################################
# Access logs configuration
################################################################

# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
# 访问记录日志
accessLog:
  # Sets the file path for the access log. If not specified, stdout will be used.
  # Intermediate directories are created if necessary.
  #
  # Optional
  # Default: os.Stdout
  #
  filePath: /etc/traefik/logs/access.log
  # 异步方式
  bufferingSize: 100

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
#  format: json

################################################################
# API and dashboard configuration
################################################################

# Enable API and dashboard
#
# Optional
#
api:
  # Enable the API in insecure mode
  #
  # Optional
  # Default: false
  # 是否可通过非安全方式访问traefik的api,true时可以通过http://ip:port访问面板
  insecure: true

  # Enabled Dashboard
  #
  # Optional
  # Default: true
  # traefik面板
  dashboard: true

################################################################
# Ping configuration
################################################################

# Enable ping
#ping:
  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
#  entryPoint: traefik

################################################################
# Docker configuration backend
################################################################

# 动态配置提供
providers:
  # 间隔x秒重新加载配置
  providersThrottleDuration: 2s

  # 文件方式,来源可以为指定文件或指定目录
  file:
    # 该目录下的yml、yaml或toml都为配置文件,便于编辑隔离
    directory: /etc/traefik/providers
    watch: true

  # docker方式
  docker:
    watch: true
    # docker的网络类型
    network: bridge    
    # 替换example.com为自己域名
    # 容器域名默认为 容器名.example.com
    defaultRule: "Host({{ trimPrefix / .Name }}.example.com)"    
    # swarm模式的轮询间隔
    swarmModeRefreshSeconds: 15s
    # 默认是否公开容器,false为不公开
    exposedByDefault: false
    # 连接docker方式
    # 这里的ip根据自己主机docker网络
    endpoint: "tcp://172.17.0.1:2375"

(缩进为两个空格)

  • 根据自己情况修改web(http)和websecure(https)端口,bridge模式需要对应端口映射
  • 修改example.com为自己顶级域名
  • acme中的email填写自己邮箱

  • dnsChallenge的providers,参考acme#providers,值为cloudflare时需要容器设置变量CF_API_EMAILCF_API_KEYCF_DNS_API_TOKEN、[CF_ZONE_API_TOKEN]
    已经在上面环境变量中设置了CF_DNS_API_TOKEN

  • 其它根据自己需要,可以按照我的模板默认

保存

启动traefik容器

(记得开放traefik的http和https端口)

片刻后上cloudflare应该可以看到域名有证书


使用

分为容器标签和配置文件

标签

容器额外添加label
-l ‘xxx’

  • traefik.enable=true
    开启通过traefik暴露该容器
  • traefik.http.routers.[容器标识名].entryPoints=web/websecure
    设置暴露方式,例traefik.http.routers.alist.entryPoints
    web/websecure对应配置文件中entryPoints下方web、websecure名(也就是可以自定义,只要统一)

对于容器端口唯一开放和访问容器域名为容器名,一般这两个就🆗

  • traefik.http.routers.[容器标识名].rule=Host(x.example.com)
    为该容器指定域名,只修改x.example.com为目标域名
  • traefik.http.services.[容器标识名].loadbalancer.server.port=端口
    注意如果是容器则需要容器内部默认端口
    例alist,容器webui默认端口是5244,映射到主机是6244,此处填写5244

应用后可以到traefik面板查看

无报错(后面显示由docker提供),此时就可以正常访问


文件

在上面traefik/providers目录下创建test.yml(可以创建多个使用)

nano providers/test.yml

简单说明:

主要分开三个模块(注意各自唯一名)

  • routers,定义请求流量规则,和对应动作(转发到哪个服务),与服务、中间件关联,一个路由可以使用多个中间件。
  • services,后端服务,流量请求转发到这些服务。
  • middlewares,逻辑处理,可以对到达服务前、后进行修改、处理、过滤等操作。例如使用traefik反代nextcloud时一些警告就需要中间件设置。

参考文档

# test.yml

http:
  routers:
    alistx_router:
      entryPoints:
       - websecure
      rule: 'Host(alistx.example.com)'
      service: alistx_service
      middlewares: test_ipwhitelist
      # 此处为了演示设置了白名单中间件

  services:
    alistx_service:
      loadBalancer:
        servers:
         - url: http://192.168.1.10:5244

  middlewares:
    # 白名单
    test_ipwhitelist:
      ipWhiteList:
        sourceRange: 
          - 192.168.1.0/24
          - 192.168.2.0/24
    deny-web:
      plugin:
        traefik-filter-plugin:
          filterType: deny-web
  • 编写services,唯一名,设置服务来源
  • 编写routers,访问协议,访问域名,关联service
  • 还可以编写middlewares,并在routers关联

保存

后面标识为由文件所提供

片刻后就可以尝试访问

显示被禁止访问了,符合预期(通过中间件设置仅能白名单ip访问),可查询traefik访问日志看到访问者的ip

tail logs/access.log

此处显示的是外网ip
(移除alistx_router中的middlewares: test_ipwhitelist键值对,外网就能正常访问)

从traefik面板也可以看到相关内容


额外

访问方式

因为设置了http重定向到https,所以在出次访问的浏览器上只需要输入[域名]:[web/http端口]就会自动跳转到https://[域名]:[websecure/https端口]

隔离

之所以文件方式编写选择监控整个traefik/providers目录,是因为可以做到隔离,如果都集中到一个file,编辑时如果其中一个出现语法问题,那该文件里配置的全部反向代理都无法使用。

中间件

标签方式如何添加配置文件定义的中间件

根据上图可以看到这个中间件在页面上显示完整名test_ipwhitelist@file,@file代表来自文件配置

容器添加label

  • traefik.http.routers.[容器标识名].middlewares=test_ipwhitelist@file

简单的需要密码访问

http:
  middlewares:
    password_protect:
      basicAuth:
        users:
          - "username:password"

nextcloud的您的网页服务器未正确设置以解析“/.well-known/caldav”警告,解决中间件为

http:
  middlewares:
    nextcloud-redirect:
      redirectRegex:
        permanent: true
        regex: "https://(.*)/.well-known/(?:card|cal)dav"
        replacement: "https://${1}/remote.php/dav"

主线完成

这些有时间再继续一起探讨

未完待续……


小结

自从diy装了NAS之后,首个系统是TrueNAS SCALE,反向代理自然而然用的就是Traefik,但是那时候出现了Breaking Change,加上其它原因,转UNRAID系统。前期也尝试过NPM,但有些功能难以实现又不想直接代码实现(不熟悉nginx😎),加上搜寻不到“重定向”的方法,于是就在UNRAID上用回Traefik。

Traefik功能丰富,配置文件也算清晰,缺点也是离不开配置文件,面板上只能作为查看。


参考

  • https://doc.traefik.io/traefik/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇