使用 Traefik 实例提供有效且动态的证书

使用 Traefik 实例提供有效且动态的证书

语境

我有一个“特殊”的设置,其中我有第一个前端服务器( ),它接收所有公共网络流量,并且仅在私有网络上server0接收至少一个其他主机( )。server1

我不知道如何为私有网络主机上托管的服务启用 HTTPS(server1)。

这是我的架构方案:


[ Internet ] --- [ Server 0 ]              --- [ Server 1]
                 +-----------------------+     +-----------------------+
                 | Docker                |     | Docker                |
                 | +-------------------+ |     | +-------------------+ |
                 | | Traefik           | |     | | Traefik           | |
                 | | Service A         | |     | | Service B         | |
                 | +-------------------+ |     | +-------------------+ |
                 +-----------------------+     +-----------------------+

我基本上使用通配符 DNS(全部指向server0)来公开每个主机上的服务。例如:

  • traefik.server0.mydomain
  • servicea.server0.mydomain
  • traefik.server1.mydomain
  • serviceb.server1.mydomain

我的尝试:

服务器0(http,https), 服务器1(http)

server0

  • http、https 和 traefik 入口点
  • docker 已启用
  • 静态规则server1
    • http、https 入口点
    • 传球头球
    • 规则:HostRegexp:{subdomain:.*}.server1.mydomain
    • 目标:http://server1

server1

  • http,traefik 入口点
  • docker 已启用
# server0:/etc/traefik/traefik.toml
[entryPoints]
    [entryPoints.http]
        address = ":80"
        [entryPoints.http.redirect]
            entryPoint = "https"
    [entryPoints.https]
        address = ":443"
        [entryPoints.https.tls]
    [entryPoints.traefik]
        address=":8080"

[api]
[ping]
[file]
directory = "/etc/traefik/config.d"

[docker]
watch = true
exposedByDefault = false
network = "traefik"

[acme]
email = "[email protected]"
storage = "/data/acme.json"
entryPoint = "https"
onHostRule = true
    [acme.httpChallenge]
    entryPoint = "http"


# server0:/etc/traefik/config.d/server1.toml
[frontends]
    [frontends.server1]
        entryPoints = ["http", "https"]
        backend = "server1"
        passHostHeader = true
        [frontends.server1.routes]
            [frontends.server1.routes.main]
                rule = "HostRegexp:{subdomain:.*}.server1.mydomain"
[backends]
    [backends.server1]
        [backends.server1.servers]
            [backends.server1.servers.main]
                url = "http://server1.local"


# server1:/etc/traefik/traefik.toml
[entryPoints]
    [entryPoints.http]
        address = ":80"
    [entryPoints.traefik]
        address=":8080"

[api]
[ping]

[docker]
watch = true
exposedByDefault = false
network = "traefik"

结果:

  • traefik.server0.mydomain:好的,有效证书(Let's Encrypt)
  • serviceA.server0.mydomain:好的,有效证书(Let's Encrypt)
  • traefik.server1.mydomain:好的,证书无效(Traefik 默认证书)

服务器0(http,https),服务器1(http,https)

server0

  • http、https 和 traefik 入口点
  • docker 已启用
  • 静态规则server1
    • http、https 入口点
    • 传球头球
    • 规则:HostRegexp:{subdomain:.*}.server1.mydomain
    • 目标:https://server1

server1

  • http、https、traefik 入口点
  • docker 已启用
# server0:/etc/traefik/traefik.toml
[entryPoints]
    [entryPoints.http]
        address = ":80"
        [entryPoints.http.redirect]
            entryPoint = "https"
    [entryPoints.https]
        address = ":443"
        [entryPoints.https.tls]
    [entryPoints.traefik]
        address=":8080"

[api]
[ping]
[file]
directory = "/etc/traefik/config.d"

[docker]
watch = true
exposedByDefault = false
network = "traefik"

[acme]
email = "[email protected]"
storage = "/data/acme.json"
entryPoint = "https"
onHostRule = true
    [acme.httpChallenge]
    entryPoint = "http"


# server0:/etc/traefik/config.d/server1.toml
[frontends]
    [frontends.server1]
        entryPoints = ["http", "https"]
        backend = "server1"
        passHostHeader = true
        [frontends.server1.routes]
            [frontends.server1.routes.main]
                rule = "HostRegexp:{subdomain:.*}.server1.mydomain"
[backends]
    [backends.server1]
        [backends.server1.servers]
            [backends.server1.servers.main]
                url = "https://server1.local"


# server1:/etc/traefik/traefik.toml
[entryPoints]
    [entryPoints.http]
        address = ":80"
    [entryPoints.https]
        address = ":443"
        [entryPoints.https.tls]
    [entryPoints.traefik]
        address=":8080"

[api]
[ping]

[docker]
watch = true
exposedByDefault = false
network = "traefik"

[acme]
email = "[email protected]"
storage = "/data/acme.json"
entryPoint = "https"
onHostRule = true
    [acme.httpChallenge]
    entryPoint = "http"

Result:

* `traefik.server0.mydomain`: OK, valid certificate (Let's Encrypt)
* `serviceA.server0.mydomain`: OK, valid certificate (Let's Encrypt)
* `traefik.server1.mydomain`: internal server error (no log), invalid certificate (Traefik default cert)
 


I don't know which options to use to have correct behavior ...

答案1

Lets-encrypt 不允许您验证内部域,因为它无法看到/访问它。因此,您需要在公共 IP 上验证它。但我不确定您是否能够完全按照您的要求进行操作,您可能需要稍微更改一下 DNS。

本文将有助于您了解一般问题。

相关内容