Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: NGING Ingress Controller guide updated to cover global integration options #1469

Merged
merged 5 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 59 additions & 9 deletions docs/content/guides/proxies/nginx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,23 @@ location = /_auth {

== NGINX Ingress Controller

Even one can configure an external auth server globally with vanilla NGINX, there is no way to achieve that with the https://kubernetes.github.io/ingress-nginx/[NGINX Ingress Controller]. Only route based configuration/integration is possible.
=== Global Configuration

=== Using `X-Forwarded-*` headers
==== Using `X-Forwarded-*` headers

To integrate heimdall with the NGINX Ingress Controller you can make use of the `nginx.ingress.kubernetes.io/auth-url`, `nginx.ingress.kubernetes.io/auth-response-headers` and the `nginx.ingress.kubernetes.io/auth-snippet` annotation as shown in the example below. This will result in an NGINX configuration corresponding to the integration option, described in the link:{{< relref "#_second_option" >}}[Forward all information in `X-Forwarded-*` headers] section.
NOTE: The configuration used in the example below requires proper configuration of `trusted_proxies` on heimdall side.

NOTE: The configuration used in the example below requires proper configuration of `trusted_proxies` on heimdall side. On NGINX Ingress Controller side you must allow the usage of `nginx.ingress.kubernetes.io/auth-snippet` (See also https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#allow-snippet-annotations[here]).
Global configuration can be achieved by setting the following properties in controller `ConfigMap`. If you install the NGINX controller via the helm chart, you can add these properties under the `controller.config` property of your helm `values.yaml` file.

[source, yaml]
----
nginx.ingress.kubernetes.io/auth-url: "http://<heimdall service name>.<namespace>.svc.cluster.local:<decision port>" # <1>
nginx.ingress.kubernetes.io/auth-response-headers: Authorization # <2>
nginx.ingress.kubernetes.io/auth-snippet: | # <3>
global-auth-url: "http://<heimdall service name>.<namespace>.svc.cluster.local:<decision port>" # <1>
global-auth-response-headers: Authorization # <2>
global-auth-snippet: | # <3>
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
# other annotations required
----
<1> Configures the controller to use heimdall's decision service endpoint with `<heimdall service name>`, `<namespace>` and `<decision port>` depending on your configuration.
<2> Let NGINX forward the `Authorization` header set by heimdall to the upstream service upon successful response. This configuration depends on
Expand All @@ -150,7 +149,58 @@ your link:{{< relref "/docs/mechanisms/contextualizers.adoc" >}}[Contextualizers
+
NOTE: Without that, heimdall will not be able extracting relevant information from the NGINX request as it does not support NGINX proprietary `X-Original-Method` and `X-Original-Uri` used by it for the same purposes.

=== Alternative Configuration
With that in place, you can simply use the standard https://kubernetes.io/docs/concepts/services-networking/ingress/[`Ingress`] resource, and the NGINX Ingress Controller will ensure, each request will be analyzed by heimdall first.

This will result in an NGINX configuration corresponding to the integration option, described in the link:{{< relref "#_second_option" >}}[Forward all information in `X-Forwarded-*` headers] section.

==== Alternative Configuration

Alternatively, if you don't want configuring `trusted_proxies` and do not rely on the used HTTP scheme, host and port in your rules, you can also use the `location-snippet` and the `server-snippet` to the `ConfigMap` of the NGINX Ingress Controller with values shown below.

This example is an exact copy of the configuration used in the very first link:{{< relref "#_first_option" >}}[integration option] described above.

[source, yaml]
----
location-snippet: |
auth_request /_auth;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
auth_request_set $auth_header $upstream_http_authorization;
proxy_set_header 'Authorization' $auth_header;
proxy_set_header Proxy "";
server-snippet: |
location = /_auth {
internal;
access_log off;
proxy_method $request_method;
proxy_pass http://<heimdall service name>.<namespace>.svc.cluster.local:<decision port>$request_uri;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Host $http_host;
}
----

As with the previous integration option, you can add these properties under the `controller.config` property of your helm `values.yaml` file if you install the NGINX Ingress Controller via helm.

=== Integration on `Ingress` Resource Level

==== Using `X-Forwarded-*` headers

One option to integrate heimdall with the NGINX Ingress Controller on the `Ingress` resource level is making use of the `nginx.ingress.kubernetes.io/auth-url`, `nginx.ingress.kubernetes.io/auth-response-headers` and the `nginx.ingress.kubernetes.io/auth-snippet` annotation as shown in the example below. This approach requires proper configuration of `trusted_proxies` on heimdall side. On NGINX Ingress Controller side you must allow the usage of `nginx.ingress.kubernetes.io/auth-snippet` (See also https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#allow-snippet-annotations[here]).

[source, yaml]
----
nginx.ingress.kubernetes.io/auth-url: "http://<heimdall service name>.<namespace>.svc.cluster.local:<decision port>"
nginx.ingress.kubernetes.io/auth-response-headers: Authorization
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
# other annotations required
----

==== Alternative Configuration

Alternatively, if you don't want configuring `trusted_proxies` and do not rely on the used HTTP scheme, host and port in your rules, you can also use the `nginx.ingress.kubernetes.io/configuration-snippet` and `nginx.ingress.kubernetes.io/server-snippet` annotations and use the configuration shown below.

Expand Down
12 changes: 9 additions & 3 deletions examples/kubernetes/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,15 @@ install-heimdall-pod-monitor:

install-observability-stack: install-grafana install-prometheus install-loki install-tempo install-phlare install-dashboards install-heimdall-pod-monitor

install-nginx-ingress-controller:
install-nginx-ingress-controller global_ext_auth="true":
#!/usr/bin/env bash

valuesFile=$({{global_ext_auth}} && echo global-helm-values.yaml || echo helm-values.yaml)

helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
-n nginx-controller --create-namespace \
--version {{nginx_version}} \
--set controller.allowSnippetAnnotations=true \
-f nginx/${valuesFile} \
--wait

install-contour-ingress-controller:
Expand Down Expand Up @@ -222,7 +226,9 @@ create-cluster:

setup-cluster: create-cluster setup-charts install-lb install-cert-manager

install-ngnix-decision-demo: setup-cluster install-nginx-ingress-controller (install-heimdall "nginx") (install-echo-service "nginx")
install-ngnix-decision-demo: setup-cluster (install-nginx-ingress-controller "false") (install-heimdall "nginx") (install-echo-service "nginx-route-based")

install-ngnix-global-decision-demo: setup-cluster install-nginx-ingress-controller (install-heimdall "nginx") (install-echo-service "nginx-global")

install-contour-decision-demo: setup-cluster install-contour-ingress-controller (install-heimdall "contour") (install-echo-service "contour")

Expand Down
9 changes: 9 additions & 0 deletions examples/kubernetes/nginx/global-helm-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
controller:
config:
global-auth-url: https://heimdall.heimdall.svc.cluster.local:4456
global-auth-response-headers: "Authorization"
global-auth-snippet: |
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
2 changes: 2 additions & 0 deletions examples/kubernetes/nginx/helm-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
controller:
allowSnippetAnnotations: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-app
namespace: quickstarts
labels:
app.kubernetes.io/name: echo-app
spec:
ingressClassName: "nginx"
tls:
- hosts:
- echo-app.local
secretName: echo-app
rules:
- host: echo-app.local
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: echo-app
port:
number: 8080
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- ingress.yaml
Loading