Enabling CloudFlare's Argo Tunnel in an AKS cluster

12/2/2020

I am in the process to set up CloudFlare's Argo tunnel with our existing AKS cluster. I have created a Docker image containing the necessary configuration to proxy incoming requests to our ingress service (we are using Kubernetes Nginx Ingress. We have completed the necessary pre-requisite steps in the CloudFlare portal to enable the Argo tunnel connection and I can see that when our CloudFlare tunnel container starts up, it successfully creates 4 connections to the tunnel. However, we cannot get to our website and in the logs we are seeing a certificate related issue. We have tried setting the URL property in the cloudflared config.yml with the internal Kubernetes address and the internal IP address of the ingress service.

# Deployment file
...
 containers:
  - name: cloudflared-container
    image: <CLOUDFLARED_IMAGE>
    imagePullPolicy: Always
    command: ["cloudflared", "tunnel", "--config", "/cloudflare/config.yml", "--no-autoupdate", "run"]
    args: ["--force", "--credentials-file", "/cloudflare/tunnel-credentials.json", "<TUNNEL_GUID>"]

Using the address:

# CONFIG.YML
url: https://<INGRESS_CONTROLLER_NAME>.default.svc.cluster.local:443
tunnel: <TUNNEL_GUID>
loglevel: debug

We see the following in the cloudflared pod logs

ERROR[2020-12-02T15:08:33Z] HTTP request error: Error proxying request to origin: x509: certificate is valid for ingress.local, not <INGRESS_CONTROLLER_NAME>.default.svc.cluster.local

Using the IP Address

# CONFIG.YML
url: https://<INTERNAL_INGRESS_SVC_IP_ADDRESS>:443
tunnel: <TUNNEL_GUID>
loglevel: debug

We see the following in the cloudflared pod logs

ERROR[2020-12-02T14:41:47Z] HTTP request error: Error proxying request to origin: x509: cannot validate certificate for <INTERNAL_INGRESS_SVC_IP_ADDRESS> because it doesn't contain any IP SANs

I also tried using ingress.local as the value for URL in our config.yml but that resulted in the below:

ERROR[2020-12-02T15:16:45Z] HTTP request error: Error proxying request to origin: dial tcp: lookup ingress.local on <CORE_DNS_IP>:53: no such host

I am guessing we either need to setup a CNAME for <INGRESS_CONTROLLER_NAME>.default.svc.cluster.local in our coredns instance in the cluster or generate and apply a certificate that has a valid subject for that address. However I do not know how you do either of these things or if I am going about it in the wrong way so need some help.

EDIT

Hi @AndyPook - yes, it is in the default namespace. I got it to work by adding a host alias to my cloudflared deployment configuration for the hostname "ingress.local" and pointed it to the internal IP address of my nginx ingress loadbalancer:

hostAliases:
  - ip: "nginx IP"
    hostnames:
      - "ingress.local"

However, I had to add no-tls-verify: true to my cloudflared config.yaml as it was trying to validate the ingress.local cert (which I believe is self signed) so was failing.

I still need to replace the ingress.local cert as this isn't a great solution. Ignoring the SSL cert verification is not something we can do in live.

-- Alex Skinner
azure-aks
cloudflare
cloudflare-argo
kubernetes
nginx

1 Answer

1/27/2022

If you are redirecting to the ingress controller and are wanting the certificate for the host that the ingress serves you'll need to add a host header to the request e.g.

ingress:
  - hostname: example.com
    service: https://<INGRESS_CONTROLLER_NAME>.default.svc.cluster.local:443
    originRequest:
      httpHostHeader: "example.com"
-- nick robinson
Source: StackOverflow