In this article , we would explain how to set up Oauth2 proxy in your organization using Azure , ArgoCD to set up more security during your application access.
What is Oauth2 proxy ?
Oauth2 is a reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain or group.
In our article , we will explain how to set up a simple hello world app ( Not Kibana and elastic search )
Prerequisites.
- ArgoCD
- AKS with Nginx Ingress controller installed.
- Application registred in Application registration in Azure.
- Working app ( Hello World application ).
- GitHub repository
1- Install Nginx ingress controller in your AKS kubernetes cluster.
Click on this link and follow the Microsoft Documentation.
Once installed make sure that ingress controller pod is up and running.
2- Deploy a demo application “ Hello World”
apiVersion: v1
kind: Service
metadata:
name: hello-world
namespace: demo
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app: hello-world
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: hello-world
name: hello-world
namespace: demo
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: Always
name: hello-world
ports:
- containerPort: 8080
name: http
protocol: TCP
And once deployed , make sure the pod is running perfectly
Now we have to register our application in Application registration service of Azure.
We will chose to set up the Redirect URI to this below address.https://medium-demo.com/oauth2/callback
3- Register the application in Azure App registration service
Once we set it up and saved it , we will be routed to the below page.
We can see above that our application is registered and that helps Azure to expose some parameters for us like ClientID and TenantID , however we still need to create some credentials for our Client , Let’s do it.
We click on “Add a certificate or secret
Once we click we will be routed to the below page.
We name our secret and we set the expiry date and then we save everything.
Our secret is now created ( Sorry I had to hide it ).
Please make sure to save it somewhere.
4- Deploy Oauth2 manifest on AKS kubernetes using ArgoCD.
So for this step , we could deploy manually Oauth2 manifests but in order to put ourselves in a real situation in a real project , I prefer we proceed this way as it is more professional ( we could package it with helm but this will make the article longer ) , so I will point to my GitHub repository to pull the required manifest.
In order to deploy it using GitOps approach , we would need to have ArgoCD installed on your AKS cluster.
After logging in ArgoCD , we need to add the repository , in our case , I forked the helm chart into my personal GitHub repository.
Right after that , we create a new app in ArgoCD where we call our Oauth2 repository.
Our Oauth2 proxy has several credentials to be filled, and as we can see below, there is 3 secrets to be created ( client-id , client-secret , cookies-secret ).
In order to create these secrets , we need to run the below commands.
kubectl create secret generic client-id --from-literal=oauth2_proxy_client_id=CLIENT_ID -n medium
kubectl create secret generic client-secret --from-literal=SECRET_ID -n medium
kubectl create secret generic cookie-secret --from-literal=oauth2_proxy_cookie_secret=LOOK AT THE COMMAND BELOW -n medium
For Cookies Secret , it could be generated using the below command:
dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
meta.helm.sh/release-name: kubecost # can be removed if your application isn\'t deployed through Helm
meta.helm.sh/release-namespace: kubecost # can be removed if your application isn\'t deployed through Helm
labels:
application: kubecost-oauth2-proxy
app.kubernetes.io/managed-by: Helm # can be removed if your application isn\'t deployed through Helm
name: kubecost-oauth2-proxy-deployment
namespace: medium
spec:
replicas: 1
selector:
matchLabels:
application: kubecost-oauth2-proxy
template:
metadata:
labels:
application: kubecost-oauth2-proxy
spec:
containers:
- args:
- --provider=oidc
- --azure-tenant=ADD YOUR TENANT ID FROM AZURE # Azure AD OAuth2 Proxy application Tenant ID
- --pass-access-token=true
- --cookie-name=_proxycookie # this can be any name of your choice which you would like OAuth2 Proxy to use for the session cookie
- --email-domain=*
- --upstream="http://ADD YOUR FQDN :80" #we changed to this FQDN
- --http-address=0.0.0.0:4180
- --oidc-issuer-url=https://login.microsoftonline.com/ADD YOUR TENANT ID /v2.0
name: kubecost-oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.3.0
imagePullPolicy: Always
env:
- name: OAUTH2_PROXY_CLIENT_ID # keep this name - it\'s required to be defined like this by OAuth2 Proxy
valueFrom:
secretKeyRef:
name: client-id
key: oauth2_proxy_client_id
- name: OAUTH2_PROXY_CLIENT_SECRET # keep this name - it\'s required to be defined like this by OAuth2 Proxy
valueFrom:
secretKeyRef:
name: client-secret
key: oauth2_proxy_client_secret
- name: OAUTH2_PROXY_COOKIE_SECRET # keep this name - it\'s required to be defined like this by OAuth2 Proxy
valueFrom:
secretKeyRef:
name: cookie-secret
key: oauth2_proxy_cookie_secret
ports:
- containerPort: 4180
protocol: TCP
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
Then we create the service.
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: kubecost # can be removed if your application isn\'t deployed through Helm
meta.helm.sh/release-namespace: kubecost # can be removed if your application isn\'t deployed through Helm
labels:
application: kubecost-oauth2-proxy
app.kubernetes.io/managed-by: Helm # can be removed if your application isn\'t deployed through Helm
name: kubecost-oauth2-proxy-svc
namespace: medium
spec:
ports:
- name: http
port: 4180
protocol: TCP
targetPort: 4180
selector:
application: kubecost-oauth2-proxy
And finally the Ingress ( We will skip the TLS and SSL termination here )
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-body-size: "2000m"
nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"
meta.helm.sh/release-name: kubecost # can be removed if your application isn\'t deployed through Helm
meta.helm.sh/release-namespace: kubecost # can be removed if your application isn\'t deployed through Helm
labels:
app.kubernetes.io/managed-by: Helm # can be removed if your application isn\'t deployed through Helm
name: kubecost-oauth2-proxy-ingress
namespace: medium
spec:
ingressClassName: nginx
# tls:
# - hosts:
# - kubecost-kris.unicorndomain.com
# secretName: kubecost-oauth2-proxy-ingress-tls-secret
rules:
- host: medium-demo.com
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: kubecost-oauth2-proxy-svc
port:
number: 4180
Once all objects are set up in your GitHub repository , ArgoCD will pull the manifests and creates the objects on Kubernetes.
5- Deploy Hello World Application
In that stage , it is very simple as we will do it with ArgoCD like before , so I would skip the steps as they are the same.
This deployment is very simple but there is something we need to explain here , It is the ingress Object.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubecost-cost-analyzer
namespace: medium
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /oauth2
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
nginx.ingress.kubernetes.io/proxy-body-size: "2000m"
nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
meta.helm.sh/release-name: medium
meta.helm.sh/release-namespace: medium
nginx.ingress.kubernetes.io/auth-url: "http://medium-demo.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "http://medium-demo.com/oauth2/start?rd=https://medium-demo.com/oauth2/callback"
labels:
app: cost-analyzer
app.kubernetes.io/instance: kubecost
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: cost-analyzer
spec:
ingressClassName: nginx
#tls:
#- hosts:
# - kubecost-kris.unicorndomain.com
# secretName: kubecost-cost-analyzer-tls-cert
rules:
- host: medium-demo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world
port:
number: 80