# 監控應用透過 Istio 搭配使用 OAuth2-Proxy 身份驗證登入 ## 目標 預設 prometheus 和 alertmanager UI 不需要帳密就可以直接進到他們的 UI,透過 istio 和 OAuth2-Proxy 搭配,可以讓我們使用帳密的方式登入到 UI。 ## 在 ubuntu 安裝套件 ``` $ sudo apt install apache2-utils ``` ## 產生加密字串 * 產生一串帳號與加密後的密碼。 ``` $ htpasswd -nbs admin password123 admin:{SHA}y/2sYAj5yrQIN4TL0YdPdmGNKpc= ``` * 產生一串隨機的加密金鑰,目的是讓別人看不出 Cookie 裡面存了什麼。 ``` $ openssl rand -base64 16 | tr -d '\n' 1om2CJDWzfOQXELLv5mQkA== ``` ## 建立 Kubernetes Secret ``` $ nano secret.yaml apiVersion: v1 kind: Secret metadata: name: oauth2-proxy-creds namespace: istio-system type: Opaque stringData: # 剛才 htpasswd 產生的整行內容 htpasswd: "admin:{SHA}y/2sYAj5yrQIN4TL0YdPdmGNKpc=" # 隨機 16, 24 或 32 字元的 base64 字串 (用於 Cookie 加密) cookie-secret: "1om2CJDWzfOQXELLv5mQkA==" ``` ``` $ kubectl apply -f secret.yaml ``` ``` $ kubectl -n istio-system get secret oauth2-proxy-creds NAME TYPE DATA AGE oauth2-proxy-creds Opaque 2 14s ``` ## 部署 OAuth2-Proxy * 它的核心任務是:幫那些「本身沒有登入功能」的應用程式(例如您的 Prometheus、Alertmanager 或 Dashboard),在不改動任何程式碼的情況下,加上一層專業的登入保護。 * OAuth2-Proxy 主要用來為後端服務增加身份驗證層。它支援多種 OAuth 2.0 提供者(如 Google、OIDC、Keycloak 等),可以保護未提供身份驗證的應用程式。 oauth2-proxy 在請求進入後端服務之前,會先進行 OAuth 2.0 登入認證,確保請求者俱有存取權限。它承擔了登入的合法性校驗、重定向、登入成功後的 cookie、response 設定等功能。 ``` $ nano oauth2-proxy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: oauth2-proxy namespace: istio-system spec: replicas: 1 selector: matchLabels: app: oauth2-proxy template: metadata: labels: app: oauth2-proxy spec: containers: - name: oauth2-proxy image: quay.io/oauth2-proxy/oauth2-proxy:v7.4.0 ports: - containerPort: 4180 args: - --http-address=0.0.0.0:4180 - --provider=github - --client-id=static-client-id - --client-secret=static-client-id - --htpasswd-file=/etc/proxy/htpasswd - --cookie-secure=false - --cookie-secret=$(COOKIE_SECRET) - --email-domain=* - --upstream=static://200 - --cookie-expire=30m env: - name: COOKIE_SECRET valueFrom: secretKeyRef: name: oauth2-proxy-creds key: cookie-secret volumeMounts: - name: htpasswd-volume mountPath: /etc/proxy volumes: - name: htpasswd-volume secret: secretName: oauth2-proxy-creds items: - key: htpasswd path: htpasswd --- apiVersion: v1 kind: Service metadata: name: oauth2-proxy namespace: istio-system spec: ports: - port: 4180 targetPort: 4180 protocol: TCP name: http selector: app: oauth2-proxy ``` ``` $ kubectl apply -f oauth2-proxy.yaml ``` ``` $ kubectl -n istio-system get pod NAME READY STATUS RESTARTS AGE oauth2-proxy-6b444f46d7-w2s86 1/1 Running 0 8s ``` ## 安裝 istio ``` $ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.29.0 sh - $ sudo cp istio-1.29.0/bin/istioctl /usr/local/bin ``` ``` $ nano istio-install.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio-control-plane namespace: istio-system spec: profile: default meshConfig: extensionProviders: - name: "my-auth-proxy" # 與 AuthorizationPolicy 對應的名字 envoyExtAuthzHttp: service: "oauth2-proxy.istio-system.svc.cluster.local" port: "4180" includeHeadersInCheck: - "authorization" - "cookie" headersToUpstreamOnAllow: - "authorization" - "path" - "x-auth-request-user" - "x-auth-request-email" headersToDownstreamOnDeny: - "content-type" - "set-cookie" components: pilot: enabled: true ingressGateways: - name: istio-ingressgateway enabled: true k8s: service: type: LoadBalancer loadBalancerIP: 10.10.7.85 # 設定自己環境可用的 ip ``` ``` $ istioctl install -f ./istio-install.yaml ``` ## 安裝 prometheus ``` $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm repo update $ helm install monitoring prometheus-community/kube-prometheus-stack --namespace monitoring-system --create-namespace ``` ``` $ kubectl -n monitoring-system get po NAME READY STATUS RESTARTS AGE alertmanager-monitoring-kube-prometheus-alertmanager-0 2/2 Running 0 52s monitoring-grafana-584c45f5f6-lq96g 3/3 Running 0 62s monitoring-kube-prometheus-operator-7967b58468-bbdc6 1/1 Running 0 62s monitoring-kube-state-metrics-68cbbfb567-kdpwg 1/1 Running 0 62s monitoring-prometheus-node-exporter-2blh2 1/1 Running 0 65s monitoring-prometheus-node-exporter-9d88w 1/1 Running 0 65s monitoring-prometheus-node-exporter-dd22v 1/1 Running 0 65s monitoring-prometheus-node-exporter-hx9d2 1/1 Running 0 65s prometheus-monitoring-kube-prometheus-prometheus-0 2/2 Running 0 52s ``` ## 建立 Gateway & VirtualService ``` $ nano app-vs.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: app-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*.k8sexample.com" --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: prometheus-vs namespace: istio-system spec: hosts: - "prometheus.k8sexample.com" gateways: - app-gateway http: - match: - uri: prefix: /oauth2 route: - destination: host: oauth2-proxy.istio-system.svc.cluster.local port: number: 4180 - match: - uri: prefix: / route: - destination: host: monitoring-kube-prometheus-prometheus.monitoring-system.svc.cluster.local port: number: 9090 --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: alertmanager-vs namespace: istio-system spec: hosts: - "alertmanager.k8sexample.com" gateways: - app-gateway http: - match: - uri: prefix: /oauth2 route: - destination: host: oauth2-proxy.istio-system.svc.cluster.local port: number: 4180 - match: - uri: prefix: / route: - destination: host: monitoring-kube-prometheus-alertmanager.monitoring-system.svc.cluster.local port: number: 9093 ``` ``` $ kubectl apply -f app-vs.yaml ``` ``` $ kubectl -n istio-system get gateway.network NAME AGE app-gateway 8s $ kubectl -n istio-system get vs NAME GATEWAYS HOSTS AGE alertmanager-vs ["app-gateway"] ["alertmanager.k8sexample.com"] 6m42s prometheus-vs ["app-gateway"] ["prometheus.k8sexample.com"] 6m42s ``` ## 建立 AuthorizationPolicy ``` $ nano auth.yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: monitor-auth-policy namespace: istio-system spec: selector: matchLabels: istio: ingressgateway # 保護您的內部網關流量 action: CUSTOM provider: name: "my-auth-proxy" # 務必與上面 IstioOperator 定義的名字相同 rules: - to: - operation: hosts: - "prometheus.k8sexample.com" - "alertmanager.k8sexample.com" notPaths: - "/oauth2/*" ``` ``` $ kubectl apply -f auth.yaml $ kubectl -n istio-system get AuthorizationPolicy NAME ACTION AGE monitor-auth-policy CUSTOM 10s ``` ## 登入 UI * 進入 UI 就需要輸入帳號密碼,輸入 `admin/password123` ![image](https://hackmd.io/_uploads/SkFyxkXFZg.png) * 成功登入 ![image](https://hackmd.io/_uploads/H1AdS1XtWl.png) ## 參考 https://oauth2-proxy.github.io/oauth2-proxy/