Recently I had to configure a router serving as an IPsec-GRE endpoint. So far, nothing special. The interesting part is that the terminating router is behind a NAT-device which changes the outer IP-header of the IPsec tunnel. Of course, the GRE-header is NOT affected by the NAT (since it is encrypted).

To summarize, the device needs to:

  • terminate an IPsec tunnel between 172.16.2.2 <-> 10.0.0.4 (its own IP); but authenticate as 172.16.2.4
  • terminate a GRE tunnel between 172.16.1.1 <-> 172.16.2.4 (a public IP that is NATed towards it)

The diagram is shown below:

172.16.x.x addresses are “public”; 10.x.x.x are private.

The setup

For this post, I assume all routers can reach each other as they should. Only the “interesting” commands are shown below.

The GRE tunnel is sourced on the far left by “GreL”:

interface Tunnel0
 tunnel source FastEthernet0/0
 tunnel destination 172.16.2.4
interface FastEthernet0/0
 ip address 172.16.1.1 255.255.255.0

This GRE tunnel is encapsulated in an IPsec tunnel at device “IPsecL”:

crypto isakmp policy 1
 hash md5
 authentication pre-share
 lifetime 3600

crypto isakmp key SHAREDKEY address 172.16.2.4

crypto ipsec transform-set IPSEC_TS_NULL esp-null esp-md5-hmac

crypto map CRYPTOMAP_1 1 ipsec-isakmp
 set peer 172.16.2.4
 set transform-set IPSEC_TS_NULL
 match address ACL_GRE

interface FastEthernet0/0
 ip address 172.16.2.2 255.255.255.0
 crypto map CRYPTOMAP_1

ip access-list extended ACL_GRE
 permit gre host 172.16.1.1 host 172.16.2.4

The “Nat” router is fairly simple:

interface FastEthernet0/0
 ip nat outside

interface FastEthernet0/1
 ip nat inside

ip nat inside source static 10.0.0.4 172.16.2.4

The magic

The magic happens at router “R”. The problem is that the GRE needs to be terminated on the public IP. The left end of the connection is unaware of any NAT, and the NAT can’t change the GRE-IP-header since it’s protected by the IPsec.

There are probably other ways around this, but I solved the issue by adding a loopback interface with 172.16.2.4/32 as IP:

crypto isakmp policy 1
 hash md5
 authentication pre-share
 lifetime 3600

crypto isakmp key SHAREDKEY address 172.16.2.2

crypto ipsec transform-set IPSEC_TS_NULL esp-null esp-md5-hmac 

crypto map CRYPTOMAP_1 1 ipsec-isakmp
 set peer 172.16.2.2
 set transform-set IPSEC_TS_NULL
 match address ACL_GRE

interface Loopback0
 ip address 172.16.2.4 255.255.255.255

interface Tunnel0
 tunnel source Loopback0
 tunnel destination 172.16.1.1

interface FastEthernet0/0
 ip address 10.0.0.4 255.255.255.0
 crypto map CRYPTOMAP_1

ip access-list extended ACL_GRE
 permit gre host 172.16.2.4 host 172.16.1.1

The Results

I verified this setup to work in dynamips. I pinged from 10.0.1.1 to 10.0.4.4. Here are the packet dumps for the ICMP packet on its way from left to right.

The reply on its way back from right to left: