Oauth2 Proxy에 대하여
Oauth2 Proxy란?
OAuth2 Proxy는 OAuth2 서버에 대해 인증을 제공해주는 리버스 프록시 구현체이다. OpenID Connect와 같은 OAuth2에 대해서 인증을 제공하는 애플리케이션의 경우에는 바로 프로바이더를 등록하여 사용할 수 있다. 하지만, 애플리케이션에서 인증을 따로 제공하지 않는다면 따로 작업이 필요하다.
기능
그러한 작업들을 쉽게 할 수 있게 앞단에 바로 리버스 프록시를 통한 인증을 도와주는 것이 OAuth2 Proxy이다. 이름 그대로 OAuth2를 이용해서 인증을 제공한다.
여러 프로바이더들을 통해서 그룹, 이메일, 도메인을 기반으로 사용자 인증을 진행한다. 사용자의 세션을 관리하고 쿠키를 사용하여 로그인 상태를 유지하게 된다. 따라서 앞단에서 정해진 인원들만 접근이 가능하며 SSO와 같이 한번의 로그인으로 세션을 유지할 수 있다. 이후에는 백엔드 서버에 인증된 요청을 리다이렉트하며 필요하면 수정한 트래픽을 보낼 수 있다.
아키텍처
작동 순서
- 인증 요청: 여러 프로바이더(google, github, facebook …)의 이메일, 도메인, 그룹 기반으로 인증
- 인증: 사용자가 프로바이더에 로그인하면, 프로바이더로부터 액세스 토큰 획득
- 세션 생성: 인증 성공 시, 사용자 세션 생성 및 쿠키 저장
- 접근 제어: 인증된 사용자 접근
- 리다이렉트: 백엔드 서버에 리다이렉트 및 추가적인 작업
쿠버네티스에서 작업
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: app-oauth2-proxy
5 namespace: default
6spec:
7 selector:
8 matchLabels:
9 app: app-oauth2-proxy
10 template:
11 metadata:
12 labels:
13 app: app-oauth2-proxy
14 spec:
15 nodeSelector:
16 role: app
17 containers:
18 - name: oauth2-proxy
19 image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1
20 args:
21 - --provider=oidc
22 - --cookie-secure=true
23 - --cookie-samesite=lax
24 - --cookie-refresh=1h
25 - --cookie-expire=4h
26 - --cookie-name=auth
27 - --set-authorization-header=true
28 - --email-domain=example.com
29 - --http-address=0.0.0.0:4180
30 - --upstream=http://app.default.svc.cluster.local:8080
31 - --redirect-url=https://app.example.com
32 - --skip-provider-button=true
33 - --whitelist-domain=https://app.example.com #URL변경필요
34 - --oidc-issuer-url=https://dex.example.com #URL변경필요
35 - --cookie-domain=example.com
36 env:
37 - name: OAUTH2_PROXY_SILENCE_PING_LOGGING
38 value: "true"
39 - name: OAUTH2_PROXY_REVERSE_PROXY
40 value: "true"
41 - name: OAUTH2_PROXY_UPSTREAMS
42 value: http://app.default.svc.cluster.local:8080
43 - name: OAUTH2_PROXY_CLIENT_ID
44 value: app
45 - name: OAUTH2_PROXY_CLIENT_SECRET
46 value: app
47 - name: OAUTH2_PROXY_COOKIE_SECRET
48 value: secret
49 - name: OAUTH2_PROXY_PASS_HOST_HEADER
50 value: 'false'
51 ports:
52 - containerPort: 4180
53 protocol: TCP
54 readinessProbe:
55 periodSeconds: 3
56 httpGet:
57 path: /ping
58 port: 4180
59---
60apiVersion: v1
61kind: Service
62metadata:
63 name: app-oauth2-proxy
64 namespace: default
65spec:
66 selector:
67 app: app-oauth2-proxy
68 ports:
69 - name: http
70 port: 4180
71---
- istio virtual serviec
1apiVersion: networking.istio.io/v1alpha3
2kind: VirtualService
3metadata:
4 name: app-example-com
5 namespace: default
6spec:
7 gateways:
8 - default/gateway
9 hosts:
10 - app.example.com
11 http:
12 - rewrite:
13 authority: app-oauth2-proxy.default.svc.cluster.local
14 route:
15 - destination:
16 host: app-oauth2-proxy.default.svc.cluster.local
17 port:
18 number: 4180
- ingress
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4 name: app-example-com
5 namespace: default
6 annotations:
7 kubernetes.io/ingress.class: nginx
8 nginx.ingress.kubernetes.io/rewrite-target: /
9 nginx.ingress.kubernetes.io/use-regex: "true"
10spec:
11 rules:
12 - host: app.example.com
13 http:
14 paths:
15 - path: /
16 pathType: Prefix
17 backend:
18 service:
19 name: app-oauth2-proxy
20 port:
21 number: 4180
위의 예제들과 같이 OAuth2 Proxy를 구성한 뒤 환경변수로 리버스 프록시와 업스트림 주소를 등록하여 사용할 수 있다. 그리고 사용하고자하는 OIDC Issuer를 등록하여 사용하면 된다. 예제에서는 dex를 지정해서 사용하는 것처럼 만들었다.
그 이후에는 네트워크를 OAuth2 Proxy를 향해 접근하도록 하면 된다. 왜냐하면 업스트림으로 원하는 애플리케이션을 향해서 보내도록 설정했기 때문이다.
이렇게 지정하게 되면, OIDC가 설정되어 있다는 가정하에 바로 사용할 수 있다.