基於 Traefik 的激進 TLS 安全配置實踐

東風微鳴發表於2022-12-24

前言

Traefik是一個現代的HTTP反向代理和負載均衡器,使部署微服務變得容易。

Traefik可以與現有的多種基礎設施元件(Docker、Swarm模式、Kubernetes、Marathon、Consul、Etcd、Rancher、Amazon ECS...)整合,並自動和動態地配置自己。

今天我們基於 Traefik on K8S 來詳細說明如何對 TLS 安全進行「激進」配置。

環境基本資訊

  1. K8S 叢集;
  2. 域名:ewhisper.cn(由 DNSPod 進行 DNS 管理,已指向 K8S 叢集的 Traefik Ingress 的 LoadBalancer 公網地址)
  3. 使用 cert-manager 自動管理的證書 *.ewhisper.cn 作為 Traefik 的預設證書;cert-manager 位於 cert-manager NameSpace 下
  4. Traefik 2.4.8 安裝於 K8S 叢集的 kube-system NameSpace 下,且使用 CRDs 進行配置。

「激進」的 TLS 配置

全站受信證書 + HTTPS。具體如下:

  1. 全站 HTTPS 443 埠配置;
  2. 證書來自 Let's Encrypt(由 cert-manager 自動申請)(⚡激進,生產慎用!)
  3. 監聽 HTTP 請求,並重定向到 HTTPS;(⚡激進,生產慎用!)
  4. 啟用 HSTS 功能(⚡激進,生產慎用!)
  5. TLS 版本限定在 TLS 1.3(⚡激進,生產慎用!)

配置實踐

TLS 版本限定在 TLS 1.3

使用 Traefik 的 CRD - TLSOption 配置如下:

apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
  name: default
  namespace: kube-system

spec:
  minVersion: VersionTLS13

? 說明

  • minVersion: VersionTLS13 指定 TLS 最小版本為 TLS 1.3.

⚠️ Warning:

以防萬一,建議 namespace: kube-system 和 Traefik 所在的 ns 保持一致。

證書

使用 Traefik 的 CRD - TLSStore 配置如下:

apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
  name: default
  namespace: cert-manager

spec:
  defaultCertificate:
    secretName: ewhisper-crt-secret

? 說明

  • secretName: ewhisper-crt-secret 這個是 cert-manager 自動從 Let's Encrypt 申請到的證書的存放位置(cert-manager 會負責定期自動更新該證書)。Traefik 就使用該證書作為預設證書。

⚠️ Warning:

TLSStore,注意 namespace: cert-manager 必須要在 證書的 secret 所在的 NameSpace。

接下來 2 個功能:

  1. HTTP 重定向到 HTTPS
  2. 啟用 HSTS

都是透過 Traefik CRD - Middleware 來進行配置的。

HTTP 重定向到 HTTPS

Traefik CRD Middleware - redirectshttps 配置如下:

# Redirect to https
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirectshttps
  namespace: kube-system
spec:
  redirectScheme:
    scheme: https
    permanent: true

? 說明

  • redirectScheme: 協議重定向
  • scheme: https: HTTP 協議重定向為 HTTPS
  • permanent: true: 設定為 true 以應用永久重定向。

啟用 HSTS

Traefik CRD Middleware - hsts-header 配置如下:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: hsts-header
  namespace: kube-system
spec:
  headers:
    customResponseHeaders:
      Strict-Transport-Security: 'max-age=63072000'
  • customResponseHeaders 應用於響應頭的名稱和值。
  • Strict-Transport-Security: 'max-age=63072000': 即 「HTTP嚴格傳輸安全」響應頭,收到該響應頭的瀏覽器會在 63072000s(約 2 年)的時間內,只要訪問該網站,即使輸入的是 http,瀏覽器會自動跳轉到 https。(HSTS 是瀏覽器端的跳轉,之前的「HTTP 重定向到 HTTPS」是伺服器端的跳轉)

具體域名配置

以上的所有配置,包括:

  1. TLS 版本限定在 TLS 1.3
  2. 證書
  3. HTTP 重定向到 HTTPS
  4. 啟用 HSTS

都是全域性的配置,接下來針對具體的域名 - 這裡是 example.ewhisper.cn 進行配置。

使用 Traefik 的 CRD - IngressRoute 配置如下:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: example
  namespace: cert-manager
spec:
  entryPoints:
    - websecure
    - web
  routes:
    - match: Host(`example.ewhisper.cn`)
      kind: Rule
      middlewares:
        - name: hsts-header
          namespace: kube-system
        - name: redirectshttps
          namespace: kube-system
      services:
        - name: example
          namespace: default
          port: 8080
  tls: {}

? 說明

  • entryPoints: EntryPoints 是進入 Traefik 的網路入口點。它們定義將接收資料包的埠,以及是否偵聽 TCP 或 UDP。如下圖所示:

    entryPoints
    這裡 entryPoints 是靜態配置,是直接靜態配置在 Traefik Deployment 中的,如下圖:
    Traefik Deployment arg

    • entryPoint - traefik 地址埠是::9000/tcp
    • entryPoint - web 地址埠是::8000/tcp
    • entryPoint - websecure 地址埠是::8443/tcp,且 tls 為 true
    • 然後,再透過 Serivce Type: LoadBalancer 暴露到公網的: 80 和 443 埠(至於entryPoint - traefik 則還沒有透過 SVC 暴露,所以即使配了 IngressRoute 也無法訪問),如下:
      Traefik LoadBalancer SVC
  • websecure 即:example.ewhisper.cn 可以透過 https://example.ewhisper.cn:443 訪問;

  • web 即:example.ewhisper.cn 可以透過 http://example.ewhisper.cn:80 訪問;

  • kind: Rule Rule 是一組配置了值的匹配器(即 match),它決定一個特定的請求是否匹配特定的條件。如果規則經過驗證,Route 就會成為活動的,呼叫中介軟體,然後將請求轉發給服務。

  • match: Host(`example.ewhisper.cn`): 這裡是檢查請求域名(host 報頭值)是否以給定域之一(即example.ewhisper.cn)為目標。

  • middlewares: 連線到 Route 的中介軟體是在請求被髮送到你的服務之前(或者在服務的回答被髮送到客戶端之前)對請求進行調整的一種方法。 在trafik中有幾種可用的中介軟體,一些可以修改請求、報頭,一些負責重定向,一些新增身份驗證,等等。 使用相同協議的中介軟體可以組合成鏈,以適應每個場景。中介軟體作用如下圖所示:

    middlewares

  • name: hsts-header 啟用 HSTS 的中介軟體(可以複用)

  • name: redirectshttps 啟用 HTTP 重定向到 HTTPS 的中介軟體(可以複用)

  • services... 轉發到 K8S default NameSpace 下的 example Service 的 8080 埠。

配置生效

假設以上配置都放在 ./traefik-sec 目錄下,執行如下命令生效:

kubectl apply -f ./traefik-sec

驗證

瀏覽器訪問

直接瀏覽器訪問 http://example.ewhisper.cn 域名,跳轉到 http://example.ewhisper.cn, 並且證書已生效。

☝ HTTP 重定向到 HTTPS 已生效

透過 SSL Labs 驗證

SSL Labs 的 SSL Server Test 下進行驗證。驗證結果如下:

A
☝ 評分為 A,且 HSTS 已啟用

證書資訊
☝ 證書為 *.ewhisper.cn 合法證書

TLS 協議
☝ TLS 協議只支援 TLS 1.3

???

參考資料

三人行, 必有我師; 知識共享, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.

相關文章