VRFing 102, Providing Internet Access With Dynamic PAT

Last week I wrote an article called VRFing 101, Understanding VRF Basics. This was a short and simple introduction into a technology that provides tremendous flexibility for network designers. With flexibility, complexity always follows. This is true in the case of VRFs as well. This week we are going to wade just a bit deeper in to the VRF waters and learn how we can use a very simple NAT configuration alongside the network we constructed last week.

Those who enjoy VRFing 101, 102 and 103 will also find the following series on Layer 3 Segmentation with VRFs useful.

https://packetu.com/2017/01/29/segmenting-layer-3-networks-vrfs/

Today’s Challenge—Utilizing the network we built last week as a base configuration, allow both VRFs to access the Internet connection on R1’s Fa0/1. Each tenant, represented by a separate VRF, should use a separate IP address assigned by the service provider (that’d be you). The tenants should not be able to access each other. The NAT should be in the form of NAT Overload (aka PAT).

Last week I said that each VRF was a separate routing table instance. Hmmm, that creates a challenge. How do we get traffic that belongs to a VRF to route based on the global routing table? Then how do we get traffic to translate to a publicly routable address? Fortunately, IOS has some tools to help us do just that.

Before we get into this new challenge, I wanted to quickly review R1’s configuration from last week. This becomes the base configuration for today’s article.

R1 Base Configureation

//create the VRFs
R1(config)#ip vrf red
R1(config)#ip vrf blue

//configure the interface and assign the VRF 
R1(config-subif)#int fa0/0.10 
R1(config-subif)#encapsulation dot1Q 10 
R1(config-subif)#ip vrf forwarding red 
R1(config-subif)#ip address 192.168.1.1 255.255.255.0 

//configure the interfaces and assign the VRF 
R1(config-subif)#int fa0/0.20 
R1(config-subif)#encapsulation dot1Q 20 
R1(config-subif)#ip vrf forwarding blue 
R1(config-subif)#ip address 192.168.1.1 255.255.255.0

For today’s challenge, we need to configure a link to the upstream router and route traffic for our the two VRFs. The initial interface configuration is typical.

R1(config)#int fa0/1
R1(config-if)#ip address 192.0.2.2 255.255.255.0
R1(config-if)#no shut

Since I like to test things as I go, let’s make sure R1 can reach the next hop Internet router. Because we are using an address that is reachable from the global routing table, this requires only the standard ping command.

R1(config-if)#do ping 192.0.2.1
Type escape sequence to abort. 
Sending 5, 100-byte ICMP Echos to 192.0.2.1, timeout is 2 seconds: 
..!!! 
Success rate is 60 percent (3/5), round-trip min/avg/max = 1/2/4 ms R1(config-if)#

Now we know that 192.0.2.1 is alive and we are going to need to use it as the next-hop for traffic originating in the “red” and “blue” VRFs. But they’re VRFs and have a separate routing instance. Cisco provides two options for overcoming this limitation. The first configuration option is to identify the egress interface in the “ip route” command. Since the interface is tagged with a vrf, the router can deduce the destination routing table instance or VRF. The other option is to use the “global” keyword on the end of the route statement to instruct the router to look up the next hop from the global routing table.

Two Options for Routing into a different VRF

//interface in the route command
R1(config)#ip route vrf red 0.0.0.0 0.0.0.0 fa0/1 192.0.2.1
R1(config)#ip route vrf blue 0.0.0.0 0.0.0.0 fa0/1 192.0.2.1

-or-

//global keyword on the route command
R1(config)#ip route vrf red 0.0.0.0 0.0.0.0 192.0.2.1 global
R1(config)#ip route vrf blue 0.0.0.0 0.0.0.0 192.0.2.1 global

Now that we have provided the routes that should steer the traffic out Fa0/1, let’s start working on our NAT configuration. This isn’t overly complicated, but it should be taken one step at a time. First we need to build a NAT pool for each VRF. This is where we will tell the router what address we want to translate to.

//NAT pool RED 192.0.2.10 (later used for vrf red)
R1(config)#ip nat pool RED 192.0.2.10 192.0.2.10 prefix-length 24

//NAT pool BLUE 192.0.2.20 (later used for vrf blue)
R1(config)#ip nat pool BLUE 192.0.2.20 192.0.2.20 prefix-length 24

Create ACLs to identify interesting traffic to be NAT’d

//to be used for vrf red
R1(config)#ip access-list extended REDNAT
R1(config-ext-nacl)#permit ip 192.168.1.0 0.0.0.255 any

//to be used for vrf blue
R1(config)#ip access-list extended BLUENAT
R1(config-ext-nacl)#permit ip 192.168.1.0 0.0.0.255 any

Now it is necessary to bring the acl that identifies the interesting traffic together with the NAT pool and vrf. This is very similar to a standard “ip nat” command.

//ip nat command for vrf red
R1(config)#ip nat inside source list REDNAT pool RED vrf red overload

//ip nat command for vrf blue
R1(config)#ip nat inside source list BLUENAT pool BLUE vrf blue overload

The last configuration step is to add the appropriate “ip nat inside” and “ip nat outside” commands to our interfaces. I have included all of the sub interface commands for clarity.

//red vrf interface (inside)
R1(config)#int fa0/0.10
R1(config-subif)#encapsulation dot1Q 10
R1(config-subif)#ip vrf forwarding red
R1(config-subif)#ip nat inside
R1(config-subif)#ip address 192.168.1.1 255.255.255.0

//blue vrf interface (inside)
R1(config-subif)#int fa0/0.20
R1(config-subif)#encapsulation dot1Q 20
R1(config-subif)#ip vrf forwarding blue
R1(config-subif)#ip nat inside
R1(config-subif)#ip address 192.168.1.1 255.255.255.0

//outside interface
R1(config-subif)#int fa0/1
R1(config-if)#ip nat outside
R1(config-if)#ip address 192.0.2.2 255.255.255.0

Finally, we can test our configuration to see if we achieved the goal and fulfilled the challenge.

Enable NAT Debugs on R1
R1#debug ip nat
IP NAT debugging is on
R1#

Test connectivity from R2 (red)

R2#ping 192.0.2.1

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

//success

Test connectivity from R3 (blue)

R3#ping 192.0.2.1

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

//success

Examine R1’s debugs to confirm the translations.

// Already enabled “debug ip nat”
// IP NAT debugging is on

//Output from R2 Pinging 192.0.2.1

Jul 7 04:05:30.851: NAT*: s=192.168.1.2->192.0.2.10, d=192.0.2.1 [217]
Jul 7 04:05:30.855: NAT*: s=192.0.2.1, d=192.0.2.10->192.168.1.2 [217]
Jul 7 04:05:30.855: NAT*: s=192.168.1.2->192.0.2.10, d=192.0.2.1 [218]
Jul 7 04:05:30.859: NAT*: s=192.0.2.1, d=192.0.2.10->192.168.1.2 [218]
Jul 7 04:05:30.859: NAT*: s=192.168.1.2->192.0.2.10, d=192.0.2.1 [219]
Jul 7 04:05:30.859: NAT*: s=192.0.2.1, d=192.0.2.10->192.168.1.2 [219]
Jul 7 04:05:30.863: NAT*: s=192.168.1.2->192.0.2.10, d=192.0.2.1 [220]
Jul 7 04:05:30.863: NAT*: s=192.0.2.1, d=192.0.2.10->192.168.1.2 [220]
Jul 7 04:05:30.867: NAT*: s=192.168.1.2->192.0.2.10, d=192.0.2.1 [221]
Jul 7 04:05:30.867: NAT*: s=192.0.2.1, d=192.0.2.10->192.168.1.2 [221]

//Output from R3 Pinging 192.0.2.1

Jul 7 04:05:39.395: NAT*: s=192.168.1.2->192.0.2.20, d=192.0.2.1 [148]
Jul 7 04:05:39.399: NAT*: s=192.0.2.1, d=192.0.2.20->192.168.1.2 [148]
Jul 7 04:05:39.399: NAT*: s=192.168.1.2->192.0.2.20, d=192.0.2.1 [149]
Jul 7 04:05:39.399: NAT*: s=192.0.2.1, d=192.0.2.20->192.168.1.2 [149]
Jul 7 04:05:39.399: NAT*: s=192.168.1.2->192.0.2.20, d=192.0.2.1 [150]
Jul 7 04:05:39.403: NAT*: s=192.0.2.1, d=192.0.2.20->192.168.1.2 [150]
Jul 7 04:05:39.403: NAT*: s=192.168.1.2->192.0.2.20, d=192.0.2.1 [151]
Jul 7 04:05:39.407: NAT*: s=192.0.2.1, d=192.0.2.20->192.168.1.2 [151]
Jul 7 04:05:39.407: NAT*: s=192.168.1.2->192.0.2.20, d=192.0.2.1 [152]
Jul 7 04:05:39.407: NAT*: s=192.0.2.1, d=192.0.2.20->192.168.1.2 [152]

We should also be able to ping 1.1.1.1, our emulated host out on the Internet

Testing from R2

R2#ping 1.1.1.1

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

Testing from R3

R3#ping 1.1.1.1

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

One more thing worth noting is how VRFs affect output of the “show ip nat translations” command. If you recall from last week, the “show ip route” command only shows the routes from the global routing table. Nothing from the VRFs are shown without adding the vrf to the command. Things seem a little different here. The “show ip nat translations” does show ALL of the translations.

R1#show ip nat translations
Pro Inside global Inside local Outside local Outside global
icmp 192.0.2.10:46 192.168.1.2:46 1.1.1.1:46 1.1.1.1:46
icmp 192.0.2.10:47 192.168.1.2:47 1.1.1.1:47 1.1.1.1:47
icmp 192.0.2.20:33 192.168.1.2:33 1.1.1.1:33 1.1.1.1:33

If you think about it, that actually makes sense. Each translation exists in a vrf as well as the global IP space. However, if you want to specify a vrf, you can see only that subset of translations.

//translations for red
R1#show ip nat translations vrf red
Pro Inside global Inside local Outside local Outside global
icmp 192.0.2.10:46 192.168.1.2:46 1.1.1.1:46 1.1.1.1:46
icmp 192.0.2.10:47 192.168.1.2:47 1.1.1.1:47 1.1.1.1:47

//translations for blue 
R1#show ip nat translations vrf blue 
Pro Inside global Inside local Outside local Outside global 
icmp 192.0.2.20:33 192.168.1.2:33 1.1.1.1:33 1.1.1.1:33

If you are trying to replicate this output, be aware that the translations will timeout and be removed. Therefore, it might be necessary to send more traffic.

Hopefully, you are starting to see how VRFs can be useful. While this configuration is incrementally more complex and useful, it still leaves some challenges. For example, what if each tenant wanted to make a web server publicly available. While a static translation might work for traffic coming into the interface designated as outside, challenges may exist if a host in the opposite VRF needed to access the server. NAT rules aren’t invoked when a packet passes between two interfaces that are designated as “ip nat inside”. In a future article, we will attack this problem using a different type of NAT configuration.

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 How-To and tagged . Bookmark the permalink.

6 Responses to VRFing 102, Providing Internet Access With Dynamic PAT

  1. Shamal Weerakoon says:

    Hi Paul,

    Thanks so much for this article. Had lots of doubts and finally got rid of them after reading your article. I have one question though.

    If my internet facing address is in VRF and inside lan is in global routing table, what would change if I want to do NAT overload ( use the interface IP as the translated address) assuming we have VRF on outside interface called “OUTVRF”.

    Really appreciate your help here

    • Paul Stewart says:

      I need to verify this. However, my initial thoughts are this.

      1 – Configure the nat/pat normally
      2 – For the default route, use the next hop IP AND the egress interface. For example-

      ip route 0.0.0.0 0.0.0.0 s0/0/0

      I think that manually allows a jump into a vrf. There could still be a return path issue. Again, just my initial thoughts. I’d need to lab it up to be sure.

      • Sensie says:

        Hi Paul,

        First i would like to thanks you a lot for this Article it’s very useful ..
        i have the similar problem that Shamal mention in one of our sites and it’s driving me crazy 🙁

        My Issue:
        The interface facing the Internet in VRF and the LAN in Global, i need to SSH/Telnet to the devices in the LAN using the Public IP Address with Static NAT!

        if you can help me with this, i would really appreciated.
        🙂

      • Paul Stewart, CCIE 26009 (Security) says:

        Sensie,

        Using NAT Virtual Interface might help with your issue. Take a look at the following Article and see if it looks like it might resolve your challenge.

        https://packetu.com/2012/07/26/vrfing-103-using-nat-virtual-interfaces-for-global-reachability/

  2. erosensie says:

    hi Paul,
    so i read the VRF103.
    in both vrf 102 and 103, you are using the Static ip route to route the traffic from the VRF to the Global and using the NAT to route the traffic from Global to the VRF.

    how would i configure that static route when i need to route the traffic from VRF to the Global ??

    Sensie

  3. Pingback: Segmenting Layer 3 Networks with VRFs - PacketU

Comments are closed.