Marco_81
Marco_81

Reputation: 163

External OAuth authentication with Nginx in Kubernetes

Having trouble setting up external authentication for a web application behind nginx ingress. When i try to access the URL https://site.example.com from external i get no redirection to Github login, and direct access to web application happens.

Running Pods for my environment:

NAME                              READY   STATUS   
nginx-ingress-68df4dfc4f-wpj5t    1/1     Running  
oauth2-proxy-6675d4b57c-cspw8     1/1     Running   
web-deployment-7d4bd85b46-blxb8   1/1     Running   
web-deployment-7d4bd85b46-nqjgl   1/1     Running   

Active Services:

NAME            TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)                      
nginx-ingress   LoadBalancer   10.96.156.157    192.168.1.82   80:31613/TCP,443:32437/TCP   
oauth2-proxy    ClusterIP      10.100.101.251   <none>         4180/TCP                     
web-service     ClusterIP      10.108.237.188   <none>         8080/TCP                     

Two Ingress resources:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: nginx-ingress
  annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
     nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$request_uri"
  labels:
    app: webapp
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-service
          servicePort: 8080
  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: oauth2-proxy
  namespace: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
  labels:
    app: oauth2-proxy
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - backend:
          serviceName: oauth2-proxy
          servicePort: 4180
        path: /oauth2

  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

Ingress output:

NAME           CLASS    HOSTS              ADDRESS        PORTS     
ingress        <none>   site.example.com   192.168.1.82   80, 443   
oauth2-proxy   <none>   site.example.com                  80, 443   

I see these errors in Ingress oauth2-proxy events:

Events:
  Type     Reason    Age   From                      Message
  ----     ------    ----  ----                      -------
  Warning  Rejected  54m   nginx-ingress-controller  All hosts are taken by other resources

Oauth2-proxy built from deployment here with Client ID, Client Secret and SECRET according to the OAuth app created in my Github account.

No logs found in oauth2-proxy logs, i suppose because it's not invoked in the process.

UPDATE:

This question was incomplete, i forgot to mention the NGINX image empolyed (NGINX 1.9.0 from installation guide).

Changing the image with the below:

NGINX Ingress controller
Release: v0.41.2
Build: d8a93551e6e5798fc4af3eb910cef62ecddc8938
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.4

the error disappears. In brief both Ingress configuration, the one from my question and the other from the answer are working.

Upvotes: 0

Views: 2843

Answers (1)

PjoterS
PjoterS

Reputation: 14092

In your configuration, you are using 2 Ingress. As you described you oauth2-proxy Ingress, in Event section you can find information:

All hosts are taken by other resources

Issue you have encounter here is called Host Collisions. It occured as in your both Ingress you have used:

spec:
  rules:
  - host: site.example.com

In that kind of situation, Ingress is using default algorith called Choosing the Winner.

If multiple resources contend for the same host, the Ingress Controller will pick the winner based on the creationTimestamp of the resources: the oldest resource will win.

As fast solution for your issue is to create one Ingress with 2 paths.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: nginx-ingress
  annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
     nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$request_uri"
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-service
          servicePort: 8080
      - path: /oauth2
        backend:
          serviceName: oauth2-proxy
          servicePort: 4180      
  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

Another way to resolve this issue is to use Merging Configuration for the Same Host, however it shouldn't be applied in this scenario.

As last thing, you can follow official Nginx Ingress tutorial - External OAUTH Authentication

Upvotes: 2

Related Questions