Score:1

Why does everybody use MASQUERADE/SNAT instead of NAPT/PAT?

in flag

Story

I have a VPN wireguard virtual interface wg0 (can be anything else) and a physical interface eth0. I want to route packets from the VPN to my LAN, or from an interface to another interface.

Almost all the blogs, articles, tutorials advice using MASQUERADE or Source NAT only: iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Moreover, IP masquerade is simply a SNAT (Source NAT), it doesn't change the source port.

Question

  • Am I wrong thinking I should use a NAPT/PAT instead?
  • For completeness, how can I add a NAPT/PAT rule with iptables and/or nftables?

Thoughts

There might be (source port) conflicts between packets generated by the host and forwarded from wg0 (or any other virtual/physical interfaces). IMHO NAPT must be used to avoid these conflicts.

RFC 2663, Network Address Port Translation (NAPT)

Score:6
gr flag

If the destination can route its traffic to the source, no NAT or PAT is required.

As an example, no NAT/PAT is required if the VPN clients in 10.8.0.0/24 want to talk with your LAN devices in 192.168.1.0/24, as long as the involved devices can route to the other network (through their gateway).

When the source is in a rfc1918 (private IP) network and the destination is a public IP, because rfc1918 networks are not routable over Internet, a NAT is required to replace the private IP by the public IP. This is source address translation. This job can be done by a SNAT, not a PAT.

Furthermore, you are wrong assuming SNAT/MASQUERADE does not change source ports.

The --to-source option is used to specify which source the packet should use. This option, at its simplest, takes one IP address which we want to use for the source IP address in the IP header. If we want to balance between several IP addresses, we can use a range of IP addresses, separated by a hyphen. The --to--source IP numbers could then, for instance, be something like in the above example: 194.236.50.155-194.236.50.160. The source IP for each stream that we open would then be allocated randomly from these, and a single stream would always use the same IP address for all packets within that stream. We can also specify a range of ports to be used by SNAT. All the source ports would then be confined to the ports specified. The port bit of the rule would then look like in the example above, :1024-32000. This is only valid if -p tcp or -p udp was specified somewhere in the match of the rule in question. iptables will always try to avoid making any port alterations if possible, but if two hosts try to use the same ports, iptables will map one of them to another port. If no port range is specified, then if they're needed, all source ports below 512 will be mapped to other ports below 512. Those between source ports 512 and 1023 will be mapped to ports below 1024. All other ports will be mapped to 1024 or above. As previously stated, iptables will always try to maintain the source ports used by the actual workstation making the connection. Note that this has nothing to do with destination ports, so if a client tries to make contact with an HTTP server outside the firewall, it will not be mapped to the FTP control port.

https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#SNATTARGET

Note that if you device want to reach a remote server on a given destination port, there are chances that the operating system already assigned a random source port over 1024. Reaching a remote HTTPS server on port 443, does not involve that the source port is 443.

Alexis avatar
in flag
Without adding static routes in the gateway or all the local network nodes, they won't be able to route back the packets to the VPN subnet. A NAT/NAPT is required.
Alexis avatar
in flag
I don't agree with `This job can be done by a SNAT, not a PAT`, a NAPT is necessary if there are more than one computer using the same public IP.
Alexis avatar
in flag
Thanks for the link, it isn't official iptables' doc and that's my problem. If it really behaves like that for a NAT rule, it's against the rfc. I wouldn't want iptables to do what I didn't ask (altering layer 4). Do you have any **official doc** stating the same? netfilter, iptables or nftables? Also, don't mix the term SNAT that describes a concept with the name of a target in iptables. Per its definition `SNAT/MASQUERADE` does **NOT** change the layer 4. If `iptables` allows to do PAT/NAPT on its so-called SNAT target, that's different.
gr flag
Yes, PAT is necessary but this task is handled by iptables' SNAT target (or MASQUERADE, which is basically SNAT). This is why iptables' SNAT (or MASQUERADE) is enough, you do not have to explicitly do PAT. SNAT does port translation, as stated by the non official documentation, but confirmed by netfilter's official documentation. See section " 6.3.4. Implicit Source Port Mapping". https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.txt
Alexis avatar
in flag
Thanks. Good catch, I'll consider it's still valid for kernels>2.4. `SNAT/MASQUERADE` shouldn't do port translation implicitly. I believe it's more a netfilter's decision to combine both. (as specified in rfc2663) I wish this could have been explained or detailed somewhere. I'll stay careful with other systems.
ilkkachu avatar
us flag
@Alexis, TBH, you're being a bit silly. The [`iptables` man page](https://man7.org/linux/man-pages/man8/iptables-extensions.8.html) says `SNAT` does port translation, and that `MASQUERADE` is similar. And the RFC you linked to doesn't even mention either of those two terms. So, it's documented to do what it does, and the RFC doesn't even use the same terms, so it's not even an overloaded meaning. No problem there. If you want just address translation, then you'll have to use some other functionality. `NETMAP` looks like it could be one, but I haven't used it.
Alexis avatar
in flag
@ilkkachu keep the silly for you, I'm not your friend. The manpage you linked doesn't indicate it does automatic port translation for `SNAT` nor `MASQUERADE`, only options we can interpret as **optional** indicating a feature that is **mainly/99%** used for explicit **port forwarding**.
ilkkachu avatar
us flag
@Alexis, it doesn't? For SNAT: "--to-source [...] If no port range is specified, then source ports below 512 will be mapped to other ports below 512: those between 512 and 1023 inclusive will be mapped to ports below 1024, and other ports will be mapped to 1024 or above. Where possible, no port alteration will occur." for MASQUERADE: "--to-ports port[-port] This specifies a range of source ports to use, overriding the default SNAT source port-selection heuristics (see above)."
ilkkachu avatar
us flag
@Alexis, and I never said you were that. Just that you seem to be having some expectations that simply don't apply, and that the RFC you refer to doesn't even support you in the naming question. The Linux guys get to name their stuff whatever they like, and after years and years of it being like it is, they're not likely to change it. So, basically, you get to choose if you want to fight against the windmills (which, IMO, is a bit silly), or accept it as it is. If you think the documentation isn't clear enough, you could of course send them a bug report to clarify that?
Score:6
za flag

You have somehow the wrong distinction between SNAT/MASQUERADE and NAPT/PAT. It is not there.

In Linux, there are two types of dynamic NAT rules, both of which you call "NAPT":

  • source NAT, which intends to leave destination address intact and only changes the source address. Sometimes it will also change the source port. For example, if the connection tracking table already contains the record with this particular (proto, src-addr, src-port, dst-addr, dst-port) tuple (src-addr and src-port are after translation), to be able to make a distinction which is which, the new translation must use another src-port (because this is the only degree of freedom), so the "NAPT" will inevitable take place. The examples of SNAT-type rules are SNAT and MASQUERADE. The difference between them is that with SNAT you are required to specify in the rule which address to translate into (and, probably, which range of ports to use), while with the MASQUERADE it makes the choice itself, based on which interface the packet is destined to egress. Both of them are to be installed into POSTROUTING chain, after most other processing was taken place, including the routing of the packet. This type of rule is used to allow many computers to be hidden behind the single exit IP address, e.g. to access the Internet for the LAN and so on. This would include any VPN users too, if you intend to access Internet via VPN.
  • destination NAT, which leaves the source address as it was and only updates the destination address, and, if you configured that, the destination port, so this is "NAPT" rule too. Rules of this type are DNAT, REDIRECT, CLUSTERIP and probably some other, I don't remember them all; these are installed into PREROUTING chain, because the routing decision usually should be changed under the influence of the rule. The packet which originally destined to the machine itself (has its address as a destination) and was to be traversed INPUT and reached some local process, is being translated instead and, after traversing FORWARD chain it is being forwarded further to some other system. Or vice versa. Where to go, INPUT or FORWARD, is the routing decision which we must change with the rule. This type of the rule is used to make access to some internal system from the Internet.

Sometimes, by the way, both rules might be used for the single packet (and connection). This is the special case, but useful if you need packets from some external system (so DNAT must be used in the PREROUTING) to appear as coming from some internal address (for which SNAT is used in POSTROUTING).

In Linux there is also the static NAT-type rules like NETMAP which is quite special and seldom used. I doubt you are talking about it and that you have seen any howtos which mention this type of the rule.

Linux makes absolutely no distinction between private (RFC1918) and public addresses. You can NAT your public subnet if you want to (but this will be a waste of addresses). You can leave private IPs without translation (but usually this will lead to no Internet connectivity for them).

The VPN is nothing more than additional network interface in the machine and should be treated as such. Consequently, you are allowed to use public addresses for VPN, if you have them. For example, I may have some /29 subnet routed to by VPN router and set up OpenVPN so this whole public subnet will be my VPN network! While OpenVPN example looks artificial, the WireGuard is much more likely to be configured like that. For instance, the new namespace solution allows the wireguard to be the only interface in the system. If there is a requirement for the system to directly have a public IP (I won't discuss any reasons for which this requirement might come from), it's inevitable you'll end up using public IPs inside the VPN! Most probably, without any NAT for them.

Alexis avatar
in flag
Thanks for your long answer. NAT and NAPT have definitions, I don't interpret them wrong. I never talked about public/private IPs. I didn't tag wireguard because as you said it doesn't matter what controls the interface. An acceptable answer is telling me that netfilter's **source NAT** is actually doing **NAPT/PAT** at the same time. That's all what I missed, I thought we had to explicitly tell netfilter we want **also** port translation in combination with simple NAT.
Nikita Kipriyanov avatar
za flag
Why do you think the definition you encounter is correct, or that there couldn't be another definition? NAT could be defined so it includes port translation too, and *that* definition is used in Linux, and not only in Linux. Actually the "strict" version is quite unpractical, because the prevalent use of NAT nowadays is to allow many machines to access Internet using a single public IP address, and this *requires* the port translation too for the reason I mentioned in my answer. So for practical purposes it is wiser to take a definition of NAT which *includes* port translation.
Alexis avatar
in flag
**rfc2663**:`Network Address Translation is a method by which **IP addresses** are mapped from one address realm to another, providing transparent routing to end hosts.` I just read the definition and it doesn't include NAPT. Nevertheless, you're right for practical purpose, it's wiser for all the docs/people mentioning NAT to also explicitly include PAT in their definition.
Alexis avatar
in flag
In fact, per definition, Linux and all are wrong and they all should use NAPT instead of NAT... in a world where people use the correct terms.
Nikita Kipriyanov avatar
za flag
It's not you or RFC who defines the correct vocabulary. The language is a living beast upon which we seem to have absolutely no control ;) The only thing valid here is a public consensus.
Alexis avatar
in flag
Agree, in that case it must be documented or mentioned more widely. Very rare are the mentions of port translation in conjunction with NAT doc/blog/tutorials/whatever page. Hence my question.
TooTea avatar
in flag
@Alexis "NAT" is just the standard generic industry term for any kind of network and port translation. Unless you're writing an RFC, you don't need to make an explicit distinction between NAT, NAPT and PAT. (You'll also see people talk about "full cone NAT" and "symmetric NAT" and the like.)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.