# 監控應用透過 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`

* 成功登入

## 參考
https://oauth2-proxy.github.io/oauth2-proxy/