Traefik x-forwarded-for headers

To describe the concept of the x-forwarded-for headers and how to configure additionally those headers Kubernetes cluster is needed. K3s is easy to install and ready to use Kubernetes cluster.

Read a detailed article on how to install k3s.

Install k3s kubernetes cluster
What is k3s? K3s is a lightweight and certified Kubernetes distribution built by the Rancher. It’s currently in the sandbox projects category at the CNCF. K3s is a production-grade distribution of Kubernetes which is in nature lightweight and the foremost reason for building it was the need to use…

A shorter version of how to install with one-liner is given below.

curl -sfL https://get.k3s.io | sh -

X-forwarded-for headers on Traefik

By default, the following headers are automatically added when proxying requests:

To describe the concept of the x-forwarded-for headers and how to configure additionally those headers Kubernetes cluster is needed. K3s is easy to install and ready to use Kubernetes cluster.

Read a detailed article on how to install k3s.

Install k3s kubernetes cluster
What is k3s? K3s is a lightweight and certified Kubernetes distribution built by the Rancher. It’s currently in the sandbox projects category at the CNCF. K3s is a production-grade distribution of Kubernetes which is in nature lightweight and the foremost reason for building it was the need to use…

A shorter version of how to install with one-liner is given below.

curl -sfL https://get.k3s.io | sh -

X-forwarded-for headers on Traefik

By default, the following headers are automatically added when proxying requests:

Client's IP X-Forwarded-For, X-Real-Ip
Host X-Forwarded-Host
Port X-Forwarded-Port
Protocol X-Forwarded-Proto
Proxy Server's Hostname X-Forwarded-Server

Deploy nginx, clusterIP service for nginx, and ingress which will Traefik forward from itself to the nginx container.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: my-service
            port:
              number: 80
        path: /nginx
        pathType: Prefix

After applying this YAML manifest we can send requests to the Nginx easily.

$ curl localhost/nginx
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>

Debugging the deployed pod can show us information about the network packets going through the nginx container. Using ephemeral containers for attaching to the running pod can do this.

$ k debug -it nginx-deployment-557757876d-v5fm9 --image=leodotcloud/swiss-army-knife --target=nginx -- /bin/bash
Targeting container "nginx". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-5lqvt.
If you don't see a command prompt, try pressing enter.
root@nginx-deployment-557757876d-v5fm9:~# tcpdump -i eth0 -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

Tcpdump command will listen to the HTTP GET request and will display everything about that request.

Sending the the curl request to the localhost/nginx will provide information like shown below.

Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Sec-Ch-Ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.42.0.14
X-Forwarded-Host: localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-7fbbb44c44-kwsqk
X-Real-Ip: 10.42.0.14

After inspection of the headers from the incoming request:

  • X-Forwarded-For: 10.42.0.14
  • X-Forwarded-Host: localhost
  • X-Forwarded-Port: 80
  • X-Forwarded-Proto: http
  • X-Forwarded-Server: traefik-7fbbb44c44-kwsqk
  • X-Real-Ip: 10.42.0.14

All this information provides data about the source of the incoming requests that can be used to condition the response to the request.

Subscribe to qdnqn

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
qdnqn@example.com
Subscribe
Join other 14 members. Unsubscribe whenever you want.