I’m beginning to learn about nat and I was wondering why does NAT translate a source port? Doesn’t a port represent an application that’s requesting a service? So why must it be translated? Also what would happen if NAT hypothetically didn’t translate the source port and two separate machines on the same network sent out a message but had the same source port? Would anything bad happen?
Nat – Why does NAT translate a source port
layer4nat;
Related Solutions
This doesn't really answer my question why did NAT always use the 80th port as source port for outgoing traffic, but at least I figured out how to fix the problem.
I created an access list to match traffic from the mail server and also created a pool of one public address for it.
ip access-list extended 109
!!! Restrict NAT for branch office destinations
deny ip host 192.168.7.7. 192.168.0.0 0.0.255.255
permit ip host 192.168.7.7 any
ip nat pool MAIL 198.51.100.7 198.51.100.7 prefix-length 27
ip nat inside source list 109 pool MAIL
And...Voilà! It now preserves the source port number as it sends traffic. And our mail is no longer blocked by some external MTA mail servers.
Update:
So now I tried reverting back to:
ip nat source static 192.168.7.7 198.51.100.7 route-map Deny_On_VPN
And it actually started to translate addresses and ports as expected - one to one. I don't really understand what the deal was with it, maybe a bug? Hopefully it will keep running like this from now on. I guess, I'll have a look at IOS release notes
To test your scenario I set up the following lab:
The 10.0.0.0/24 network is your -RangeOfIPs-
When traffic comes from 10.0.0.0/24
it will be NATed to 192.168.0.21
.
Traffic sourcing from 192.168.0.114
will be NATed to 10.1.1.21
.
Configuration:
R3(config)#int f0/0
R3(config-if)#ip nat outside
R3(config-if)#int f0/1
R3(config-if)#ip nat inside
The above commands define the interfaces as outside
and inside
.
R3(config)#ip nat inside source static 192.168.0.114 10.1.1.21
This command translates the inside local
address of 192.168.0.114
to an inside global
address of 10.1.1.21
.
R3(config)#access-list 1 permit 10.0.0.0 0.0.0.255
This access-list will define which hosts on the outside
that will get NATed.
R3(config)#ip nat pool NAT_POOL 192.168.0.21 192.168.0.21 netmask 255.255.255.0
We create a NAT pool consisting of a single address.
R3(config)#ip nat outside source list 1 pool NAT_POOL add-route
Then we configure so that hosts matching access-list 1
will get NATed to 192.168.0.21
.
It is important to configure add-route here or to add a static route because when doing inside to outside
NAT, NAT takes place before routing in the order of operations. That means that R3 must have a route for 10.1.1.21.
R3 now has the following NAT table:
R3#show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- --- --- 192.168.0.21 10.0.0.1
--- 10.1.1.21 192.168.0.114 --- ---
Note that R4 has configured with an IP and ip routing
turned off to emulate a host. Debugging of ICMP on R1 is enabled and debugging of ip nat on R3 is also enabled.
R1#debug ip icmp
ICMP packet debugging is on
R3#debug ip nat
IP NAT debugging is on
A ping is then issued from R1:
R1#ping 10.1.1.21 so f0/1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.1.21, timeout is 2 seconds:
Packet sent with a source address of 10.0.0.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 80/86/104 ms
R1#
ICMP: echo reply rcvd, src 10.1.1.21, dst 10.0.0.1
ICMP: echo reply rcvd, src 10.1.1.21, dst 10.0.0.1
ICMP: echo reply rcvd, src 10.1.1.21, dst 10.0.0.1
ICMP: echo reply rcvd, src 10.1.1.21, dst 10.0.0.1
ICMP: echo reply rcvd, src 10.1.1.21, dst 10.0.0.1
Debug and NAT table from R3:
NAT*: s=10.0.0.1->192.168.0.21, d=10.1.1.21 [15]
NAT*: s=192.168.0.21, d=10.1.1.21->192.168.0.114 [15
NAT: s=192.168.0.114->10.1.1.21, d=192.168.0.21 [15]
NAT: s=10.1.1.21, d=192.168.0.21->10.0.0.1 [15]
R3#show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- --- --- 192.168.0.21 10.0.0.1
icmp 10.1.1.21:3 192.168.0.114:3 192.168.0.21:3 10.0.0.1:3
--- 10.1.1.21 192.168.0.114 --- ---
I think that this is the kind of configuration you are looking for.
However, note that there is a caveat because there is no overload (PAT)
available for outside to inside
translation. That means that as soon as one of your hosts communicate with 192.168.0.114
, there will be no free IP's in the pool. What you can do is to increase the pool size
so that you reserve maybe 10 IP's that are only used for NAT
.
Best Answer
First, I'm assuming you're focused on TCP. UDP has some differences, and I'm not as up-to-speed on that part.
You're right to ask this question, and to be frank, it doesn't always need to. However, sometimes that translation IS required. Given that it is sometimes required, and given that the NAT system therefore needs to track source port for some traffic, and because there are efficiencies in doing something the same way every time, most NAT implementations don't make an effort to re-use the original source-port on the NATted connection.
Many (most?) protocols don't depend on the source port for TCP connections, so that's the simplest approach, and it rarely hurts.
It does, but generally the source port is not specified by the application. Instead it is assigned (somewhat) randomly. This is actually good, because before that was true it was way too easy to break existing connections by predicting the source port number (the "unreach" attack using ICMP DESTINATION UNREACHABLE packets).
The answer to your first question is in the answer to the second, so I'll take a stab at the second, and you share if it doesn't answer the first.
First, assume your NAT host only has one IP address (N) to translate to. Second, assume you actually have an extra coincidence where internal hosts A and B both try to communicate with external host X on port 80 with source port 17835.
After NAT, assuming no translation of source port:
Oops. They look the same. They particularly look the same to the remote host X. It is most likely to drop the packets associated with the second connection attempt because the sequence numbers are going to be wrong.
You also have a problem on the NAT host, as it can't tell the difference between the two either. It can only maintain one "connection" record with remote host X on port 80 per source port. It has to keep this record so it knows which internal host to translate back to when it receives an inbound packet. If the record corresponds to the first host to connect, then you would have the experience where A (the first host) has no problems, and B cannot connect.
If, more entertainingly, B's record in the NAT overwrites A's after the connection is built for A, then the NAT system will never forward X's responses to A (it only has B's record), and X will never respond to B (wrong sequence numbers / connection state) and nobody wins (communicates).
Let's be honest. NAT is a hack. It is an ugly hack, and we are either lucky it works (because we haven't rolled out IPv6 universally yet) or victims of its success (because it works well enough, people don't insist on IPv6 support).