Skip to content

Instantly share code, notes, and snippets.

@russelldavies
Created May 29, 2022 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russelldavies/ac45dfea5cc66ed6e3406e0660516daf to your computer and use it in GitHub Desktop.
Save russelldavies/ac45dfea5cc66ed6e3406e0660516daf to your computer and use it in GitHub Desktop.
AWS VPC IPv6-only subnets with IPv4 connectivity using DNS64 and NAT64

This is mainly applicable if you want to have IPv6-only subnets rather than dual-stack. You might do this because you don't want to have to worry about IPv4 address conflicts or whatever.

IPv4 enabled subnet

You must either have or create a separate IPv4 public subnet from the IPv6-only subnet. Configure a NAT gateway (which must have an IPv4 address) in this subnet.

Routing Table

Destination Target
<IPv4 CIDR> local
<IPv6 CIDR> local
0.0.0.0/0 igw
::/0 (optional) igw or eigw

IPv6-only subnet

Enable DNS64 in this subnet.

Routing Table

Destination Target
<IPv4 CIDR> local
<IPv6 CIDR> local
::/0 igw or eigw
64:ff9b::/96 ngw or eni

Custom NAT Gateway

The AWS NAT Gateway is quite expensive so it might be preferable to run an EC2 instance that functions as a NAT gateway.

  1. Launch an EC2 instance of type t4g.nano with Ubuntu in a dual-stack subnet. It must have a public IPv4 address.

  2. Disable "Source/Destination check" in the instance attribute.

  3. Install Jool: sudo apt update && sudo apt install -y jool-dkms jool-tools

  4. Configure Jool with script, create systemd unit and enable it on boot.

References

#!/bin/bash
# Credit to Radek Zajic (zajdee)
# Save the file as e.g. /usr/sbin/jool-init.sh
# Edit to match your dual-stack interface
DUALSTACKIFACE=ens5
modprobe jool
# add namespace and devices to link the two namespaces
ip netns add joolns
ip link add name to_jool type veth peer name from_jool
ip link set dev from_jool netns joolns
# global namespace
ip link set to_jool up
ip -6 addr flush dev to_jool scope link
ip addr add fe80::1/64 scope link dev to_jool
ip addr add 192.0.2.8/24 dev to_jool
# joolns namespace
ip netns exec joolns ip link set from_jool up
ip netns exec joolns ip -6 addr flush dev from_jool scope link
ip netns exec joolns ip addr add fe80::2/64 scope link dev from_jool
ip netns exec joolns ip addr add 192.0.2.1/24 dev from_jool
ip netns exec joolns ip route add default via 192.0.2.8
ip netns exec joolns ip -6 route add default via fe80::1 dev from_jool
ip netns exec joolns sysctl -w net.ipv4.conf.all.forwarding=1
ip netns exec joolns sysctl -w net.ipv6.conf.all.forwarding=1
# create jool instance in the joolns namespace
ip netns exec joolns jool instance add --netfilter --pool6 64:ff9b::/96
# add route to the main namespace
ip route add 64:ff9b::/96 via fe80::2 dev to_jool
# display jool status
ip netns exec joolns jool global display
# masquerade the output from the Jool namespace
# remove if you can route the network or if you masquerade elsewhere
iptables -t nat -A POSTROUTING -o ${DUALSTACKIFACE} -s 192.0.2.1 -j MASQUERADE
# enable IP forwarding
sysctl -w net.ipv4.conf.all.forwarding=1
sysctl -w net.ipv6.conf.all.forwarding=1
exit 0
# Update the path to your jool-init.sh, if it differs
# Save as /etc/systemd/system/jool.service
# Run systemctl daemon reload && systemctl enable jool.service
[Unit]
Description=Jool.mx NAT64 service
[Service]
ExecStart=/usr/sbin/jool-init.sh
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment