I'm trying to set up a simple HTTP to HTTPS redirect for traffic going to a Kubernetes cluster. The SSL termination is happening on the ELB. When I try to use the nginx.ingress.kubernetes.io/ssl-redirect = true
it results in an infinite redirect which led me to setting up a config map to handle this (nginx-ingress: Too many redirects when force-ssl is enabled).
Now there seems to be no redirection happening at all.
My ingress service is defined as:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "3600"
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:...:certificate/...
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
labels:
k8s-addon: ingress-nginx.addons.k8s.io
name: ingress-nginx
namespace: ingress-nginx
spec:
externalTrafficPolicy: Cluster
ports:
- name: https
port: 443
protocol: TCP
targetPort: http
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app: ingress-nginx
type: LoadBalancer
My config map is defined as:
apiVersion: v1
kind: ConfigMap
data:
client-body-buffer-size: 32M
hsts: "true"
proxy-body-size: 1G
proxy-buffering: "off"
proxy-read-timeout: "600"
proxy-send-timeout: "600"
server-tokens: "false"
ssl-redirect: "false"
upstream-keepalive-connections: "50"
use-proxy-protocol: "true"
http-snippet: |
server {
listen 8080 proxy_protocol;
server_tokens off;
return 307 https://$host$request_uri;
}
metadata:
labels:
app: ingress-nginx
name: nginx-configuration
namespace: ingress-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
name: udp-services
namespace: ingress-nginx
And, the ingress is defined as:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway-ingress
annotations:
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
nginx.ingress.kubernetes.io/cors-allow-origin: gateway.example.com.com/monitor
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: gateway.example.com
http:
paths:
- backend:
serviceName: gateway
servicePort: 8080
path: /
tls:
- hosts:
- gateway.example.com
Terminating at an external load balancer A common strategy for TLS/SSL termination and Kubernetes is to use an external load balancer such as an AWS Elastic Load Balancer or Google Cloud Load Balancer. This approach offloads the computation and management of TLS/SSL to another system.
Classic Load Balancers can't redirect HTTP traffic to HTTPS by default. Instead, configure your rewrite rules for the web servers instances behind the Classic Load Balancer. You must configure your rewrite rules to use the X-Forwarded-Proto header and redirect only HTTP clients.
Select a load balancer, and then choose HTTP Listener. Under Rules, choose View/edit rules. Choose Edit Rule to modify the existing default rule to redirect all HTTP requests to HTTPS.
The issue was the target port I was using on the load balancer not matching the port the redirection server was listening on:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
This was just sending everything to port 80. It should have been this:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
That way it matches up with the ConfigMap's:
data:
...
http-snippet: |
server {
listen 8080 proxy_protocol;
server_tokens off;
return 307 https://$host$request_uri;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With