[k8s] oauth2-proxyを使ってKubernetesの管理画面に認証をかける方法

## はじめに

oauth2-proxy を使って、サイトに認証をかけるようにしたので、その記録を残しておきます。

## 抱えていた問題

現在運用している Kubernetes クラスタには、いくつかの管理者向けのページがあります。

- Longhorn の管理画面
- Prometheus の管理画面
- Alertmanager の管理画面

これらのページは、誰でもアクセスできると問題があるため、認証をかける必要があります。

今までは Basic 認証を使っていましたが、これだとパスワードの管理が面倒です。

そこで、今回は oauth2-proxy を使って、GitHub の OAuth 認証で認証をかけることにしました。

## 実装

### GitHub の OAuth アプリケーションの作成

以下のページから GitHub の OAuth アプリケーションを作成します。

<https://github.com/settings/developers>

Redirect URL には、`https://<サーバのFQDN>/oauth2/callback` を指定します。

Client ID と Client Secret を控えておきます。

### oauth2-proxy の設定

ClientID と ClientSecret は ConfigMap・Secret に保存しておきます。

以下のように HelmRelease を作成します。fluxcd を使っていない場合は、`values.yaml`に values 以下を書いて `helm install`してください。

```yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: oauth2-proxy
spec:
  interval: 24h
  url: https://oauth2-proxy.github.io/manifests
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: oauth2-proxy
spec:
  interval: 10m
  chart:
    spec:
      version: 7.x.x
      chart: oauth2-proxy
      sourceRef:
        kind: HelmRepository
        name: oauth2-proxy
  values:
    envFrom:
      - configMapRef:
          name: oauth2-proxy-conf
      - secretRef:
          name: oauth2-proxy-secret
    extraArgs:
      - --http-address=0.0.0.0:4180
      - --github-user=$(ALLOWED_USERS)
      - --client-id=$(CLIENT_ID)
      - --client-secret=$(CLIENT_SECRET)
      - --cookie-secret=$(COOKIE_SECRET)
      - --provider=github
      - --redirect-url=https://$(SERVER_FQDN)/oauth2/callback
      - --cookie-domain=piny940.com
      - --cookie-secure=true
      - --whitelist-domain=*.piny940.com
      - --email-domain=*
```

Ingress は 2 つ作成します。

1 つは oauth2-proxy の Ingress、もう 1 つは認証をかけるサービスの Ingress です。

```yaml
# oauth2-proxyのIngress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: oauth2-proxy-ingress
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - service.example.com
      secretName: cluster-tls
  rules:
    - host: service.example.com
      http:
        paths:
          - path: /oauth2
            pathType: Prefix
            backend:
              service:
                name: oauth2-proxy
                port:
                  number: 80
---
# 認証をかけるサービスのIngress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: service-name
  annotations:
    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=https%3A%2F%2F$host$escaped_request_uri"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - service.example.com
      secretName: cluster-tls
  rules:
    - host: service.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service-name
                port:
                  number: 80
```

これで、サーバーにアクセスすると、GitHub の OAuth 認証画面が表示されるようになります。

## まとめ

今回は、oauth2-proxy を使って、GitHub の OAuth 認証で認証をかける方法を紹介しました。
これで管理画面がよりセキュアになりました。

次回は、以前自作した OIDC プロバイダを使って認証をかけるようにしようと思います。

## 参考資料

https://oauth2-proxy.github.io/oauth2-proxy/

https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/