IPv6 and private subnets in OCI
Sven Illert -
IPv6 is raoming around since many years, it was launched in 1998. That’s 26 years ago and it is still not used by default in many locations. Why is that, especially when IPv6 is the recommended protocol for internet communication? Unfortunately IPv6 isn’t default even with modern cloud providers like Oracle with it’s OCI.
Of course you will get a world wide usable and routed subnet if you like, but you have to enable it by yourself in the first place. You’ll get DHCPv6 for free with recurring adresses, so that you can name things even after a reboot. But in difference to IPv4 you’re not able to communicate with the internet if your resource is in a private subnet as shown in the diagram below.
But there’s a problem with modern operating systems in this setup. Of course you can get operating system updates using a service gateway but what if you want to download something with wget? The most tools on Linux use IPv6 by default if it is enabled and there’s an AAAA record for the domain of the resource you want to access over the internet. How could you solve the problem then? There’s many ways to do this, but I’d like to show you a way that is possible using Oracles generous Free Tier offer.
For being able to access the internet from a private subnet of course you need some sort of gateway. Oracle doesn’t offer a NAT gateway for IPv6 so we need to build our own which can be a simple A1 Flex VM in a public subnet. Of course it has to have IPv6 enabled too which is pretty easy when using Oracle Linux itself. You just need to assign an IPv6 prefix to all involved subnets and vcns. Linux will automatically discover the prefix and will get a fixed address from that space via DHCPv6.
The next step is to define to a route into the internet using that gateway vm. The destination CIDR block would be ::/0
(which is the equivalent to 0.0.0.0/0
in IPv4) and the target selection would be the IPv6 address of your VM which you can retrieve via the ip addr
command on the pub-vm. Have a look at the inet6 prefixed lines, in my case the target IPv6 address of the pub-vm would be 2603:c020:8015:XXXX:YYYY:ZZ:1111:2222
.
% hostname -f
pub-vm.public.vcn.oraclevcn.com
% ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:17:0d:XX:XX brd ff:ff:ff:ff:ff:ff
inet 10.42.XXX.XXX/24 brd 10.42.XXX.XXX scope global dynamic noprefixroute enp0s6
valid_lft 80813sec preferred_lft 80813sec
--> inet6 2603:c020:8015:XXXX:YYYY:ZZ:1111:2222/128 scope global dynamic noprefixroute
valid_lft 62106sec preferred_lft 58506sec
inet6 fe80::17ff:fe0d:4c42/64 scope link noprefixroute
valid_lft forever preferred_lft forever
With this address we can create a route for the routing table of the private subnet, where the IPv6 routing into the internet will be sent to our pub-vm. To achieve this you need to select the route table for your private network from your VCN configuration and add a new route. Then you have to select IPv6 as a protocol with the target type of IPv6 Address, a destination CIDR block with ::/0
, and the IPv6 address from above for the Target Selection.
With this in place you just need to do two more things.
- Add a network security group that allows egress communication on both machines for port 80, 443 or whatever you want for the CIDR range
::/0
. - Configure IPv6 forwarding on the pub-vm that acts as an IPv6 router in this configuration.
I think you know how to achieve the former. The latter depends on which operating system you are using. For any Red Hat based distributions, like Oracle Linux, you can configure your firewalld with the following command. For the source address you should configure the CIDR block of your private network. You also have to enable the option “Skip source/destination check” fo the VNIC of pub-vm, otherwise routing wouldn’t work.
% firewall-cmd --zone=public --add-rich-rule='rule family="ipv6" source address="2603:c020:8015:XXXX:0000:0000:0000:0000/64" masquerade' --permanent
% firewall-cmd --reload
With this configuration I am now able to connect via the current default IP protocol to the internet even from within an private subnet. HTH!