Using Route Based VPNs to Make Hairpinning More Logical

Last week we looked at the challenges of combining VPN and NAT on the same device while hairpinning VPN traffic back out to the Internet. That created some interesting challenges with NAT that required some duct tape and band-aids to resolve. Actually, we used policy based routing in conjunction with a loopback interface to initiate the dynamic NAT translations.

In any case, our configuration last week was a far less than elegant approach. This week, we are going to start with the same diagram and a similar scenario. This configuration is built in an IOS router environment. However, we are going to remove the restriction that requires the VPN built using traditional crypto maps.

The Scenario–

You are the administrator of the network shown below. On the left is a branch office that needs a built to the LAN for the Headquarters (represented by Loopback0). As is typically the case, you have no control over routers or hosts that are outside the organization on the Internet. Your boss also decides he (or she) desires that all branch Internet traffic use the 192.0.2.131 from R3 at Headquarters. All traffic between Branch and HQ must be encrypted. Your boss stresses that an elegant and logical configuration is desired (I like your boss :-0 ).


PC (emulated by a Cisco Router)

hostname PC
!
no ip routing
!
interface FastEthernet0/1
 ip address 192.168.0.2 255.255.255.0
!
ip default-gateway 192.168.0.1

WWW_Server (emulated by a Cisco Router)–Not under your control

hostname WWW_Server
!
no ip routing
!
interface FastEthernet0/0
 ip address 192.0.2.3 255.255.255.128
!
ip default-gateway 192.0.2.2

R2–Not under your control

hostname R2
!
interface FastEthernet0/0
 ip address 192.0.2.2 255.255.255.128
!
interface Serial0/0
 ip address 192.0.2.130 255.255.255.128

The above device configurations are shown for informational purposes only. No changes will be necessary. The following devices configure the current NAT and Internet configuration for their respective location. After reviewing the base configuration, we will configure R1 and R3 for the VPN and appropriate NAT at R3.

R1–Branch Office

hostname R1
!         
interface FastEthernet0/0
 ip address 192.0.2.1 255.255.255.128
 ip nat outside
!         
interface FastEthernet0/1
 ip address 192.168.0.1 255.255.255.0
 ip nat inside
!         
ip route 0.0.0.0 0.0.0.0 192.0.2.2
!
ip nat inside source list NAT interface FastEthernet0/0 overload
!         
ip access-list extended NAT
 permit   ip 192.168.0.0 0.0.0.255 any
!

R3–Headquarters

hostname R3
!

!  
interface Loopback0
 description LAN
 ip nat inside
 ip address 192.168.1.1 255.255.255.0
!
interface Serial0/0
 ip address 192.0.2.131 255.255.255.128
 ip nat outside
!
ip route 0.0.0.0 0.0.0.0 192.0.2.130
!
ip nat inside source list NAT interface Serial0/0 overload
!         
ip access-list extended NAT
 permit ip 192.168.1.0 0.0.0.255 any
!

At this stage, our branch office and Headquarters are two standalone entities. Each has their own connection to the Internet and there is no connection between the two. Your boss asked you to build a VPN in an eloquent way that sends the Branch traffic through R3 when accessing the Internet. Additionally, we will need to provide access from R1’s LAN to R3’s LAN. Let’s get started with SVTI (Static Virtual Tunnel Interface) in order to accomplish this. SVTI provides an extra place to hook important things like NAT and ACL’s.

R1–Branch Office

hostname R1
!
crypto isakmp policy 10
 encr 3des
 hash md5 
 authentication pre-share
crypto isakmp key cisco address 192.0.2.131
!         
crypto ipsec transform-set MYSET esp-3des esp-md5-hmac 
!         
crypto ipsec profile MYVTI
 set transform MYSET
!
interface tunnel 1
 ip address 10.1.1.1 255.255.255.0
 tunnel mode ipsec ipv4
 tunnel source 192.0.2.1
 tunnel destination 192.0.2.131
 tunnel protection ipsec profile MYVTI
!  
//we shouldn't need NAT anymore on R1       
interface FastEthernet0/0
 no ip nat outside
!         
interface FastEthernet0/1
 no ip nat inside
!         
no ip nat inside source list NAT interface FastEthernet0/0 overload
!
//we only want to route tunnel traffic to 192.0.2.2 now
no ip route 0.0.0.0 0.0.0.0 192.0.2.2
ip route 192.0.2.131 255.255.255.255 192.0.2.2

//everything else should go through the tunne 
//10.1.1.3 is the VTI on the other end
ip route 0.0.0.0 0.0.0.0 10.1.1.3
!
!

R3–Headquarters

hostname R3
!
crypto isakmp policy 10
 encr 3des
 hash md5 
 authentication pre-share
crypto isakmp key cisco address 192.0.2.1
!         
crypto ipsec transform-set MYSET esp-3des esp-md5-hmac 
!         
crypto ipsec profile MYVTI
 set transform MYSET
!           
interface tunnel 1
 //this is the cool part
 //we can set ip nat inside on the vti
 ip nat inside
 ip address 10.1.1.3 255.255.255.0
 tunnel mode ipsec ipv4
 tunnel source 192.0.2.131
 tunnel destination 192.0.2.1
 tunnel protection ipsec profile MYVTI
!
//add a more specific route to get to 192.168.0.0/24
ip route 192.168.0.0 255.255.255.0 10.1.1.1
!
//expand the NAT ACL to include 192.168.0.0/24
ip access-list extended NAT
 permit ip 192.168.1.0 0.0.0.255 any
 permit ip 192.168.0.0 0.0.0.255 any
!

Okay, now all we need to do is test our configuration. For this, I’ll enable “debug ip packet” on WWW_Server and “debug ip nat” on R3.

WWW_Server#debug ip packet
IP packet debugging is on
WWW_Server#
R3#debug ip nat
IP NAT debugging is on
R3#

Now we’ll try pinging 192.168.1.1 and 192.0.2.3 from “PC”.

PC#ping 192.168.1.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/37/44 ms
PC#ping 192.0.2.3  

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.0.2.3, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
PC#

Well that’s just typical. The easy one worked and the more complicated one failed. But that gives us the opportunity to troubleshoot. Let’s see if we have any output from the debugs on WWW_Server and R3.

R3#
WWW_Server#
*Mar  1 00:23:47.623: IP: s=192.168.0.2 (FastEthernet0/0), d=192.0.2.3, len 100, rcvd 1
*Mar  1 00:23:47.623: IP: tableid=0, s=192.0.2.3 (local), d=192.168.0.2 (FastEthernet0/0), routed via RIB
//this repeats 5 times

Well there is no output on R3, so it isn’t NAT’ing the packets. WWW_Server confirms this by showing us the source of 192.168.0.2. So let’s double check our NAT ACL on R3.

R3#show run | sec NAT
ip nat inside source list NAT interface Serial0/0 overload
ip access-list extended NAT
 permit ip 192.168.1.0 0.0.0.255 any
 permit ip 192.168.0.0 0.0.0.255 any
R3#show run int s0/0 
Building configuration...

Current configuration : 126 bytes
!
interface Serial0/0
 ip address 192.0.2.131 255.255.255.128
 ip nat outside
 ip virtual-reassembly
 clock rate 2000000
end

R3#show run int tun 1
Building configuration...

Current configuration : 218 bytes
!
interface Tunnel1
 ip address 10.1.1.3 255.255.255.0
 ip nat inside
 ip virtual-reassembly
 tunnel source 192.0.2.131
 tunnel destination 192.0.2.1
 tunnel mode ipsec ipv4
 tunnel protection ipsec profile MYVTI
end

That looks like it should work to me. Maybe the traffic isn’t even getting to R3 to be NAT’d. Let’s go back and look at R1.

R1#show crypto ipsec sa

interface: Tunnel1
    Crypto map tag: Tunnel1-head-0, local addr 192.0.2.1

   protected vrf: (none)
   local  ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   remote ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   current_peer 192.0.2.131 port 500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 50, #pkts encrypt: 50, #pkts digest: 50

Well that looks like it would tunnel everything associated with the tunnel interface. Let’s look at how our R1 would reach 192.0.2.3.

R1#show ip route 192.0.2.3
Routing entry for 192.0.2.0/25
  Known via "connected", distance 0, metric 0 (connected, via interface)
  Routing Descriptor Blocks:
  * directly connected, via FastEthernet0/0
      Route metric is 0, traffic share count is 1

So the packets aren’t even routed out tunnel 0. This is actually an anomaly since this is a lab environment. Directly connected networks are automatically entered into the routing table and are more specific than the default route. Let’s fix it for this host.

R1(config)#ip route 192.0.2.3 255.255.255.255 10.1.1.3

R1(config)#do show ip route 192.0.2.3
Routing entry for 192.0.2.3/32
  Known via "static", distance 1, metric 0
  Routing Descriptor Blocks:
  * 10.1.1.3
      Route metric is 0, traffic share count is 1

R1(config)#

Now let’s try again.

PC#ping 192.168.1.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/40/48 ms

//first test still works

//now to test pinging WWW_Server
PC#ping 192.0.2.3  

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.0.2.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 40/62/76 ms
PC#

//w00t

Now Let’s Look at our debugs

R3#
*Mar  1 00:32:12.087: NAT*: s=192.168.0.2->192.0.2.131, d=192.0.2.3 [115]
*Mar  1 00:32:12.095: NAT*: s=192.0.2.3, d=192.0.2.131->192.168.0.2 [115]
WWW_Server#
*Mar  1 00:23:47.623: IP: s=192.168.0.2 (FastEthernet0/0), d=192.0.2.3, len 100, rcvd 1
*Mar  1 00:23:47.623: IP: tableid=0, s=192.0.2.3 (local), d=192.168.0.2 (FastEthernet0/0), routed via RIB

If WWW_Server hadn’t of been “directly connected” to R1 and thus already in the routing table, this exercise would have been very logical and eloquent. This is a much cleaner approach to this type of scenario than traditional policy based VPNs. Unfortunately, there is no option for VTI in the Cisco ASA. Therefore, this is a Router only option.

If you have other methods or scenarios, I’d love to hear about them. Feel free to reach out via Facebook, Twitter, or the Requests Link above. Also, I love to hear comments and feedback about the weekly articles.

No related content found.

About Paul Stewart, CCIE 26009 (Security)

Paul is a Network and Security Engineer, Trainer and Blogger who enjoys understanding how things really work. With over 15 years of experience in the technology industry, Paul has helped many organizations build, maintain and secure their networks and systems.
This entry was posted in Design. Bookmark the permalink.

13 Responses to Using Route Based VPNs to Make Hairpinning More Logical

  1. Pablo says:

    Hi,

    First off all I would like to say that you have great website.
    There is any possible to show us the configuration supposing that we have two branch office and one HQ?All branch offices getting internet from HQ.

    Kind regards,
    Pablo

  2. Matt says:

    I’ve done as you suggested. In order to manage a customer network i must actually come in through a crypto policy and then nat to the lan interface so that packets from my monitoring center will appear as coming from my lan interface. In other words: Me—->internet—>fa4–>de-crypto—>vlan1. I have created loop1:

    interface Loopback1
    ip address 172.30.251.1 255.255.255.252
    ip nat inside
    ip virtual-reassembly in

    I have created a route-map:

    route-map s2s-vpn-nat permit 10
    match ip address s2s-nat
    set ip next-hop 172.30.251.2

    the ACL match is created as follows:

    Extended IP access list s2s-nat
    10 permit ip host 172.30.252.110 172.20.205.0 0.0.0.255 log

    I have applied this route-map to the vlan interface:

    interface Vlan1
    ip address 10.254.5.1 255.255.0.0
    ip access-group 150 out
    ip nat outside
    ip virtual-reassembly in
    ip policy route-map s2s-vpn-nat
    end

    I can do a debug packet and i see the traffic from the vpn as i ping 172.20.205.10:

    067897: *Oct 14 10:50:32.615: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10, len 60, input feature, Process Packet Capture(4), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067898: *Oct 14 10:50:32.615: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10, len 60, input feature, IPSec input classification(52), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067899: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10, len 60, input feature, MCI Check(101), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067900: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, output feature, Post-routing NAT Outside(25), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067901: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, output feature, Common Flow Table(28), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067902: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, output feature, Stateful Inspection(29), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067903: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, output feature, Access List(50), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067904: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, output feature, NAT ALG proxy(61), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067905: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), g=10.254.1.251, len 60, forward
    067906: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, post-encap feature, CEF Packet Capture(35), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
    067907: *Oct 14 10:50:32.619: IP: s=172.30.252.110 (FastEthernet4), d=172.20.205.10 (Vlan1), len 60, sending full packet

    Which in summary sees the packet from my real source, with the real destination, chooses the route to vlan 1 (as configured by a static route) and selects the gateway out the vlan interface and sends the packet. There is no mention of hitting the route map. The traffic does not reroute to loop1 only to nat from inside to outside. Looking at the route-map reveals no matches:

    route-map s2s-vpn-nat, permit, sequence 10
    Match clauses:
    ip address (access-lists): s2s-nat
    Set clauses:
    ip next-hop 172.30.251.2
    Policy routing matches: 0 packets, 0 bytes

    No matches on the policy map. No matches on the acl in the policy map. But the debug ip packet clearly shows matching traffic. The traffic doesn’t even seem to hit the route-map. Indeed, a debug ip policy shows lots of traffic hitting the route-map and being rejected and “normally forwarded”… just none of the traffic specified in the acl in the route-map. What gives? What am i missing? I am running: Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.2(4)M6, RELEASE SOFTWARE (fc2)

    Any ideas would be greatly appreciated.

    • I’m not sure I fully follow the question. However, the ACL applied to the RM would be backwards for the traffic received by “interface vlan 1”.

      • Matt says:

        Thanks for the speedy response. Let me clarify: the source traffic comes over a vpn tunnel to the device via crypto policy on fa4. The source of the decrypted traffic is 172.30.252.110. The destination of the decrypted traffic 172.20.205.10. A static route points this destination to a LAN interface: VLAN1. Interface VLAN 1 goes towards the customer’s internal network. That VLAN 1 interface is configured with the ip nat outside command because I want to overload NAT my real source IP to the IP of the VLAN 1 interface before it is sent to the customer LAN via interface Vlan 1. I am doing this with the command:

        ip nat inside source list noc-nat interface Vlan1 overload.

        The access-list noc-nat is configured as:

        Standard IP access list noc-nat
        10 permit 172.30.252.110 log
        20 permit 209.51.49.0, wildcard bits 0.0.0.255 (65934 matches)
        40 deny any log (6 matches)

        The nat statement does not current get hit because i am coming out of a crypto policy tunnel (which cannot be configured as “ip nat inside) and being routed to interface Vlan 1 which is the “ip nat outside” interface. Because i am not going from “inside” to “outside” the nat doesn’t happen. I am attempting to have the route-map you suggested to reroute my traffic to loop1 (with ip nat inside) BEFORE it is sent back and out Interface VLAN 1 where, now that it has passed an inside and outside nat interface command, will use the ip nat inside source statement. You will see that my debug ip packet info that i pasted early matches the correct source and destination addresses in the route map but does not get “seen” by it. I think you may have thought that my ACL was reversed because you are used to seeing traffic go in the other direction. However to clarify:

        From: The internet into Fa4 over a crypto VPN policy with a decrypted source IP of 172.30.252.110
        To: Destination IP of 172.20.205.10 which is statically routed to interface VLAN 1.

        Please let me know if i’ve cleared up the confusion.

      • That does make sense. If that is the only traffic that needs NAT, I think the configuration can be simpler. The source of my statement around the ACL being backward is that traffic is only assessed as it enters the interface it is applied to. That ACL would only match traffic egressing VLAN1 (which is not how a route-map works).

        Regarding crypto and NAT, traffic is decrypted first then NAT is applied–

        http://www.cisco.com/c/en/us/support/docs/ip/network-address-translation-nat/6209-5.html

        I would think something like this would work

        int fa0/4
        ip address x.x.x.x y.y.y.y
        crypto map
        ip nat inside

        interface vlan 1
        ip address a.a.a.a b.b.b.b
        ip nat outside

        access-list 1 permit 172.30.252.110 0.0.0.0.0

        ip nat inside source list 1 interface vlan 1 overload

        I don’t see why a route-map would be required for the scenario. I would try to keep it simple if possible. HTH

      • Matt says:

        Would you believe the fa4 interface didn’t have NAT inside configured on it? I just assumed it was a default command. After successfully configuring this router to connect to a Juniper SSG i tried to figure out this NAT issue for 2.5 days, it turns out my fatal flaw was assuming a command was already there. After being a CCNP CCDP on IOS and CATOS for quite a while I switched up to a security role using cisco asa and juniper firewalls for the past 6 years. Being back on a Cisco IOS has left me… careless. Thank you so much for your patient and expedient expertise.

      • It is so easy to overlook things like that. Additionally, Cisco’s NAT implementation is oriented by interface. In any case, I’m glad you got it going.

  3. Kafi says:

    Thanks a lot for sharing your thoughts. Actually I tried to configure in the same way you suggested. So the branch office can share the internet and also it can access the hosts in HQ. But the problem is HQ cannot access anything at the branch office. So please tell me what could be the problem?

  4. Georg says:

    Hi Paul

    What is the situation was reversed.. ie the PC was in fact a WWW server (eg a cloud server and accessed via the VPN from HQ) and we wanted to direct port 80 from the internet to this server via R3? Is this possible?

Comments are closed.