註:筆者居住於韓國,部分內容包含韓國特有的背景。
以下內容與 Sealed Secrets 第 3 節 有相當多重疊的部分。如果您已經完成那一節,並且對 Basic Auth 較為熟悉,可以直接跳過。
1. 前言
使用 Kubernetes 時,會陸續部署各種各樣的服務。
當然,僅在內網中提供服務在安全方面是最理想的,但叢集管理並不一定總能從內網進行。例如外出時突然出現問題之類的情況也是有可能發生的。
這種情況下大致有兩種解決方案。
- 使用 VPN,從其他電腦連入內網,使用相關服務
- 將服務暴露在網際網路上,但加入認證機制
我個人選擇了第 2 種,並自己建置了一個 SSO 伺服器使用。
不過,由於 SSO 系統的建置過程相當龐大,這裡先從最簡單的認證機制開始。
2. Basic Auth 的流程

Basic Auth 非常簡單!
- 用戶端向伺服器請求頁面。
- 伺服器收到請求,如果沒有認證資訊,則回應 401 並要求認證方式(Basic Auth)。
- 用戶端收到回應後,進行 Basic Auth。
- 此時,HTTP Authorization Header 中會帶上
Basic ${認證 token}的值。 - 此處的認證 token 是 Base64Encode(“userId:password”)。
- 例如 id 為 lemondouble,密碼為 1q2w3e4r! 時,使用對
"lemondouble:1q2w3e4r!"進行 base64 編碼後的值bGVtb25kb3VibGU6MXEydzNlNHIh。
- 此時,HTTP Authorization Header 中會帶上
- 伺服器驗證該 token 後,回傳正常回應。
3. Basic Auth 的優缺點
優點:
- 內建! 大多數瀏覽器無需額外設定即可支援。
- 實作簡單。 大多數 Web 框架都預設支援!
缺點:
- 安全性較弱:這是最大的缺點。
- 密碼以 base64 編碼(=明文)的形式在每次請求中傳輸。
- 若使用 HTTPS 協定還好,但若使用 HTTP 協定,密碼會在每次請求中以明文形式傳送!
- 不防禦暴力破解等攻擊。
- 這雖然也算是 Id/Password 本身的問題,但在 Traefik 的預設設定下,並沒有諸如丟棄失敗請求超過一定次數的用戶端之類的功能。
- 如果 Id/Password 較弱,惡意攻擊者可能透過暴力破解存取該服務。
- 密碼以 base64 編碼(=明文)的形式在每次請求中傳輸。
因此,如有可能,建議在以下情形下使用此功能:
- 即使被存取也無大礙的服務,或僅希望分享給少數使用者的服務
- 使用 HTTPS 協定
- 使用足夠長的密碼
4. Basic Auth 的設定方法
- 我們將使用 Sealed Secrets 對連線資訊(Id/Password)進行加密,並儲存到 Git 中。
- 這樣做的原因如下:
- 在突發事故發生時,連同連線資訊一起快速復原叢集(Secrets 資訊也在 Git 中,只需部署即可)
- 即便使用 Private Repo,也可以防止因一時疏忽導致 Id/Password 外洩
Disclaimer:以下內容與 Sealed Secrets 第 3 節 完全相同!
讓我們將 Longhorn Dashboard 設定為可從外部存取,同時學習 Basic Auth 的設定方法。
- 執行
apt install apache2-utils,以便使用 htpasswd 命令。 - 使用
htpasswd -nb <id> <password> | openssl base64,取得包含 id、password 的 Secret String。 - 用任意文字編輯器建立 secret.yaml,並參考下方內容新增 Secret。
apiVersion: v1
kind: Secret
metadata:
name: longhorn-system-basic-auth
namespace: longhorn-system
data:
users: <步驟 2 中得到的 String>- 輸入
cat secret.yaml | kubeseal --controller-namespace=sealed-secrets-system --controller-name=sealed-secrets -oyaml > sealed-secrets.yaml,取得 sealed-secrets.yaml。 - 參考下方內容註冊 ingress。
modules/longhorn-system/ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: longhorn-dashboard
namespace: longhorn-system
spec:
tls:
certResolver: le
routes:
- kind: Rule
match: Host(`<想要的 subdomain,例如 longhorn.lemon.com>`)
middlewares:
- name: basic-auth
namespace: longhorn-system
services:
- name: longhorn-frontend
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: basic-auth
namespace: longhorn-system
spec:
basicAuth:
secret: longhorn-system-basic-auth在 modules/longhorn-system/sealed-basic-auth-secret.yaml 中,將剛剛產生的 sealed-secrets.yaml 複製貼上進去。
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: longhorn-system-basic-auth
namespace: longhorn-system
spec:
encryptedData:
users: adfasdflavasdlfj...
template:
metadata:
creationTimestamp: null
name: longhorn-system-basic-auth
namespace: longhorn-system- 之後進行部署。
- 存取時會正常彈出 id/password 確認視窗,未登入則無法看到該頁面!
5. 結語
Basic Auth 是我早期的叢集管理方式。
如果對外暴露的服務不多,我覺得僅僅設定 Basic Auth 並使用 Bitwarden 等密碼管理器來管理就已經足夠了。
但如果之後專案越來越多呢?
為了因應這種情況,我會在下一篇文章中介紹 SSO 認證方式。
但由於認證伺服器是我自己 DIY 的,可能很難提供完整的原始碼,還請各位先包涵,我會先介紹可直接使用的 Basic Auth 🙇

Comments