Thursday 8th May 2025
In the last post I did some route filtering and manipulation in preparation for this post. This post explains how to configure NPTv6 (IPv6 NPT) on a VyOS router.
High-Level Design
Note: ‘3FFF::/20’ is a new IPv6 documentation prefix.
Design
NPTv6 Design
Let’s imagine 3 tenants with IPv6 sharing the same space:
The datacenters local IPv6 Scope is 3FFF:123:abc:3000::/60
Bastuklubben has a scope of 3FFF:123:abc:9000::/60
Customer A has a scope of 3FFF:c1a:fb1:3000::/60
Explanation:
The Local Datacenter network does not need translation. Therefore the prefix will always be 3FFF:123:abc:3000::/60
Bastuklubben is my home/testing environment and will be translated:
from 3FFF:123:abc:9000::/60
to 3FFF:123:abc:3010::/60
The customer A network will also be translated:
from 3FFF:c1a:fb1:3000::/60
to 3FFF:123:abc:123:3020::/60
The first 60 bits will be translated on both of them. When NPTv6 has been configured, this is how it looks from the firewalls perspective:
VyOS Configuration
All configuration will be made on the VyOS router.
Translate from Inside to Outside
Configuring anything NAT related really makes your head spin. It’s recommended to draw it out to better see where the translations takes place and in what direction.
NAT66 commands are used to configure NPTv6
Source: https://docs.vyos.io/en/sagitta/configuration/nat/nat66.html
To translate traffic from inside (untranslated) to outside (translated):
set nat66 source rule 10010 description 'Translate DC1_SAUNA -> LBS'
set nat66 source rule 10010 outbound-interface name 'eth1.3001'
set nat66 source rule 10010 source prefix '3FFF:123:ABC:A000::/60'
set nat66 source rule 10010 translation address '3FFF:123:ABC:1010::/60'
Explanation:
“set nat66 source”
refers to outgoing traffic.“source prefix '3FFF:123:ABC:A000::/60'“
matches the source prefix of the outgoing traffic“translation address '3FFF:123:ABC:1010::/60'“
translates the source prefix of the outgoing traffic to this prefix
Note: the syntax is a bit inconsistent:
“
nat66 source”
is followed by“source/destination prefix”
.“
nat66 destination”
is followed by“source/destination address”
.
Verification
Ping on a VM before NPTv6:
~$ sudo ip vrf exec PUB ping -I 3FFF:123:ABC:9000::1 2620:FE::FE
PING 2620:FE::FE (2620:fe::fe) from 3fff:123:abc:9000::1 : 56 data bytes
^C
--- 2620:FE::FE ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2073ms
Ping after NPTv6:
~$ sudo ip vrf exec PUB ping -I 3FFF:123:ABC:9000::1 2620:FE::FE
PING 2620:FE::FE (2620:fe::fe) from 3fff:123:abc:9000::1 : 56 data bytes
64 bytes from 2620:fe::fe: icmp_seq=1 ttl=59 time=5.05 ms
64 bytes from 2620:fe::fe: icmp_seq=2 ttl=59 time=5.22 ms
64 bytes from 2620:fe::fe: icmp_seq=3 ttl=59 time=4.61 ms
NAT66 verification command:
vyos@LBS-RO1:~$ show nat66 source translations
Pre-NAT Post-NAT Proto Timeout Mark
---------------------- ---------------------- ------- --------- ----
3fff:123:abc:9000::1 3fff:123:abc:3010::1 icmpv6 29 0
Note: If the firewall does not have a route towards the translated prefix, it will drop the packets when they return. You can configure a summary route on the router but additionally you either need to have at least one dummy interface or a node that is always up for the summary route to be advertised.
Translate from Outside to Inside
To translate traffic from outside to inside:
set nat66 destination rule 30010 description 'Translate LBS --> DC1_SAUNA'
set nat66 destination rule 30010 destination address '3FFF:123:ABC:3010::/60'
set nat66 destination rule 30010 inbound-interface name 'eth1.3003'
set nat66 destination rule 30010 translation address '3FFF:123:ABC:9000::/60'
Explanation:
“set nat66 destination”
refers to incoming traffic.“destination address '3FFF:123:ABC:3010::/60'“
matches the destination prefix of the incoming traffic“translation address '3FFF:123:ABC:1010::/60'“
translates the destination prefix of the incoming traffic to this prefix
Verification
I’m pinging from the firewall. Before NPTv6:
Enter a host name or IP address: 2001:464F:6F83:3010::1
PING(56=40+8+8 bytes) 2001:464f:6f83:3::1 --> 2001:464f:6f83:3010::1
--- 2001:464F:6F83:3010::1 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
Ping after NPTv6 configuration:
Enter a host name or IP address: 3FFF:123:ABC:3010::1
PING(56=40+8+8 bytes) 3fff:123:abc:3::1 --> 3fff:123:abc:3010::1
16 bytes from 3fff:123:abc:3010::1, icmp_seq=0 hlim=63 time=1.840 ms
16 bytes from 3fff:123:abc:3010::1, icmp_seq=1 hlim=63 time=1.002 ms
16 bytes from 3fff:123:abc:3010::1, icmp_seq=2 hlim=63 time=1.130 ms
NAT66 verification command:
vyos@LBS-RO1:~$ show nat66 destination translations
Pre-NAT Post-NAT Proto Timeout Mark
---------------------- ---------------------- ------- --------- ----
3fff:123:abc:3010::1 3fff:123:abc:9000::1 icmpv6 18 0
That’s it. Just a one consideration…
Known Limitation
…If I would like to initiate a connection from DC2 to DC1 or vice versa, I have to use the inside addresses. If I’m trying to reach nodes using their outside addresses, the return traffic will be asymmetrical.
Therefore I have blocked all traffic between 3FFF:123:ABC::/49
and 3FFF:123:ABC:8000::/49
. More on that in the upcoming posts.
Appendix
More Translations
You can translate both source and destination prefix in both directions.
Example 1:
set nat66 source rule 30011 destination prefix '3FFF:123:ABC:1010::/60'
set nat66 source rule 30011 outbound-interface name eth1.4003
set nat source rule 30011 translation address '2001:DB8:123:567::/60'
Explanation: This would translate the source address to 2001:DB8:1234:5678::/60'
for outgoing traffic destined to '3FFF:123:ABC:1010::/60'
Example 2:
set nat66 destination rule 30011 source address '2001:DB8:123:567::/60'
set nat66 destination rule 30011 inbound-interface name eth1.4003
set nat66 destination rule 30011 translation address 3FFF:123:ABC:3010::/60
Explanation: This would translate the destination address to “3FFF:123:ABC:3010::/60”
for traffic sourced from “2001:DB8:123:567::/60”
I’m not sure why anyone would perform these types of translations, but at least there is an option for those eventual corner cases.