title: Kubernetes on AWS: Preserving Client IP with nginx-ingress + cert-manager
body: <p>We have setup Kubernetes with <code>nginx-ingress</code> combined with <code>cert-manager</code> to automatically obtain and use SSL certificates for ingress domains using LetsEncrypt using this guide: <a href="https://medium.com/@maninder.bindra/auto-provisioning-of-letsencrypt-tls-certificates-for-kubernetes-services-deployed-to-an-aks-52fd437b06b0" rel="nofollow noreferrer">https://medium.com/@maninder.bindra/auto-provisioning-of-letsencrypt-tls-certificates-for-kubernetes-services-deployed-to-an-aks-52fd437b06b0</a>. The result is that each Ingress defines its own SSL certificate that is automatically provisioned by <code>cert-manager</code>.</p>
  
  <p>This all works well but for one problem, the source IP address of the traffic is lost to applications in Pods. </p>
  
  <p>There is an annotation that is advised to use to apply to the <code>nginx-ingress</code> controller service <code>service.beta.kubernetes.io/aws-load-balancer-backend-protocol: '*'</code>. This has the effect of preserving source IP addresses. However, doing it breaks SSL:</p>
  
  <pre><code>An error occurred during a connection to {my.domain.com}. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG
  </code></pre>
  
  <p>My head is starting to spin. Does anyone know of any approaches to this (it seems to me that this would be a common requirement)?</p>
  
  <p>Ingress configuration:</p>
  
  <pre><code>apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: my-http-ingress
    annotations:
      kubernetes.io/ingress.class: nginx
      certmanager.k8s.io/cluster-issuer: letsencrypt-prod
  spec:
    rules:
    - host: my.host.com
      http:
        paths:
        - path: /
          backend:
            serviceName: my-http-service
            servicePort: 80
    tls:
    - hosts:
      - "my.host.com"
      secretName: malcolmqa-tls
  </code></pre>