What is this post about?
We are planning to make a minor change to the way our VPNs NAT clients. For those who are interested, this blog post explains why and how we are doing this. Please note that these days NAT is used as a general term encompassing both NAT (Network Address Translation) and PAT (Port Address Translation). I’ll be specific in this post.
Problem summary
The original VPN config didn’t use NAT or PAT and had a client pool of 129.67.116.0/22
, which was advertised to the various departmental and collegiate IT staff working at Oxford University. This pool became exhausted but we don’t want to be seen to be favouring our own services by taking whatever IPs we would like. Also there are lots of local firewalls around the University which are aware of this range so we migrated to PAT, taking 2 IPs from the above range per ASA.
At the time of writing (Jan 2012), the ASA VPNs are configured as follows, where X and Y are two adjacent IPs and are unique to each ASA:
object network nat_inside_local subnet 10.16.0.0 255.255.240.0 object network nat_outside_pool range 129.67.119.24X 129.67.119.24Y nat (vpn-outside,vpn-inside) \ source dynamic nat_inside_local pat-pool nat_outside_pool
This means that hosts in 10.16.0.0/20 whose traffic hits the vpn-outside interface and is destined for the vpn-inside interface, will be PATed onto 129.67.119.24X. When all 65K ports have been used up, .24Y will be used. The issue we are having is that IP/Port combinations are being re-used too quickly for our CERT team to be certain (ha ha) of who is being naughty.
Solution
To get around this we will move to using Dynamic NAT with a generous range of IPs, falling back to a PAT IP if they are exhausted. We need to take care when choosing the pools though as some IPs are reserved for existing VPN infrastructure. As such the allocation of the pools will asymetrical as to me this seems cleaner than giving 9 hosts from .117 to node 1.
- node0 will have
129.67.116.1 - 129.67.117.255
- node1 will have
129.67.118.0 - 129.67.119.235
The /22 contains a few addresses which will look odd. Namely 116.255, 117.[0|255], 118.[0|255], 119.0 are all legitimate. We will waste 118.0 as it means both PAT addresses will be silimar which should make life a bit easier.
116.0 and 119.255 are the only network and broadcast addresses.
The final config will be as follows. I’ve renamed the groups to simplify migration and hopefully make it very clear what is going on.
vpn-0
object network D-NAT-RANGE range 129.67.116.2 129.67.117.255 object network PAT-HOST host 129.67.116.1 object network INSIDE-POOL subnet 10.16.0.0 255.255.240.0 object-group network OUTSIDE-POOL network-object object D-NAT-RANGE network-object object PAT-HOST nat (vpn-outside,vpn-inside) \ source dynamic INSIDE-POOL OUTSIDE-POOL
vpn-1
object network D-NAT-RANGE range 129.67.118.2 129.67.119.235 object network PAT-HOST host 129.67.118.1 object network INSIDE-POOL subnet 10.16.16.0 255.255.240.0 object-group network OUTSIDE-POOL network-object object D-NAT-RANGE network-object object PAT-HOST nat (vpn-outside,vpn-inside) source dynamic INSIDE-POOL OUTSIDE-POOL
All three objects are unique on each host.
Staging tests
I used our lab to mimic the production environment. We tested with four clients so needed to artifically shrink the Dynamic NAT range to 2 IPs so that PAT would be triggered and we could verify it worked. We used only one ASA for the same reason, here is the config:
object network D-NAT-RANGE range 192.168.30.12 192.168.30.13 object network PAT-HOST host 192.168.30.31 object network INSIDE-POOL subnet 10.0.0.0 255.255.255.0 object-group network OUTSIDE-POOL network-object object D-NAT-RANGE network-object object PAT-HOST nat (vpn-outside,vpn-inside) source dynamic INSIDE-POOL OUTSIDE-POOL
Verification
The first two hosts to connect were NATed to 192.168.30.12 and .13 respectivly. The remaining two hosts use PAT on .31. All hosts were able to reach the appropriate fake external networks hosted on an area of the lab only reachable from the VPN pool.
With three laptops connected we see the first two use 1-1 dynamic NAT and the third uses PAT:
vpn-dev-0# show xlate 4 in use, 7 most used Flags: D - DNS, i - dynamic, r - portmap, s - static, I - identity, T - twice NAT from vpn-outside:10.0.0.1 to vpn-inside:192.168.30.12 \ flags i idle 0:00:09 timeout 3:00:00 NAT from vpn-outside:10.0.0.2 to vpn-inside:192.168.30.13 \ flags i idle 0:00:17 timeout 3:00:00 TCP PAT from vpn-outside:10.0.0.3/53013 to vpn-inside:192.168.30.31/42959 \ flags ri idle 0:00:00 timeout 0:00:30 TCP PAT from vpn-outside:10.0.0.3/53012 to vpn-inside:192.168.30.31/20628 \ flags ri idle 0:00:01 timeout 0:00:30
Now with four laptops connected the additional client also used PAT:
vpn-dev-0# show xlate 36 in use, 36 most used Flags: D - DNS, i - dynamic, r - portmap, s - static, I - identity, T - twice <snip> UDP PAT from vpn-outside:10.0.0.4/52004 to vpn-inside:192.168.30.31/60697 \ flags ri idle 0:00:45 timeout 0:00:30 UDP PAT from vpn-outside:10.0.0.4/137 to vpn-inside:192.168.30.31/252 \ flags ri idle 0:01:25 timeout 0:00:30 NAT from vpn-outside:10.0.0.1 to vpn-inside:192.168.30.12 \ flags i idle 0:00:00 timeout 3:00:00 NAT from vpn-outside:10.0.0.2 to vpn-inside:192.168.30.13 \ flags i idle 0:00:10 timeout 3:00:00 ICMP PAT from vpn-outside:10.0.0.3/51467 to vpn-inside:192.168.30.31/26251 \ flags ri idle 0:01:51 timeout 0:00:30
Our policy is in use:
vpn-dev-0# show nat Manual NAT Policies (Section 1) 1 (vpn-outside) to (vpn-inside) \ source dynamic INSIDE-POOL OUTSIDE-POOL translate_hits = 59, untranslate_hits = 126
Sumary
We plan to make this change live during our next maintenance release.