Greek Freak
Greek Freak

Reputation: 385

Kubernetes SSL Redirect Ingress

I am very new to Kubernetes and I am trying to figure out how to set up a http -> https redirect for my kubernetes cluster. I have searched and have tried many different annotations and I am not sure if I am applying them correctly or not. I have pasted my files below and would be happy to share more if more is necessary.

I have tried to adding these lines to the annotation section

nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"

I have also tried to implement this workaround, but have not had success.

Redirect workaround

I appreciate the help!

service.yaml

kind: Service
apiVersion: v1
metadata:
  name: loadbalancer-ingress
  annotations:
    {{- if .Values.loadbalancer.cert }}
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: {{ .Values.loadbalancer.cert | quote }}
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "{{- range .Values.loadbalancer.ports -}}{{- if .ssl -}}{{ .name }},{{- end -}}{{- end -}}"
    {{- end }}
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: {{ .Values.loadbalancer.backend_protocol | quote }}
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
spec:
  type: LoadBalancer
  selector: 
    pod: {{ .Chart.Name }}
  ports:
    {{- range .Values.loadbalancer.ports }}
    - name: {{ .name }}
      port: {{ .port }}
      targetPort: {{ .targetPort }}
    {{- end }}

configmap.yaml

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: {{ .Chart.Name }}-nginx-configuration
data:
  use-proxy-protocol: "false"
  use-forwarded-headers: "true"
  server-tokens: "false"

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: {{ .Chart.Name }}-tcp-services

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: {{ .Chart.Name }}-udp-services

values.yaml

loadbalancer:
  backend_protocol: http
  cert: MY_AWS_CERT
  ports:
    - name: http
      port: 80
      targetPort: 80
      ssl: false
    - name: https
      port: 443
      targetPort: 80
      ssl: true

Upvotes: 7

Views: 25706

Answers (3)

Distnie Manuel
Distnie Manuel

Reputation: 387

Adding the follwing annotations to Ingress will do the job: This will do redirect the followings

  1. HTTP => HTTPS
  2. non-www => WWW
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/configuration-snippet: |-
      proxy_ssl_server_name on;
      proxy_ssl_name $host;
    nginx.ingress.kubernetes.io/from-to-www-redirect: 'true'

Upvotes: 1

Yasen
Yasen

Reputation: 4504

HTTPS for backend

If you wanna to setup https as backend traffic, then replace http->https in values.yaml

Explanation:

service.yaml has:

service.beta.kubernetes.io/aws-load-balancer-backend-protocol: {{ .Values.loadbalancer.backend_protocol | quote }}

It means that aws-load-balancer-backend-protocol is declared in values.yaml

loadbalancer:
  backend_protocol: http

According to AWS part of k8s man:

service.beta.kubernetes.io/aws-load-balancer-backend-protocol: Used on the service to specify the protocol spoken by the backend (pod) behind a listener. If http (default) or https, an HTTPS listener that terminates the connection and parses headers is created. If set to ssl or tcp, a “raw” SSL listener is used. If set to http and aws-load-balancer-ssl-cert is not used then a HTTP listener is used.

HTTPS for frontend

If your question about https for frontend, then setup an ingress-controller. As per ingress man of k8s:

You must have an ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect.

You may need to deploy an Ingress controller such as ingress-nginx.

AWS part of NGINX ingress controller installation guide is here:

In AWS we use a Network load balancer (NLB) to expose the NGINX Ingress controller behind a Service of Type=LoadBalancer.

Network Load Balancer (NLB)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/aws/deploy.yaml

`

TLS termination in AWS Load Balancer (ELB) > In some scenarios is required to terminate TLS in the Load Balancer and not in the ingress controller.

For this purpose we provide a template: deploy-tls-termination.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/aws/deploy-tls-termination.yaml
  • Edit the file and change:
  • VPC CIDR in use for the Kubernetes cluster: proxy-real-ip-cidr: XXX.XXX.XXX/XX
  • AWS Certificate Manager (ACM) ID arn:aws:acm:us-west-2:XXXXXXXX:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX
  • Deploy the manifest: kubectl apply -f deploy-tls-termination.yaml

Upvotes: 3

Arghya Sadhu
Arghya Sadhu

Reputation: 44657

You need to have pods and a clusterIP service in front of those pods and then in the ingress resource you can refer to the service. So ingress controller such as nginx will receive the traffic from client which is outside the kubernetes cluster and forward that traffic to the pods behind the service. The ingress controller itself need to be exposed outside the cluster via a LoadBalancer type service.

Referring from docs here an ingress resource will look like

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        backend:
          serviceName: test
          servicePort: 80

Upvotes: 3

Related Questions