|
| 1 | +--- |
| 2 | +title: Using Cilium as a standalone NAT46x64Gateway |
| 3 | +date: 2025-05-01 |
| 4 | +tags: ["IPv6", "Cilium", "eBPF"] |
| 5 | +authors: ["Kapil Agrawal"] |
| 6 | +comments: false |
| 7 | +--- |
| 8 | + |
| 9 | +# Cilium |
| 10 | + |
| 11 | +Since IPv4 and IPv6 are two completely different protocols they are incompatible with one another i.e a host with IPv4 address cannot connect to an application that is only being served over IPv6 and vice-versa. This is where a v4 to v6 translator comes into play. Having a NAT46x64Gateway on the local network simplifies the transition from IPv4 to IPv6 while providing seamless connectivity to applications. |
| 12 | + |
| 13 | +In this blog post I cover how I am running [Cilium](https://cilium.io) as a standalone NAT46x64 gateway which harnesses the power of [eBPF](https://docs.ebpf.io) in the linux kernel. Cilium is a CNCF graduate project which brings advanced networking capabilities to Kubernetes. While it is most commonly used as a CNI (Container Network Interface), not much has been documented about it's capabilities outside of Kubernetes, specially as a standalone NAT46x64 gateway. For my fellow kernel nerds and C lovers, Cilium's NAT46x64 implementation can be found [here](https://github.com/cilium/cilium/blob/main/bpf/lib/nat_46x64.h) |
| 14 | + |
| 15 | +## Create a standalone NAT46x64Gateway |
| 16 | + |
| 17 | +Before we get to the real meat and potatoes we need to do some prep work. |
| 18 | + |
| 19 | +- Provision a VM - I am using Ubuntu 22.04LTS with kernel version 5.15.0-138-generic in my setup. |
| 20 | +- Configure networking - A `NAT46x64Gateway` must be dual stacked as it acts as a bridge between IPv4 and IPv6 networks. Here's an example netplan config I am using. |
| 21 | + |
| 22 | +```yaml |
| 23 | +network: |
| 24 | + version: 2 |
| 25 | + renderer: networkd |
| 26 | + ethernets: |
| 27 | + ens18: |
| 28 | + set-name: eth0 |
| 29 | + match: |
| 30 | + macaddress: bc:24:11:ee:19:90 |
| 31 | + accept-ra: false |
| 32 | + addresses: |
| 33 | + - 192.168.2.10/24 |
| 34 | + - 2001:db8:abcd::2/64 |
| 35 | + nameservers: |
| 36 | + addresses: |
| 37 | + - 1.1.1.1 |
| 38 | + - 2606:4700:4700::64 |
| 39 | + routes: |
| 40 | + - to: default |
| 41 | + via: 192.168.2.1 |
| 42 | + - to: default |
| 43 | + via: 2001:db8:abcd::1/64 |
| 44 | +``` |
| 45 | +
|
| 46 | +To get Cilium up and running as a NAT46x64Gateway simply run the Cilium container image with the following options. Notice that we're running cilium with `enabled-k8s=false`. Also pay special attention to `--devices` flag as it must match the interface name (eth0) from our netplan config above. Traffic entering/leaving this interface will be subject to translation. |
| 47 | + |
| 48 | +```sh |
| 49 | +docker run --name cilium-lb -itd \ |
| 50 | + -v /sys/fs/bpf:/sys/fs/bpf \ |
| 51 | + -v /lib/modules:/lib/modules \ |
| 52 | + --privileged=true \ |
| 53 | + --restart=always \ |
| 54 | + --network=host \ |
| 55 | + "quay.io/cilium/cilium:stable" cilium-agent --enable-ipv4=true --enable-ipv6=true --devices=eth0 --datapath-mode=lb-only --enable-k8s=false --bpf-lb-mode=snat --enable-nat46x64-gateway=true |
| 56 | +``` |
| 57 | + |
| 58 | +## Quick test |
| 59 | + |
| 60 | +Let's create another Ubuntu VM as a test host with an IPv6 only address that points to our NAT46x64Gateway. Few noteworthy points in the netplan config shared below. |
| 61 | + |
| 62 | +- The two nameservers are DNS64 servers from dns64.cloudflare-dns.com and dns64.dns.google respectively. You can use any dns server which has dns64 capability.When a client queries a DNS64 server for a hostname which only has an A record setup, the dns64 server sends a response containing the corresponding IPv4 address as well as a translated IPv6 address. |
| 63 | + |
| 64 | +- static route to `64::ff9b/96` which is a special prefix that is used by IPv4/IPv6 translators as defined in [RFC6502](https://datatracker.ietf.org/doc/html/rfc6052). When the DNS64 server responds with the translated IPv6 address, our VM will forward the packet to our NAT46x64Gateway i.e `2001:db8:abcd::2` |
| 65 | + |
| 66 | +```yaml |
| 67 | +root@controller:/home/kagraw# cat /etc/netplan/00-installer-config.yaml |
| 68 | +network: |
| 69 | + version: 2 |
| 70 | + renderer: networkd |
| 71 | + ethernets: |
| 72 | + ens18: |
| 73 | + set-name: eth0 |
| 74 | + match: |
| 75 | + macaddress: bc:24:11:55:02:a5 |
| 76 | + accept-ra: false |
| 77 | + addresses: |
| 78 | + - 2001:db8:dead:beef::2/64 |
| 79 | + nameservers: |
| 80 | + addresses: |
| 81 | + - 2606:4700:4700::64 |
| 82 | + - 2001:4860:4860::64 |
| 83 | + routes: |
| 84 | + - to: default |
| 85 | + via: 2001:db8:dead:beef::1 |
| 86 | + - to: 64:ff9b::/96 |
| 87 | + via: 2001:db8:abcd::2 |
| 88 | +``` |
| 89 | + |
| 90 | +Example: |
| 91 | + |
| 92 | +google.com has both an A record and a AAAA record. |
| 93 | + |
| 94 | +```sh |
| 95 | +root@controller:/home/kagraw# host google.com |
| 96 | +google.com has address 142.250.190.78 |
| 97 | +google.com has IPv6 address 2607:f8b0:4009:803::200e |
| 98 | +``` |
| 99 | + |
| 100 | +github.com only has an A record but since we're using a DNS64 server we receive a (translated) AAAA record as well. |
| 101 | + |
| 102 | +```sh |
| 103 | +root@controller:/home/kagraw# host github.com |
| 104 | +github.com has address 140.82.113.4 |
| 105 | +github.com has IPv6 address 64:ff9b::8c52:7104 |
| 106 | +``` |
| 107 | + |
| 108 | +But since we have a static route to 64:ff9b::/96, any traffic going to github (64:ff9b::8c52:7203) will be forwarded via `2001:db8:abcd::2` i.e our Cilium based NAT46x64Gateway. |
| 109 | + |
| 110 | +```sh |
| 111 | +root@controller:/home/kagraw# curl -6 -v github.com |
| 112 | +* Trying 64:ff9b::8c52:7104:80... |
| 113 | +* Connected to github.com (64:ff9b::8c52:7104) port 80 (#0) |
| 114 | +> GET / HTTP/1.1 |
| 115 | +> Host: github.com |
| 116 | +> User-Agent: curl/7.81.0 |
| 117 | +> Accept: */* |
| 118 | +> |
| 119 | +* Mark bundle as not supporting multiuse |
| 120 | +< HTTP/1.1 301 Moved Permanently |
| 121 | +< Content-Length: 0 |
| 122 | +< Location: https://github.com/ |
| 123 | +< |
| 124 | +* Connection #0 to host github.com left intact |
| 125 | +``` |
| 126 | + |
| 127 | +and Voila!🍾 our Cilium based NAT46x64Gateway is up and running! |
0 commit comments