summaryrefslogtreecommitdiff
path: root/docs/configuration/nat
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-05-02 17:25:47 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-05-06 16:18:03 +0300
commitfa54a080fac977157454beb0853daf0ac0e6af66 (patch)
tree82b112cde06437b80515450d63eb793bee198ec6 /docs/configuration/nat
parent746195618941d8be8ed132f4b0be539763ec352d (diff)
downloadvyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.tar.gz
vyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.zip
feat(swap): import .md files and webp transition from myst/current
Selective import from origin/myst/current (cf9c9b34): - Add/update 255 .md files (full MyST conversion plus webp ref updates) - Delete 175 PNG/JPG from docs/_static/images (webp twins already present) - Delete 5 autotest topology.png (webp twins already present) Preserved on swap (untouched): - All .rst files (incremental swap pattern) - conf.py, _ext/, _include/*.txt, .gitignore - 115 canary md-*.md files - 7 superpowers/specs/*.md design docs - Logos vyos-logo.png / vyos-logo-icon.png (referenced by conf.py) 🤖 Generated by [robots](https://vyos.io)
Diffstat (limited to 'docs/configuration/nat')
-rw-r--r--docs/configuration/nat/cgnat.md200
-rw-r--r--docs/configuration/nat/index.md13
-rw-r--r--docs/configuration/nat/nat44.md788
-rw-r--r--docs/configuration/nat/nat64.md73
-rw-r--r--docs/configuration/nat/nat66.md243
5 files changed, 1317 insertions, 0 deletions
diff --git a/docs/configuration/nat/cgnat.md b/docs/configuration/nat/cgnat.md
new file mode 100644
index 00000000..914a466b
--- /dev/null
+++ b/docs/configuration/nat/cgnat.md
@@ -0,0 +1,200 @@
+(cgnat)=
+
+# CGNAT
+
+{abbr}`CGNAT (Carrier-Grade Network Address Translation)` , also known as
+Large-Scale NAT (LSN), is a type of network address translation used by
+Internet Service Providers (ISPs) to enable multiple private IP addresses to
+share a single public IP address. This technique helps to conserve the limited
+IPv4 address space.
+The 100.64.0.0/10 address block is reserved for use in carrier-grade NAT
+
+## Overview
+
+CGNAT works by placing a NAT device within the ISP's network. This device
+translates private IP addresses from customer networks to a limited pool of
+public IP addresses assigned to the ISP. This allows many customers to share a
+smaller number of public IP addresses.
+
+Not all {rfc}`6888` requirements are implemented in CGNAT.
+
+Implemented the following {rfc}`6888` requirements:
+
+- REQ 2: A CGN must have a default "IP address pooling" behavior of "Paired".
+ CGN must use the same external IP address mapping for all sessions associated
+ with the same internal IP address, be they TCP, UDP, ICMP, something else,
+ or a mix of different protocols.
+- REQ 3: The CGN function should not have any limitations on the size or the
+ contiguity of the external address pool.
+- REQ 4: A CGN must support limiting the number of external ports (or,
+ equivalently, "identifiers" for ICMP) that are assigned per subscriber
+
+### Advantages of CGNAT
+
+- **IPv4 Address Conservation**: CGNAT helps mitigate the exhaustion of IPv4 addresses by allowing multiple customers to share a single public IP address.
+- **Scalability**: ISPs can support more customers without needing a proportional increase in public IP addresses.
+- **Cost-Effective**: Reduces the cost associated with acquiring additional public IPv4 addresses.
+
+### Considerations
+
+- **Traceability Issues**: Since multiple users share the same public IP address, tracking individual users for security and legal purposes can be challenging.
+- **Performance Overheads**: The translation process can introduce latency and potential performance bottlenecks, especially under high load.
+- **Application Compatibility**: Some applications and protocols may not work well with CGNAT due to their reliance on unique public IP addresses.
+- **Port Allocation Limits**: Each public IP address has a limited number of ports, which can be exhausted, affecting the ability to establish new connections.
+- **Port Control Protocol**: PCP is not implemented.
+
+## Port calculation
+
+When implementing CGNAT, ensuring that there are enough ports allocated per subscriber is critical. Below is a summary based on RFC 6888.
+
+1. **Total Ports Available**:
+
+ - Total Ports: 65536 (0 to 65535)
+ - Reserved Ports: Assume 1024 ports are reserved for well-known services and administrative purposes.
+ - Usable Ports: 65536 - 1024 = 64512
+
+2. **Estimate Ports Needed per Subscriber**:
+
+ - Example: A household might need 1000 ports to ensure smooth operation for multiple devices and applications.
+
+3. **Calculate the Number of Subscribers per Public IP**:
+
+ - Usable Ports / Ports per Subscriber
+ - 64512 / 1000 ≈ 64 subscribers per public IP
+
+## Configuration
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> external-port-range \<port-range\>
+
+Set an external port-range for the external pool, the default range is
+1024-65535. Multiple entries can be added to the same pool.
+```
+
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> per-user-limit port \<num\>
+
+Set external source port limits that will be allocated to each subscriber
+individually. The default value is 2000.
+```
+
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> range [address | address range | network] [seq]
+
+Set the range of external IP addresses for the CGNAT pool.
+The sequence is optional; if set, a lower value means higher priority.
+```
+
+
+```{cfgcmd} set nat cgnat pool internal \<pool-name\> range [address range | network]
+
+Set the range of internal IP addresses for the CGNAT pool.
+```
+
+
+```{cfgcmd} set nat cgnat rule \<num\> source pool \<internal-pool-name\>
+
+Set the rule for the source pool.
+```
+
+
+```{cfgcmd} set nat cgnat rule \<num\> translation pool \<external-pool-name\>
+
+Set the rule for the translation pool.
+```
+
+
+```{cfgcmd} set nat cgnat log-allocation
+
+Enable logging of IP address and ports allocations.
+```
+
+
+## Configuration Examples
+
+### Single external address
+
+Example of setting up a basic CGNAT configuration:
+In the following example, we define an external pool named `ext-1` with one
+external IP address.
+
+Each subscriber will be allocated a maximum of 2000 ports from the external pool.
+
+```none
+set nat cgnat pool external ext1 external-port-range '1024-65535'
+set nat cgnat pool external ext1 per-user-limit port '2000'
+set nat cgnat pool external ext1 range '192.0.2.222/32'
+set nat cgnat pool internal int1 range '100.64.0.0/28'
+set nat cgnat rule 10 source pool 'int1'
+set nat cgnat rule 10 translation pool 'ext1'
+```
+
+
+### Multiple external addresses
+
+```none
+set nat cgnat pool external ext1 external-port-range '1024-65535'
+set nat cgnat pool external ext1 per-user-limit port '8000'
+set nat cgnat pool external ext1 range '192.0.2.1-192.0.2.2'
+set nat cgnat pool external ext1 range '203.0.113.253-203.0.113.254'
+set nat cgnat pool internal int1 range '100.64.0.1-100.64.0.32'
+set nat cgnat rule 10 source pool 'int1'
+set nat cgnat rule 10 translation pool 'ext1'
+```
+
+
+### External address sequences
+
+```none
+set nat cgnat pool external ext-01 per-user-limit port '16000'
+set nat cgnat pool external ext-01 range 203.0.113.1/32 seq '10'
+set nat cgnat pool external ext-01 range 192.0.2.1/32 seq '20'
+set nat cgnat pool internal int-01 range '100.64.0.0/29'
+set nat cgnat rule 10 source pool 'int-01'
+set nat cgnat rule 10 translation pool 'ext-01'
+```
+
+
+## Operation commands
+
+```{opcmd} show nat cgnat allocation
+
+Show address and port allocations
+```
+
+```{opcmd} show nat cgnat allocation external-address \<address\>
+
+Show all allocations for an external IP address
+```
+
+```{opcmd} show nat cgnat allocation internal-address \<address\>
+
+Show all allocations for an internal IP address
+```
+
+
+### Show CGNAT allocations
+
+```none
+vyos@vyos:~$ show nat cgnat allocation
+Internal IP External IP Port range
+------------- ------------- ------------
+100.64.0.0 203.0.113.1 1024-17023
+100.64.0.1 203.0.113.1 17024-33023
+100.64.0.2 203.0.113.1 33024-49023
+100.64.0.3 203.0.113.1 49024-65023
+100.64.0.4 192.0.2.1 1024-17023
+100.64.0.5 192.0.2.1 17024-33023
+100.64.0.6 192.0.2.1 33024-49023
+100.64.0.7 192.0.2.1 49024-65023
+
+vyos@vyos:~$ show nat cgnat allocation internal-address 100.64.0.4
+Internal IP External IP Port range
+------------- ------------- ------------
+100.64.0.4 192.0.2.1 1024-17023
+```
+
+
+## Further Reading
+
+- {rfc}`6598` - IANA-Reserved IPv4 Prefix for Shared Address Space
+- {rfc}`6888` - Requirements for CGNAT
diff --git a/docs/configuration/nat/index.md b/docs/configuration/nat/index.md
new file mode 100644
index 00000000..35e5d32b
--- /dev/null
+++ b/docs/configuration/nat/index.md
@@ -0,0 +1,13 @@
+(nat)=
+
+# NAT
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+nat44
+nat64
+nat66
+cgnat
+```
diff --git a/docs/configuration/nat/nat44.md b/docs/configuration/nat/nat44.md
new file mode 100644
index 00000000..4f5bd580
--- /dev/null
+++ b/docs/configuration/nat/nat44.md
@@ -0,0 +1,788 @@
+(nat44)=
+
+# NAT44
+
+{abbr}`NAT (Network Address Translation)` is a common method of
+remapping one IP address space into another by modifying network address
+information in the IP header of packets while they are in transit across
+a traffic routing device. The technique was originally used as a
+shortcut to avoid the need to readdress every host when a network was
+moved. It has become a popular and essential tool in conserving global
+address space in the face of IPv4 address exhaustion. One
+Internet-routable IP address of a NAT gateway can be used for an entire
+private network.
+
+IP masquerading is a technique that hides an entire IP address space,
+usually consisting of private IP addresses, behind a single IP address
+in another, usually public address space. The hidden addresses are
+changed into a single (public) IP address as the source address of the
+outgoing IP packets so they appear as originating not from the hidden
+host but from the routing device itself. Because of the popularity of
+this technique to conserve IPv4 address space, the term NAT has become
+virtually synonymous with IP masquerading.
+
+As network address translation modifies the IP address information in
+packets, NAT implementations may vary in their specific behavior in
+various addressing cases and their effect on network traffic. The
+specifics of NAT behavior are not commonly documented by vendors of
+equipment containing NAT implementations.
+
+The computers on an internal network can use any of the addresses set
+aside by the {abbr}`IANA (Internet Assigned Numbers Authority)` for
+private addressing (see {rfc}`1918`). These reserved IP addresses are
+not in use on the Internet, so an external machine will not directly
+route to them. The following addresses are reserved for private use:
+
+- 10.0.0.0 to 10.255.255.255 (CIDR: 10.0.0.0/8)
+- 172.16.0.0 to 172.31.255.255 (CIDR: 172.16.0.0/12)
+- 192.168.0.0 to 192.168.255.255 (CIDR: 192.168.0.0/16)
+
+If an ISP deploys a {abbr}`CGN (Carrier-grade NAT)`, and uses
+{rfc}`1918` address space to number customer gateways, the risk of
+address collision, and therefore routing failures, arises when the
+customer network already uses an {rfc}`1918` address space.
+
+This prompted some ISPs to develop a policy within the {abbr}`ARIN
+(American Registry for Internet Numbers)` to allocate new private
+address space for CGNs, but ARIN deferred to the IETF before
+implementing the policy indicating that the matter was not a typical
+allocation issue but a reservation of addresses for technical purposes
+(per {rfc}`2860`).
+
+IETF published {rfc}`6598`, detailing a shared address space for use in
+ISP CGN deployments that can handle the same network prefixes occurring
+both on inbound and outbound interfaces. ARIN returned address space to
+the {abbr}`IANA (Internet Assigned Numbers Authority)` for this
+allocation.
+
+The allocated address block is 100.64.0.0/10.
+
+Devices evaluating whether an IPv4 address is public must be updated to
+recognize the new address space. Allocating more private IPv4 address
+space for NAT devices might prolong the transition to IPv6.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat)=
+
+#### SNAT
+
+{abbr}`SNAT (Source Network Address Translation)` is the most common
+form of {abbr}`NAT (Network Address Translation)` and is typically
+referred to simply as NAT. To be more correct, what most people refer
+to as {abbr}`NAT (Network Address Translation)` is actually the process
+of {abbr}`PAT (Port Address Translation)`, or NAT overload. SNAT is
+typically used by internal users/private hosts to access the Internet
+\- the source address is translated and thus kept private.
+
+(destination-nat)=
+
+#### DNAT
+
+{abbr}`DNAT (Destination Network Address Translation)` changes the
+destination address of packets passing through the router, while
+{ref}`source-nat` changes the source address of packets. DNAT is
+typically used when an external (public) host needs to initiate a
+session with an internal (private) host. A customer needs to access a
+private service behind the routers public IP. A connection is
+established with the routers public IP address on a well known port and
+thus all traffic for this port is rewritten to address the internal
+(private) host.
+
+(bidirectional-nat)=
+
+#### Bidirectional NAT
+
+This is a common scenario where both {ref}`source-nat` and
+{ref}`destination-nat` are configured at the same time. It's commonly
+used when internal (private) hosts need to establish a connection with
+external resources and external systems need to access internal
+(private) resources.
+
+### NAT, Routing, Firewall Interaction
+
+There is a very nice picture/explanation in the Vyatta documentation
+which should be rewritten here.
+
+### NAT Ruleset
+
+{abbr}`NAT (Network Address Translation)` is configured entirely on a
+series of so called *rules*. Rules are numbered and evaluated by the
+underlying OS in numerical order! The rule numbers can be changes by
+utilizing the {cfgcmd}`rename` and {cfgcmd}`copy` commands.
+
+:::{note}
+Changes to the NAT system only affect newly established
+connections. Already established connections are not affected.
+:::
+
+:::{hint}
+When designing your NAT ruleset leave some space between
+consecutive rules for later extension. Your ruleset could start with
+numbers 10, 20, 30. You thus can later extend the ruleset and place
+new rules between existing ones.
+:::
+
+Rules will be created for both {ref}`source-nat` and
+{ref}`destination-nat`.
+
+For {ref}`bidirectional-nat` a rule for both {ref}`source-nat` and
+{ref}`destination-nat` needs to be created.
+
+(traffic-filters)=
+
+### Traffic Filters
+
+Traffic Filters are used to control which packets will have the defined
+NAT rules applied. Five different filters can be applied within a NAT
+rule.
+
+- **outbound-interface** - applicable only to {ref}`source-nat`. It
+ configures the interface which is used for the outside traffic that
+ this translation rule applies to. Interface groups, inverted
+ selection and wildcard, are also supported.
+
+ Examples:
+
+ ```none
+ set nat source rule 20 outbound-interface name eth0
+ set nat source rule 30 outbound-interface name bond1*
+ set nat source rule 20 outbound-interface name !vtun2
+ set nat source rule 20 outbound-interface group GROUP1
+ set nat source rule 20 outbound-interface group !GROUP2
+ ```
+
+- **inbound-interface** - applicable only to {ref}`destination-nat`. It
+ configures the interface which is used for the inside traffic the
+ translation rule applies to. Interface groups, inverted
+ selection and wildcard, are also supported.
+
+ Example:
+
+ ```none
+ set nat destination rule 20 inbound-interface name eth0
+ set nat destination rule 30 inbound-interface name bond1*
+ set nat destination rule 20 inbound-interface name !vtun2
+ set nat destination rule 20 inbound-interface group GROUP1
+ set nat destination rule 20 inbound-interface group !GROUP2
+ ```
+
+- **protocol** - specify which types of protocols this translation rule
+ applies to. Only packets matching the specified protocol are NATed.
+ By default this applies to *all* protocols.
+
+ Example:
+
+ - Set SNAT rule 20 to only NAT TCP and UDP packets
+ - Set DNAT rule 20 to only NAT UDP packets
+
+ ```none
+ set nat source rule 20 protocol tcp_udp
+ set nat destination rule 20 protocol udp
+ ```
+
+- **source** - specifies which packets the NAT translation rule applies
+ to based on the packets source IP address and/or source port. Only
+ matching packets are considered for NAT.
+
+ Example:
+
+ - Set SNAT rule 20 to only NAT packets arriving from the 192.0.2.0/24
+ network
+ - Set SNAT rule 30 to only NAT packets arriving from the 203.0.113.0/24
+ network with a source port of 80 and 443
+
+ ```none
+ set nat source rule 20 source address 192.0.2.0/24
+ set nat source rule 30 source address 203.0.113.0/24
+ set nat source rule 30 source port 80,443
+ ```
+
+- **destination** - specify which packets the translation will be
+ applied to, only based on the destination address and/or port number
+ configured.
+
+ :::{note}
+ If no destination is specified the rule will match on any
+ destination address and port.
+ :::
+
+ Example:
+
+ - Configure SNAT rule (40) to only NAT packets with a destination
+ address of 192.0.2.1.
+
+ ```none
+ set nat source rule 40 destination address 192.0.2.1
+ ```
+
+### Address Conversion
+
+Every NAT rule has a translation command defined. The address defined
+for the translation is the address used when the address information in
+a packet is replaced.
+
+#### Source Address
+
+For {ref}`source-nat` rules the packets source address will be replaced
+with the address specified in the translation command. A port
+translation can also be specified and is part of the translation
+address.
+
+:::{note}
+The translation address must be set to one of the available
+addresses on the configured *outbound-interface* or it must be set to
+*masquerade* which will use the primary IP address of the
+*outbound-interface* as its translation address.
+:::
+
+:::{note}
+When using NAT for a large number of host systems it
+recommended that a minimum of 1 IP address is used to NAT every 256
+private host systems. This is due to the limit of 65,000 port numbers
+available for unique translations and a reserving an average of
+200-300 sessions per host system.
+:::
+
+Example:
+
+- Define a discrete source IP address of 100.64.0.1 for SNAT rule 20
+- Use address *masquerade* (the interfaces primary address) on rule 30
+- For a large amount of private machines behind the NAT your address
+ pool might to be bigger. Use any address in the range 100.64.0.10 -
+ 100.64.0.20 on SNAT rule 40 when doing the translation
+
+```none
+set nat source rule 20 translation address 100.64.0.1
+set nat source rule 30 translation address 'masquerade'
+set nat source rule 40 translation address 100.64.0.10-100.64.0.20
+```
+
+#### Destination Address
+
+For {ref}`destination-nat` rules the packets destination address will be
+replaced by the specified address in the *translation address* command.
+
+Example:
+
+- DNAT rule 10 replaces the destination address of an inbound packet
+ with 192.0.2.10
+
+```none
+set nat destination rule 10 translation address 192.0.2.10
+```
+
+Also, in {ref}`destination-nat`, redirection to localhost is supported.
+The redirect statement is a special form of dnat which always translates
+the destination address to the local host’s one.
+
+Example of redirection:
+
+```none
+set nat destination rule 10 translation redirect port 22
+```
+
+### NAT Load Balance
+
+Advanced configuration can be used in order to apply source or destination NAT,
+and within a single rule, be able to define multiple translated addresses,
+so NAT balances the translations among them.
+
+NAT Load Balance uses an algorithm that generates a hash and based on it, then
+it applies corresponding translation. This hash can be generated randomly, or
+can use data from the ip header: source-address, destination-address,
+source-port and/or destination-port. By default, it will generate the hash
+randomly.
+
+When defining the translated address, called `backends`, a `weight` must
+be configured. This lets the user define load balance distribution according
+to their needs. Them sum of all the weights defined for the backends should
+be equal to 100. In oder words, the weight defined for the backend is the
+percentage of the connections that will receive such backend.
+
+```{cfgcmd} set nat [source | destination] rule \<rule\> load-balance hash [source-address | destination-address | source-port | destination-port | random]
+```
+
+```{cfgcmd} set nat [source | destination] rule \<rule\> load-balance backend \<x.x.x.x\> weight \<1-100\>
+```
+
+## Configuration Examples
+
+To setup SNAT, we need to know:
+- The internal IP addresses we want to translate
+- The outgoing interface to perform the translation on
+- The external IP address to translate to
+
+In the example used for the Quick Start configuration above, we
+demonstrate the following configuration:
+
+```none
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 source address '192.168.0.0/24'
+set nat source rule 100 translation address 'masquerade'
+```
+
+Which generates the following configuration:
+
+```none
+rule 100 {
+ outbound-interface {
+ name eth0
+ }
+ source {
+ address 192.168.0.0/24
+ }
+ translation {
+ address masquerade
+ }
+}
+```
+
+In this example, we use **masquerade** as the translation address
+instead of an IP address. The **masquerade** target is effectively an
+alias to say "use whatever IP address is on the outgoing interface",
+rather than a statically configured IP address. This is useful if you
+use DHCP for your outgoing interface and do not know what the external
+address will be.
+
+When using NAT for a large number of host systems it recommended that a
+minimum of 1 IP address is used to NAT every 256 host systems. This is
+due to the limit of 65,000 port numbers available for unique
+translations and a reserving an average of 200-300 sessions per host
+system.
+
+Example: For an ~8,000 host network a source NAT pool of 32 IP addresses
+is recommended.
+
+A pool of addresses can be defined by using a hyphen between two IP
+addresses:
+
+```none
+set nat source rule 100 translation address '203.0.113.32-203.0.113.63'
+```
+
+(avoidng-leaky-nat)=
+
+### Avoiding "leaky" NAT
+
+Linux netfilter will not NAT traffic marked as INVALID. This often
+confuses people into thinking that Linux (or specifically VyOS) has a
+broken NAT implementation because non-NATed traffic is seen leaving an
+external interface. This is actually working as intended, and a packet
+capture of the "leaky" traffic should reveal that the traffic is either
+an additional TCP "RST", "FIN,ACK", or "RST,ACK" sent by client systems
+after Linux netfilter considers the connection closed. The most common
+is the additional TCP RST some host implementations send after
+terminating a connection (which is implementation-specific).
+
+In other words, connection tracking has already observed the connection
+be closed and has transition the flow to INVALID to prevent attacks from
+attempting to reuse the connection.
+
+You can avoid the "leaky" behavior by using a firewall policy that drops
+"invalid" state packets.
+
+Having control over the matching of INVALID state traffic, e.g. the
+ability to selectively log, is an important troubleshooting tool for
+observing broken protocol behavior. For this reason, VyOS does not
+globally drop invalid state traffic, instead allowing the operator to
+make the determination on how the traffic is handled.
+
+(hairpin-nat-reflection)=
+
+### Hairpin NAT/NAT Reflection
+
+A typical problem with using NAT and hosting public servers is the
+ability for internal systems to reach an internal server using it's
+external IP address. The solution to this is usually the use of
+split-DNS to correctly point host systems to the internal address when
+requests are made internally. Because many smaller networks lack DNS
+infrastructure, a work-around is commonly deployed to facilitate the
+traffic by NATing the request from internal hosts to the source address
+of the internal interface on the firewall.
+
+This technique is commonly referred to as NAT Reflection or Hairpin NAT.
+
+Example:
+
+- Redirect Microsoft RDP traffic from the outside (WAN, external) world
+ via {ref}`destination-nat` in rule 100 to the internal, private host
+ 192.0.2.40.
+- Redirect Microsoft RDP traffic from the internal (LAN, private)
+ network via {ref}`destination-nat` in rule 110 to the internal,
+ private host 192.0.2.40. We also need a {ref}`source-nat` rule 110 for
+ the reverse path of the traffic. The internal network 192.0.2.0/24 is
+ reachable via interface *eth0.10*.
+
+```none
+set nat destination rule 100 description 'Regular destination NAT from external'
+set nat destination rule 100 destination port '3389'
+set nat destination rule 100 inbound-interface name 'pppoe0'
+set nat destination rule 100 protocol 'tcp'
+set nat destination rule 100 translation address '192.0.2.40'
+
+set nat destination rule 110 description 'NAT Reflection: INSIDE'
+set nat destination rule 110 destination port '3389'
+set nat destination rule 110 inbound-interface name 'eth0.10'
+set nat destination rule 110 protocol 'tcp'
+set nat destination rule 110 translation address '192.0.2.40'
+
+set nat source rule 110 description 'NAT Reflection: INSIDE'
+set nat source rule 110 destination address '192.0.2.0/24'
+set nat source rule 110 outbound-interface name 'eth0.10'
+set nat source rule 110 protocol 'tcp'
+set nat source rule 110 source address '192.0.2.0/24'
+set nat source rule 110 translation address 'masquerade'
+```
+
+Which results in a configuration of:
+
+```none
+vyos@vyos# show nat
+ destination {
+ rule 100 {
+ description "Regular destination NAT from external"
+ destination {
+ port 3389
+ }
+ inbound-interface {
+ name pppoe0
+ }
+ protocol tcp
+ translation {
+ address 192.0.2.40
+ }
+ }
+ rule 110 {
+ description "NAT Reflection: INSIDE"
+ destination {
+ port 3389
+ }
+ inbound-interface {
+ name eth0.10
+ }
+ protocol tcp
+ translation {
+ address 192.0.2.40
+ }
+ }
+ }
+ source {
+ rule 110 {
+ description "NAT Reflection: INSIDE"
+ destination {
+ address 192.0.2.0/24
+ }
+ outbound-interface {
+ name eth0.10
+ }
+ protocol tcp
+ source {
+ address 192.0.2.0/24
+ }
+ translation {
+ address masquerade
+ }
+ }
+ }
+```
+
+### Destination NAT
+
+DNAT is typically referred to as a **Port Forward**. When using VyOS as
+a NAT router and firewall, a common configuration task is to redirect
+incoming traffic to a system behind the firewall.
+
+In this example, we will be using the example Quick Start configuration
+above as a starting point.
+
+To setup a destination NAT rule we need to gather:
+- The interface traffic will be coming in on;
+- The protocol and port we wish to forward;
+- The IP address of the internal system we wish to forward traffic to.
+
+In our example, we will be forwarding web server traffic to an internal
+web server on 192.168.0.100. HTTP traffic makes use of the TCP protocol
+on port 80. For other common port numbers, see:
+<https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers>
+
+Our configuration commands would be:
+
+```none
+set nat destination rule 10 description 'Port Forward: HTTP to 192.168.0.100'
+set nat destination rule 10 destination port '80'
+set nat destination rule 10 inbound-interface name 'eth0'
+set nat destination rule 10 protocol 'tcp'
+set nat destination rule 10 translation address '192.168.0.100'
+```
+
+Which would generate the following NAT destination configuration:
+
+```none
+nat {
+ destination {
+ rule 10 {
+ description "Port Forward: HTTP to 192.168.0.100"
+ destination {
+ port 80
+ }
+ inbound-interface {
+ name eth0
+ }
+ protocol tcp
+ translation {
+ address 192.168.0.100
+ }
+ }
+ }
+}
+```
+:::{note}
+If forwarding traffic to a different port than it is arriving
+on, you may also configure the translation port using
+*set nat destination rule [n] translation port*.
+:::
+
+This establishes our Port Forward rule, but if we created a firewall
+policy it will likely block the traffic.
+
+#### Firewall rules for Destination NAT
+
+It is important to note that when creating firewall rules, the DNAT
+translation occurs **before** traffic traverses the firewall. In other
+words, the destination address has already been translated to
+192.168.0.100.
+
+So in our firewall ruleset, we want to allow traffic which previously matched
+a destination nat rule. In order to avoid creating many rules, one for each
+destination nat rule, we can accept all **'dnat'** connections with one simple
+rule, using `connection-status` matcher:
+
+```none
+set firewall ipv4 forward filter rule 10 action accept
+set firewall ipv4 forward filter rule 10 connection-status nat destination
+set firewall ipv4 forward filter rule 10 state new
+```
+
+This would generate the following configuration:
+
+```none
+ipv4 {
+ forward {
+ filter {
+ rule 10 {
+ action accept
+ connection-status {
+ nat destination
+ }
+ state new
+ }
+ }
+ }
+}
+```
+
+### 1-to-1 NAT
+
+Another term often used for DNAT is **1-to-1 NAT**. For a 1-to-1 NAT
+configuration, both DNAT and SNAT are used to NAT all traffic from an
+external IP address to an internal IP address and vice-versa.
+
+Typically, a 1-to-1 NAT rule omits the destination port (all ports) and
+replaces the protocol with either **all** or **ip**.
+
+Then a corresponding SNAT rule is created to NAT outgoing traffic for
+the internal IP to a reserved external IP. This dedicates an external IP
+address to an internal IP address and is useful for protocols which
+don't have the notion of ports, such as GRE.
+
+Here's an extract of a simple 1-to-1 NAT configuration with one internal
+and one external interface:
+
+```none
+set interfaces ethernet eth0 address '192.168.1.1/24'
+set interfaces ethernet eth0 description 'Inside interface'
+set interfaces ethernet eth1 address '192.0.2.30/24'
+set interfaces ethernet eth1 description 'Outside interface'
+set nat destination rule 2000 description '1-to-1 NAT example'
+set nat destination rule 2000 destination address '192.0.2.30'
+set nat destination rule 2000 inbound-interface name 'eth1'
+set nat destination rule 2000 translation address '192.168.1.10'
+set nat source rule 2000 description '1-to-1 NAT example'
+set nat source rule 2000 outbound-interface name 'eth1'
+set nat source rule 2000 source address '192.168.1.10'
+set nat source rule 2000 translation address '192.0.2.30'
+```
+
+Firewall rules are written as normal, using the internal IP address as
+the source of outbound rules and the destination of inbound rules.
+
+### NAT before VPN
+
+Some application service providers (ASPs) operate a VPN gateway to
+provide access to their internal resources, and require that a
+connecting organisation translate all traffic to the service provider
+network to a source address provided by the ASP.
+
+### Load Balance
+
+Here we provide two examples on how to apply NAT Load Balance.
+
+First scenario: apply destination NAT for all HTTP traffic comming through
+interface eth0, and user 4 backends. First backend should received 30% of
+the request, second backend should get 20%, third 15% and the fourth 35%
+We will use source and destination address for hash generation.
+
+```none
+set nat destination rule 10 inbound-interface name eth0
+set nat destination rule 10 protocol tcp
+set nat destination rule 10 destination port 80
+set nat destination rule 10 load-balance hash source-address
+set nat destination rule 10 load-balance hash destination-address
+set nat destination rule 10 load-balance backend 198.51.100.101 weight 30
+set nat destination rule 10 load-balance backend 198.51.100.102 weight 20
+set nat destination rule 10 load-balance backend 198.51.100.103 weight 15
+set nat destination rule 10 load-balance backend 198.51.100.104 weight 35
+```
+
+Second scenario: apply source NAT for all outgoing connections from
+LAN 10.0.0.0/8, using 3 public addresses and equal distribution.
+We will generate the hash randomly.
+
+```none
+set nat source rule 10 outbound-interface name eth0
+set nat source rule 10 source address 10.0.0.0/8
+set nat source rule 10 load-balance hash random
+set nat source rule 10 load-balance backend 192.0.2.251 weight 33
+set nat source rule 10 load-balance backend 192.0.2.252 weight 33
+set nat source rule 10 load-balance backend 192.0.2.253 weight 34
+```
+
+#### Example Network
+
+Here's one example of a network environment for an ASP.
+The ASP requests that all connections from this company should come from
+172.29.41.89 - an address that is assigned by the ASP and not in use at
+the customer site.
+
+```{eval-rst}
+.. figure:: /_static/images/nat_before_vpn_topology.webp
+ :scale: 100 %
+ :alt: NAT before VPN Topology
+
+ NAT before VPN Topology
+```
+#### Configuration
+
+The required configuration can be broken down into 4 major pieces:
+- A dummy interface for the provider-assigned IP;
+- NAT (specifically, Source NAT);
+- IPSec IKE and ESP Groups;
+- IPSec VPN tunnels.
+
+##### Dummy interface
+
+The dummy interface allows us to have an equivalent of the Cisco IOS
+Loopback interface - a router-internal interface we can use for IP
+addresses the router must know about, but which are not actually
+assigned to a real network.
+
+We only need a single step for this interface:
+
+```none
+set interfaces dummy dum0 address '172.29.41.89/32'
+```
+
+##### NAT Configuration
+
+```none
+set nat source rule 110 description 'Internal to ASP'
+set nat source rule 110 destination address '172.27.1.0/24'
+set nat source rule 110 source address '192.168.43.0/24'
+set nat source rule 110 translation address '172.29.41.89'
+set nat source rule 120 description 'Internal to ASP'
+set nat source rule 120 destination address '10.125.0.0/16'
+set nat source rule 120 source address '192.168.43.0/24'
+set nat source rule 120 translation address '172.29.41.89'
+```
+
+##### IPSec IKE and ESP
+
+The ASP has documented their IPSec requirements:
+- IKE Phase:
+ - aes256 Encryption
+ - sha256 Hashes
+- ESP Phase:
+ - aes256 Encryption
+ - sha256 Hashes
+ - DH Group 14
+
+Additionally, we want to use VPNs only on our eth1 interface (the
+external interface in the image above)
+
+```none
+set vpn ipsec ike-group my-ike key-exchange 'ikev1'
+set vpn ipsec ike-group my-ike lifetime '7800'
+set vpn ipsec ike-group my-ike proposal 1 dh-group '14'
+set vpn ipsec ike-group my-ike proposal 1 encryption 'aes256'
+set vpn ipsec ike-group my-ike proposal 1 hash 'sha256'
+
+set vpn ipsec esp-group my-esp lifetime '3600'
+set vpn ipsec esp-group my-esp mode 'tunnel'
+set vpn ipsec esp-group my-esp pfs 'disable'
+set vpn ipsec esp-group my-esp proposal 1 encryption 'aes256'
+set vpn ipsec esp-group my-esp proposal 1 hash 'sha256'
+
+set vpn ipsec interface 'eth1'
+```
+
+##### IPSec VPN Tunnels
+
+We'll use the IKE and ESP groups created above for this VPN. Because we
+need access to 2 different subnets on the far side, we will need two
+different tunnels. If you changed the names of the ESP group and IKE
+group in the previous step, make sure you use the correct names here
+too.
+
+```none
+set vpn ipsec authentication psk vyos id '203.0.113.46'
+set vpn ipsec authentication psk vyos id '198.51.100.243'
+set vpn ipsec authentication psk vyos secret 'MYSECRETPASSWORD'
+set vpn ipsec site-to-site peer branch authentication local-id '203.0.113.46'
+set vpn ipsec site-to-site peer branch authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer branch authentication remote-id '198.51.100.243'
+set vpn ipsec site-to-site peer branch connection-type 'initiate'
+set vpn ipsec site-to-site peer branch default-esp-group 'my-esp'
+set vpn ipsec site-to-site peer branch ike-group 'my-ike'
+set vpn ipsec site-to-site peer branch ikev2-reauth 'inherit'
+set vpn ipsec site-to-site peer branch local-address '203.0.113.46'
+set vpn ipsec site-to-site peer branch remote-address '198.51.100.243'
+set vpn ipsec site-to-site peer branch tunnel 0 local prefix '172.29.41.89/32'
+set vpn ipsec site-to-site peer branch tunnel 0 remote prefix '172.27.1.0/24'
+set vpn ipsec site-to-site peer branch tunnel 1 local prefix '172.29.41.89/32'
+set vpn ipsec site-to-site peer branch tunnel 1 remote prefix '10.125.0.0/16'
+```
+
+##### Testing and Validation
+
+If you've completed all the above steps you no doubt want to see if it's
+all working.
+
+Start by checking for IPSec SAs (Security Associations) with:
+
+```none
+$ show vpn ipsec sa
+
+Peer ID / IP Local ID / IP
+------------ -------------
+198.51.100.243 203.0.113.46
+
+ Tunnel State Bytes Out/In Encrypt Hash NAT-T A-Time L-Time Proto
+ ------ ----- ------------- ------- ---- ----- ------ ------ -----
+ 0 up 0.0/0.0 aes256 sha256 no 1647 3600 all
+ 1 up 0.0/0.0 aes256 sha256 no 865 3600 all
+```
+
+That looks good - we defined 2 tunnels and they're both up and running.
diff --git a/docs/configuration/nat/nat64.md b/docs/configuration/nat/nat64.md
new file mode 100644
index 00000000..c1b1c994
--- /dev/null
+++ b/docs/configuration/nat/nat64.md
@@ -0,0 +1,73 @@
+(nat64)=
+
+# NAT64
+
+{abbr}`NAT64 (IPv6-to-IPv4 Prefix Translation)` is a critical component in
+modern networking, facilitating communication between IPv6 and IPv4 networks.
+This documentation outlines the setup, configuration, and usage of the NAT64
+feature in your project. Whether you are transitioning to IPv6 or need to
+seamlessly connect IPv4 and IPv6 devices.
+NAT64 is a stateful translation mechanism that translates IPv6 addresses to
+IPv4 addresses and IPv4 addresses to IPv6 addresses. NAT64 is used to enable
+IPv6-only clients to contact IPv4 servers using unicast UDP, TCP, or ICMP.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat64)=
+
+#### SNAT64
+
+{abbr}`SNAT64 (IPv6-to-IPv4 Source Address Translation)` is a stateful
+translation mechanism that translates IPv6 addresses to IPv4 addresses.
+
+`64:ff9b::/96` is the well-known prefix for IPv4-embedded IPv6 addresses.
+The prefix is used to represent IPv4 addresses in an IPv6 address format.
+The IPv4 address is encoded in the low-order 32 bits of the IPv6 address.
+The high-order 32 bits are set to the well-known prefix 64:ff9b::/96.
+
+## Configuration Examples
+
+The following examples show how to configure NAT64 on a VyOS router.
+The 192.0.2.10 address is used as the IPv4 address for the translation pool.
+
+NAT64 server configuration:
+
+```none
+set interfaces ethernet eth0 address '192.0.2.1/24'
+set interfaces ethernet eth0 address '192.0.2.10/24'
+set interfaces ethernet eth0 description 'WAN'
+set interfaces ethernet eth1 address '2001:db8::1/64'
+set interfaces ethernet eth1 description 'LAN'
+
+set service dns forwarding allow-from '2001:db8::/64'
+set service dns forwarding dns64-prefix '64:ff9b::/96'
+set service dns forwarding listen-address '2001:db8::1'
+
+set nat64 source rule 100 source prefix '64:ff9b::/96'
+set nat64 source rule 100 translation pool 10 address '192.0.2.10'
+set nat64 source rule 100 translation pool 10 port '1-65535'
+```
+
+NAT64 client configuration:
+
+```none
+set interfaces ethernet eth1 address '2001:db8::2/64'
+set protocols static route6 64:ff9b::/96 next-hop 2001:db8::1
+set system name-server '2001:db8::1'
+```
+
+Test from the IPv6 only client:
+
+```none
+vyos@r1:~$ ping 64:ff9b::192.0.2.1 count 2
+PING 64:ff9b::192.0.2.1(64:ff9b::c000:201) 56 data bytes
+64 bytes from 64:ff9b::c000:201: icmp_seq=1 ttl=63 time=0.351 ms
+64 bytes from 64:ff9b::c000:201: icmp_seq=2 ttl=63 time=0.373 ms
+
+--- 64:ff9b::192.0.2.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1023ms
+rtt min/avg/max/mdev = 0.351/0.362/0.373/0.011 ms
+```
+
diff --git a/docs/configuration/nat/nat66.md b/docs/configuration/nat/nat66.md
new file mode 100644
index 00000000..1cbe3317
--- /dev/null
+++ b/docs/configuration/nat/nat66.md
@@ -0,0 +1,243 @@
+(nat66)=
+
+# NAT66(NPTv6)
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+{abbr}`NPTv6 (IPv6-to-IPv6 Network Prefix Translation)` is an address
+translation technology based on IPv6 networks, used to convert an IPv6
+address prefix in an IPv6 message into another IPv6 address prefix.
+We call this address translation method NAT66. Devices that support the NAT66
+function are called NAT66 devices, which can provide NAT66 source
+and destination address translation functions.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat66)=
+
+#### SNAT66
+
+{abbr}`SNPTv6 (Source IPv6-to-IPv6 Network Prefix Translation)` The conversion
+function is mainly used in the following scenarios:
+- A single internal network and external network. Use the NAT66 device to
+ connect a single internal network and public network, and the hosts in
+ the internal network use IPv6 address prefixes that only support
+ routing within the local range. When a host in the internal network
+ accesses the external network, the source IPv6 address prefix in
+ the message will be converted into a global unicast IPv6 address
+ prefix by the NAT66 device.
+- Redundancy and load sharing. There are multiple NAT66 devices at the edge
+ of an IPv6 network to another IPv6 network. The path through the NAT66
+ device to another IPv6 network forms an equivalent route, and traffic
+ can be load-shared on these NAT66 devices. In this case, you
+ can configure the same source address translation rules on these
+ NAT66 devices, so that any NAT66 device can handle IPv6 traffic between
+ different sites.
+- Multi-homed. In a multi-homed network environment, the NAT66 device
+ connects to an internal network and simultaneously connects to
+ different external networks. Address translation can be configured
+ on each external network side interface of the NAT66 device to
+ convert the same internal network address into different external
+ network addresses, and realize the mapping of the same internal
+ address to multiple external addresses.
+(destination-nat66)=
+
+#### DNAT66
+
+The {abbr}`DNPTv6 (Destination IPv6-to-IPv6 Network Prefix Translation)`
+destination address translation function is used in scenarios where the
+server in the internal network provides services to the external network,
+such as providing Web services or FTP services to the external network.
+By configuring the mapping relationship between the internal server
+address and the external network address on the external network
+side interface of the NAT66 device, external network users can
+access the internal network server through the designated
+external network address.
+
+### Prefix Conversion
+
+#### Source Prefix
+
+Every SNAT66 rule has a translation command defined. The prefix defined
+for the translation is the prefix used when the address information in
+a packet is replaced.、
+
+The {ref}`source-nat66` rule replaces the source address of the packet
+and calculates the converted address using the prefix specified in the rule.
+
+Example:
+- Convert the address prefix of a single `fc01::/64` network to `fc00::/64`
+- Output from `eth0` network interface
+
+```none
+set nat66 source rule 1 outbound-interface name 'eth0'
+set nat66 source rule 1 source prefix 'fc01::/64'
+set nat66 source rule 1 translation address 'fc00::/64'
+```
+
+
+#### Destination Prefix
+
+For the {ref}`destination-nat66` rule, the destination address of
+the packet isreplaced by the address calculated from the specified
+address or prefix in the `translation address` command
+
+Example:
+- Convert the address prefix of a single `fc00::/64` network
+ to `fc01::/64`
+- Input from `eth0` network interface
+
+```none
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 destination address 'fc00::/64'
+set nat66 destination rule 1 translation address 'fc01::/64'
+```
+
+For the destination, groups can also be used instead of an address.
+
+Example:
+
+```none
+set firewall group ipv6-address-group ADR-INSIDE-v6 address fc00::1
+
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 destination group address-group ADR-INSIDE-v6
+set nat66 destination rule 1 translation address 'fc01::/64'
+```
+
+
+## Configuration Examples
+
+Use the following topology to build a nat66 based isolated
+network between internal and external networks (dynamic prefix is
+not supported):
+
+:::{figure} /_static/images/vyos_1_4_nat66_simple.webp
+:alt: VyOS NAT66 Simple Configure
+:::
+
+R1:
+
+```none
+set interfaces ethernet eth0 ipv6 address autoconf
+set interfaces ethernet eth1 address 'fc01::1/64'
+set nat66 destination rule 1 destination address 'fc00:470:f1cd:101::/64'
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 translation address 'fc01::/64'
+set nat66 source rule 1 outbound-interface name 'eth0'
+set nat66 source rule 1 source prefix 'fc01::/64'
+set nat66 source rule 1 translation address 'fc00:470:f1cd:101::/64'
+```
+
+R2:
+
+```none
+set interfaces bridge br1 address 'fc01::2/64'
+set interfaces bridge br1 member interface eth0
+set interfaces bridge br1 member interface eth1
+set protocols static route6 ::/0 next-hop fc01::1
+set service router-advert interface br1 prefix ::/0
+```
+
+Use the following topology to translate internal user local addresses
+(`fc::/7`) to DHCPv6-PD provided prefixes from an ISP connected to
+a VyOS HA pair.
+
+:::{figure} /_static/images/vyos_1_5_nat66_dhcpv6_wdummy.webp
+:alt: VyOS NAT66 DHCPv6 using a dummy interface
+:::
+
+Configure both routers (a and b) for DHCPv6-PD via dummy interface:
+
+```none
+set interfaces dummy dum1 description 'DHCPv6-PD NPT dummy'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 0 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 1 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 2 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 3 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options rapid-commit
+commit
+```
+
+Get the DHCPv6-PD prefixes from both routers:
+
+```none
+trae@cr01a-vyos# run show interfaces dummy dum1 br
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+dum1 2001:db8:123:b008::/64 u/u DHCPv6-PD NPT dummy
+ 2001:db8:123:b00a::/64
+ 2001:db8:123:b00b::/64
+ 2001:db8:123:b009::/64
+
+trae@cr01b-vyos# run show int dummy dum1 brief
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+dum1 2001:db8:123:b00d::/64 u/u DHCPv6-PD NPT dummy
+ 2001:db8:123:b00c::/64
+ 2001:db8:123:b00e::/64
+ 2001:db8:123:b00f::/64
+```
+
+Configure the A-side router for NPTv6 using the prefixes above:
+
+```none
+set nat66 source rule 10 description 'NPT to VLAN 10'
+set nat66 source rule 10 outbound-interface name 'bond0.20'
+set nat66 source rule 10 source prefix 'fd52:d62e:8011:a::/64'
+set nat66 source rule 10 translation address '2001:db8:123:b008::/64'
+set nat66 source rule 20 description 'NPT to VLAN 70'
+set nat66 source rule 20 outbound-interface name 'bond0.20'
+set nat66 source rule 20 source prefix 'fd52:d62e:8011:46::/64'
+set nat66 source rule 20 translation address '2001:db8:123:b009::/64'
+set nat66 source rule 30 description 'NPT to VLAN 200'
+set nat66 source rule 30 outbound-interface name 'bond0.20'
+set nat66 source rule 30 source prefix 'fd52:d62e:8011:c8::/64'
+set nat66 source rule 30 translation address '2001:db8:123:b00a::/64'
+set nat66 source rule 40 description 'NPT to VLAN 240'
+set nat66 source rule 40 outbound-interface name 'bond0.20'
+set nat66 source rule 40 source prefix 'fd52:d62e:8011:f0::/64'
+set nat66 source rule 40 translation address '2001:db8:123:b00b::/64'
+commit
+```
+
+Configure the B-side router for NPTv6 using the prefixes above:
+
+```none
+set nat66 source rule 10 description 'NPT to VLAN 10'
+set nat66 source rule 10 outbound-interface name 'bond0.20'
+set nat66 source rule 10 source prefix 'fd52:d62e:8011:a::/64'
+set nat66 source rule 10 translation address '2001:db8:123:b00c::/64'
+set nat66 source rule 20 description 'NPT to VLAN 70'
+set nat66 source rule 20 outbound-interface name 'bond0.20'
+set nat66 source rule 20 source prefix 'fd52:d62e:8011:46::/64'
+set nat66 source rule 20 translation address '2001:db8:123:b00d::/64'
+set nat66 source rule 30 description 'NPT to VLAN 200'
+set nat66 source rule 30 outbound-interface name 'bond0.20'
+set nat66 source rule 30 source prefix 'fd52:d62e:8011:c8::/64'
+set nat66 source rule 30 translation address '2001:db8:123:b00e::/64'
+set nat66 source rule 40 description 'NPT to VLAN 240'
+set nat66 source rule 40 outbound-interface name 'bond0.20'
+set nat66 source rule 40 source prefix 'fd52:d62e:8011:f0::/64'
+set nat66 source rule 40 translation address '2001:db8:123:b00f::/64'
+commit
+```
+
+Verify that connections are hitting the rule on both sides:
+
+```none
+trae@cr01a-vyos# run show nat66 source statistics
+Rule Packets Bytes Interface
+------ --------- ------- -----------
+10 1 104 bond0.20
+20 1 104 bond0.20
+30 8093 669445 bond0.20
+40 2446 216912 bond0.20
+```