Terminating a GRE/IPSEC tunnel behind NAT

Suppose I need to (for whatever reason ;)) site-to-site VPN but also need to terminate the GRE/IPSEC tunnel on a device which is behind a NAT. The following diagram illustrates the scenario:

GRE over IPSEC, terminating both behind NAT
GRE/IPSEC terminating behind NAT

We need to have an IPSEC SA between RLeft and RRight and we need to have a GRE VTI between RLeft and RRight, running over this SA. The SA will secure and encapsulate the GRE traffic.

Some initial notes

If we want RRight to be behind NAT, there are some challenges to the normal GRE/IPSEC operation. The source address of the packets coming from RRight is changed to the public IP that NATRouter assigns it after it does the address translation. Being completely unaware of any NATs in the way, RLeft would only see packets coming from the NAT public IP 172.16.20.3 and not from the actual interface of RRight. This means RRight will have to authenticate as 172.16.20.3, so we need to bring up a loopback on RRight holding this IP address. This is why this could not work with NAT interface overloading on NATRouter, as in that case the IP of the loopback on RRight would be the same as the IP address of the fa0/0 interface on NATRouter, and there would be issues with routing the packets back to RRight.

NAT traversal

A note worh mentioning is that the NAT-transparency feature, also known in some sources as “UDP wrapper” or “UDP encapsulation” is enabled by default since 12.2(13)T. This feature allows the IPSEC endpoints to detect whether a NAT is present somewhere along the way, by exchanging hashes of the source and destination IP address and port at each end of the IPSEC SA. By recalculating the hashes locally and then comparing the values, the endpoints can detect whether a NAT is present along the way or not. Then, if both endpoints support NAT-T (which in our case they do), they will negotiate whteher to use NAT-T. The final (and most important) step is to encapsulate every IPSEC SA and ISAKMP packet within a new UDP header. IPSEC NAT-T uses UDP port 4500.

Configurations

First, the configuration on RLeft:

!
crypto isakmp policy 1
encr 3des
hash md5
authentication pre-share
lifetime 3600
crypto isakmp key cryptopass address 172.16.20.3
!
!
crypto ipsec transform-set MYSET esp-3des esp-md5-hmac
!
crypto map CRYPTOMAP1 1 ipsec-isakmp
set peer 172.16.20.3
set transform-set MYSET
match address CRYPTO_ACL

First we define an ISAKMP policy and a pre-shared key for authentication. We go on defining a transform-set, using esp-3des for encryption and esp-md5-hmac for authentication. On a side note, NAT-T would not work with AH transform-sets, because AH includes the source and destination IP address fields from the original IP header in its Integrity Check hash computation and therefore relies on an unchanging IP address. Then we define a crypto map to put it all together – the IKE policy, the remote peer, and the transform-set. The ACL used in the crypto map specifiies the traffic to protect, i.e. the interesting traffic that will trigger the Security Association. This is specified as only GRE traffic between the tunnel source and the tunnel destination of the GRE VTI. What remains to be seen below is the ACL itself, the GRE tunnel interface configuration, and the outgoing interface where we apply the crypto map.

!
interface Tunnel1
ip address 192.168.3.1 255.255.255.252
keepalive 5 3
tunnel source 172.16.10.1
tunnel destination 172.16.20.3
!
interface FastEthernet0/0
description IC to ICRouter f0/0
ip address 172.16.10.1 255.255.255.252
speed 100
full-duplex
crypto map CRYPTOMAP1
!

Of course we have to know how to reach the remote endpoint, indeed we only need a default route pointing to ICRouter:

ip route 0.0.0.0 0.0.0.0 172.16.10.2
!

And the ACL defining the interesting traffic:

!
ip access-list extended CRYPTO_ACL
permit gre host 172.16.10.1 host 172.16.20.3
deny   ip any any
!

Thats about it for RLeft. The complete configuration can be found in the “Configuration files” section at the end of this post.

ICRouter’s purpose in this scenario is just to provide interconnection, so the only thing we have really done on it, is to configure the two interfaces, connecting to Rleft and NATRouter.

NATRouter’s configuration is quite simple:

!
interface FastEthernet0/0
description IC to ICRouter f0/1
ip address 172.16.20.2 255.255.255.248
ip nat outside
ip virtual-reassembly
speed 100
full-duplex
!
interface FastEthernet0/1
description IC to RRight f0/0
ip address 192.168.4.1 255.255.255.252
ip nat inside
ip virtual-reassembly
speed 100
full-duplex
!

We define the outside and inside interfaces for the address translation above. The actual NAT configuration is done with a pool of just one IP:

ip nat pool NAT_POOL 172.16.20.3 172.16.20.3 prefix-length 29
ip nat inside source list NAT_ACL pool NAT_POOL overload
!
ip access-list standard NAT_ACL
permit 192.168.4.0 0.0.0.3
permit 192.168.2.0 0.0.0.255
deny   any
!

We could have had the same effect by specifying a static mapping for RRight’s fa0/0 interface – 192.168.4.2, to the public IP used for the address translation – 172.16.20.3 (ip nat source static 192.168.4.2 172.16.20.3). The only interesting thing in this configuration is that we cannot use this with interface overloading. If we use the actual outside interface (fa0/0) on NATRouter for the address translation, we will need to terminate the tunnel on the NATRouter itself, as we would not be able to route to the same IP address on RRight Loopback, and we would not be able to hold the tunnel there. Of course, in case we have chosen this solution with a loopback.

And now, RRight:

All the crypto parameters must match the configuration on RLeft, with a reversed peer address.

!
crypto isakmp policy 1
encr 3des
hash md5
authentication pre-share
lifetime 3600
crypto isakmp key cryptopass address 172.16.10.1
!
!
crypto ipsec transform-set MYSET esp-3des esp-md5-hmac
!
crypto map CRYPTOMAP1 1 ipsec-isakmp
set peer 172.16.10.1
set transform-set MYSET
match address CRYPTO_ACL
!

The interesting point here is that we bring up a loopback with the same IP address as the public IP address for the NAT translation. This loopback will hold our GRE tunnel interface as a tunnel source.

!
interface Loopback1
description Tunnel termination
ip address 172.16.20.3 255.255.255.255
!
interface Tunnel1
ip address 192.168.3.2 255.255.255.252
keepalive 5 3
tunnel source 172.16.20.3
tunnel destination 172.16.10.1
!

And then, the crypto map is applied on the outbound interface of RRight, fa0/0, connecting to NATRouter, and having the IP address of 192.168.4.2.

!
interface FastEthernet0/0
description IC to NATRouter f0/1
ip address 192.168.4.2 255.255.255.252
speed 100
full-duplex
crypto map CRYPTOMAP1
!

We define a static default route, pointing to NATRouter.

ip route 0.0.0.0 0.0.0.0 192.168.4.1
!

The ACL identifying the interesting traffic for the crypto is identical to the ACL on RLeft, but reversed – only GRE traffic between RRight’s loopback0 interface and the fa0/0 IP address of RLeft.

!
ip access-list extended CRYPTO_ACL
permit gre host 172.16.20.3 host 172.16.10.1
deny   ip any any
!

This is about all we need. After this is all done, the tunnel should come up, and so should the crypto SA. We can examine the crypto sa information on both ends.

Verifying the configuration

on RLeft:

RLeft#show crypto isakmp sa detail
Codes: C - IKE configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal
X - IKE Extended Authentication
psk - Preshared key, rsig - RSA signature
renc - RSA encryption
IPv4 Crypto ISAKMP SA

C-id  Local           Remote          I-VRF    Status Encr Hash Auth DH Lifetime Cap.

1001  172.16.10.1     172.16.20.3              ACTIVE 3des md5  psk  1  00:12:39 N
Engine-id:Conn-id =  SW:1

IPv6 Crypto ISAKMP SA

RLeft#

We can see from this that the remote endpoint supports NAT-Transparency in the “Cap.” column (Capabilities).

We can also have a look at the IPSEC SA:

RLeft#show crypto ipsec sa

interface: FastEthernet0/0
Crypto map tag: CRYPTOMAP1, local addr 172.16.10.1

protected vrf: (none)
local  ident (addr/mask/prot/port): (172.16.10.1/255.255.255.255/47/0)
remote ident (addr/mask/prot/port): (172.16.20.3/255.255.255.255/47/0)
current_peer 172.16.20.3 port 4500
PERMIT, flags={origin_is_acl,}
#pkts encaps: 1780, #pkts encrypt: 1780, #pkts digest: 1780
#pkts decaps: 1777, #pkts decrypt: 1777, #pkts verify: 1777
#pkts compressed: 0, #pkts decompressed: 0
#pkts not compressed: 0, #pkts compr. failed: 0
#pkts not decompressed: 0, #pkts decompress failed: 0
#send errors 19, #recv errors 0

local crypto endpt.: 172.16.10.1, remote crypto endpt.: 172.16.20.3
path mtu 1500, ip mtu 1500, ip mtu idb FastEthernet0/0
current outbound spi: 0xF8743C7E(4168367230)

inbound esp sas:
spi: 0x724AD016(1917505558)
transform: esp-3des esp-md5-hmac ,
in use settings ={Tunnel UDP-Encaps, }
conn id: 1, flow_id: SW:1, crypto map: CRYPTOMAP1
sa timing: remaining key lifetime (k/sec): (4596301/715)
IV size: 8 bytes
replay detection support: Y
Status: ACTIVE

inbound ah sas:

inbound pcp sas:

outbound esp sas:
spi: 0xF8743C7E(4168367230)
transform: esp-3des esp-md5-hmac ,
in use settings ={Tunnel UDP-Encaps, }
conn id: 2, flow_id: SW:2, crypto map: CRYPTOMAP1
sa timing: remaining key lifetime (k/sec): (4596298/714)
IV size: 8 bytes
replay detection support: Y
Status: ACTIVE

outbound ah sas:

outbound pcp sas:
RLeft#

And also the crypto session details:

RLeft#show crypto session detail
Crypto session current status

Code: C - IKE Configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal, X - IKE Extended Authentication

Interface: FastEthernet0/0
Session status: DOWN
Peer: 172.16.20.3 port 500 fvrf: (none) ivrf: (none)
Desc: (none)
Phase1_id: (none)
IPSEC FLOW: deny ip 0.0.0.0/0.0.0.0 0.0.0.0/0.0.0.0
Active SAs: 0, origin: crypto map
Inbound:  #pkts dec'ed 0 drop 0 life (KB/Sec) 0/0
Outbound: #pkts enc'ed 0 drop 0 life (KB/Sec) 0/0

Interface: FastEthernet0/0
Uptime: 00:48:31
Session status: UP-ACTIVE
Peer: 172.16.20.3 port 4500 fvrf: (none) ivrf: (none)
Phase1_id: 192.168.4.2
Desc: (none)
IKE SA: local 172.16.10.1/4500 remote 172.16.20.3/4500 Active
Capabilities:N connid:1001 lifetime:00:11:17
IPSEC FLOW: permit 47 host 172.16.10.1 host 172.16.20.3
Active SAs: 2, origin: crypto map
Inbound:  #pkts dec'ed 1795 drop 0 life (KB/Sec) 4596299/688
Outbound: #pkts enc'ed 1797 drop 19 life (KB/Sec) 4596296/688

RLeft#

Here, we can see the IKE Phase 1 ID of the remote peer was indeed its private IP address. We can also see that the connection to the peer is established using NAT traversal, as we see the port used is 4500.

Below, the same information is gathered from RRight:

RRight#show crypto isakmp sa detail
Codes: C - IKE configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal
X - IKE Extended Authentication
psk - Preshared key, rsig - RSA signature
renc - RSA encryption
IPv4 Crypto ISAKMP SA

C-id  Local           Remote          I-VRF    Status Encr Hash Auth DH Lifetime Cap.

1001  192.168.4.2     172.16.10.1              ACTIVE 3des md5  psk  1  00:09:51 N
Engine-id:Conn-id =  SW:1

IPv6 Crypto ISAKMP SA

RRight#
RRight#
RRight#show crypto ipsec sa detail

interface: FastEthernet0/0
Crypto map tag: CRYPTOMAP1, local addr 192.168.4.2

protected vrf: (none)
local  ident (addr/mask/prot/port): (172.16.20.3/255.255.255.255/47/0)
remote ident (addr/mask/prot/port): (172.16.10.1/255.255.255.255/47/0)
current_peer 172.16.10.1 port 4500
PERMIT, flags={origin_is_acl,}
#pkts encaps: 1860, #pkts encrypt: 1860, #pkts digest: 1860
#pkts decaps: 1863, #pkts decrypt: 1863, #pkts verify: 1863
#pkts compressed: 0, #pkts decompressed: 0
#pkts not compressed: 0, #pkts compr. failed: 0
#pkts not decompressed: 0, #pkts decompress failed: 0
#pkts no sa (send) 7, #pkts invalid sa (rcv) 0
#pkts encaps failed (send) 0, #pkts decaps failed (rcv) 0
#pkts invalid prot (recv) 0, #pkts verify failed: 0
#pkts invalid identity (recv) 0, #pkts invalid len (rcv) 0
#pkts replay rollover (send): 0, #pkts replay rollover (rcv) 0
##pkts replay failed (rcv): 0
#pkts internal err (send): 0, #pkts internal err (recv) 0

local crypto endpt.: 192.168.4.2, remote crypto endpt.: 172.16.10.1
path mtu 1500, ip mtu 1500, ip mtu idb FastEthernet0/0
current outbound spi: 0x724AD016(1917505558)

inbound esp sas:
spi: 0xF8743C7E(4168367230)
transform: esp-3des esp-md5-hmac ,
in use settings ={Tunnel UDP-Encaps, }
conn id: 1, flow_id: SW:1, crypto map: CRYPTOMAP1
sa timing: remaining key lifetime (k/sec): (4522175/579)
IV size: 8 bytes
replay detection support: Y
Status: ACTIVE

inbound ah sas:

inbound pcp sas:

outbound esp sas:
spi: 0x724AD016(1917505558)
transform: esp-3des esp-md5-hmac ,
in use settings ={Tunnel UDP-Encaps, }
conn id: 2, flow_id: SW:2, crypto map: CRYPTOMAP1
sa timing: remaining key lifetime (k/sec): (4522178/579)
IV size: 8 bytes
replay detection support: Y
Status: ACTIVE

outbound ah sas:

outbound pcp sas:
RRight#
RRight#
RRight#show crypto session detail
Crypto session current status

Code: C - IKE Configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal, X - IKE Extended Authentication

Interface: FastEthernet0/0
Session status: DOWN
Peer: 172.16.10.1 port 500 fvrf: (none) ivrf: (none)
Desc: (none)
Phase1_id: (none)
IPSEC FLOW: deny ip 0.0.0.0/0.0.0.0 0.0.0.0/0.0.0.0
Active SAs: 0, origin: crypto map
Inbound:  #pkts dec'ed 0 drop 0 life (KB/Sec) 0/0
Outbound: #pkts enc'ed 0 drop 0 life (KB/Sec) 0/0

Interface: FastEthernet0/0
Uptime: 00:50:30
Session status: UP-ACTIVE
Peer: 172.16.10.1 port 4500 fvrf: (none) ivrf: (none)
Phase1_id: 172.16.10.1
Desc: (none)
IKE SA: local 192.168.4.2/4500 remote 172.16.10.1/4500 Active
Capabilities:N connid:1001 lifetime:00:09:29
IPSEC FLOW: permit 47 host 172.16.20.3 host 172.16.10.1
Active SAs: 2, origin: crypto map
Inbound:  #pkts dec'ed 1869 drop 0 life (KB/Sec) 4522175/569
Outbound: #pkts enc'ed 1866 drop 7 life (KB/Sec) 4522178/569

RRight#

If we go to the NATRouter, and have a look at the NAT translations, we will see the IPSEC NAT-T translation there:

NATRouter#sh ip nat translations
Pro Inside global      Inside local       Outside local      Outside global
udp 172.16.20.3:4500   192.168.4.2:4500   172.16.10.1:4500   172.16.10.1:4500
NATRouter#

Additionaly, to make some use of the site-to-site configuration we have, we are running EIGRP over it for the two local networks, and we can see the EIGRP neighbors and routes on both sides:

RLeft:

RLeft#show ip eigrp neighbors
IP-EIGRP neighbors for process 100
H   Address                 Interface       Hold Uptime   SRTT   RTO  Q  Seq
(sec)         (ms)       Cnt Num
0   192.168.3.2             Tu1               13 00:52:58  156  5000  0  3
RLeft#show ip route eigrp
D    192.168.2.0/24 [90/297372416] via 192.168.3.2, 00:53:08, Tunnel1
RLeft#

RRight:

RRight#show ip eigrp neighbors
IP-EIGRP neighbors for process 100
H   Address                 Interface       Hold Uptime   SRTT   RTO  Q  Seq
(sec)         (ms)       Cnt Num
0   192.168.3.1             Tu1               14 00:52:42  185  5000  0  3
RRight#show ip route eigrp
D    192.168.1.0/24 [90/297372416] via 192.168.3.1, 00:52:45, Tunnel1
RRight#

And, we can ping across the tunnel as well:

RLeft#ping 192.168.2.1 sou 192.168.1.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.2.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 116/157/204 ms
RLeft#

RRight#ping 192.168.1.1 sou 192.168.2.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.2.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 132/157/204 ms
RRight#

Complete configurations

Links to the complete configurations of the routers in this lab:

| RLeft | ICRouter | NATRouter | RRight |

2 thoughts on “Terminating a GRE/IPSEC tunnel behind NAT

  1. had this problem for a few days now, but as soon as you mentioned loopback interfaces with the NAT address it all feel into place…

  2. Why configure the RRight’s tunnel source address the NAT address?If configure it to the interface FastEthernet0/0 address,so u need not to bring up a loopback on RRight holding this NAT IP address.

Leave a Reply

Your email address will not be published. Required fields are marked *