Showing posts with label GNS3. Show all posts
Showing posts with label GNS3. Show all posts

Thursday, May 04, 2017

Net::SSH2 Upgrade Access to Cisco

I upgraded my Strawberry Perl to 5.24 and my GNS3 test lab for SSH access via CRAPPS suddenly didn't work.

Knowing the Perl version changed, I checked and the Net::SSH2 version changed (0.58 to 0.63). Troubleshooting was pretty easy - just a quick Perl script to open a connection and die on failure with error:

#!perl
use strict;
use warnings;
use Net::SSH2;

my $ssh2 = Net::SSH2->new();
$ssh2->connect('10.254.254.1') or $ssh2->die_with_error;
print "Success\n";

The error was: Unable to exchange encryption keys (-8 LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE). OK, so I said troubleshooting was easy ... the solution ... maybe not so much?

Tuesday, November 24, 2015

DMVPN IPv6 Easy

I needed to test IPv6 overlay on DMVPN. Easy enough; there are plenty of DMVPN configuration guides out there and even some on IPv6. I tested on a version of 12.4T on 7200-series routers in GNS3 and the config was really as simple as taking my working IPv4 DMVPN setup and adding the same commands with an "ipv6" prefix, using IPv6 addresses and adding IPv6 EIGRP.

Monday, June 03, 2013

IPv6 to IPv4 Server Load Balancing Testing in GNS3

My last post talked about testing IPv4 / IPv6 web and proxy services using Qemu in GNS3. My next challenge was to understand the "easy" way to IPv6-enable an IPv4-only web site - configure your load balancer to do it.

The simple explanation for Server Load Balancing IPv6 to IPv4 (SLB64) is that it performs traditional server load balancing functions but additionally does address family translation from the requested IPv6 address to the real IPv4 address of the internal servers in the server farm.

I don't have a big name load balancer at my disposal nor does my laptop have the power needed to download a virtual image and spin up VMware connected to my GNS3 simulation. So I went looking for a linux software based alternative and found HAProxy. The site indicates IPv6 support came along in version 1.1 and of course there is a Tiny Core linux package available. That meant following the Qemu "installation" procedure I described in a previous post and doing the proper 'filetool' backup.

My lab looks like the following, including an Apache web server running on Qemu in GNS3 as described in the last post:

IPV6 = 2001:db8

 192.168.100.254    192.168.100.1      10.100.100.17
IPV6:192:168::254  IPV6:192:168::1
     HOST      ------    R1    ------   Web Server
                    10.200.200.1          (Qemu)
                   IPv6:AC8:C800::1
                          |
                          |
                    10.200.200.17
                  IPV6:AC8:C800::254
                       HAProxy
                       (Qemu)

The HAProxy package didn't come with a configuration or startup script, so I had to create them. First, the configuration file was pretty simple to create in /usr/local/etc/haproxy.conf:

global
  user tc
  group staff
  daemon
defaults
  mode tcp
  retries 3
  timeout connect 5000
  timeout client 50000
  timeout server 50000
listen ipv6proxy80 :::80
  server ipv4server80 10.100.100.17:80

A little translation: the 'global' and 'default' headings just set some standard parameters for HAProxy operation. The 'listen' heading is where I tell HAProxy to listen for all incoming IPv6 traffic to TCP port 80 (TCP comes from the 'mode tcp' command in the 'defaults' section). HAProxy should then distribute matched traffic to the listed servers - in this case only 10.100.100.17 on port 80. Listening on IPv6 and distributing to an IPv4 server causes HAProxy to do the address family translation from IPv6 to IPv4. Note that you can make this configuration much more secure and/or selective, but this is perfect for my little test.

Next, the startup script in /etc/init.d/services/loadbal:

#!/bin/sh
case "${1}" in
  start)
    /usr/local/sbin/haproxy -f /usr/local/etc/haproxy.conf -p /var/run/haproxy.pid -D
    ;;
  stop)
    pkill haproxy
    ;;
  status)
    pidof haproxy
    ;;
  *)
    exit 1
    ;;
esac

HAProxy is now started with "sudo /etc/init.d/services/loadbal start".

To test we need to remember that HAProxy is our load balancer and thus is advertising the "outside" (read: Internet) address of the web server. So on the HOST, I open a browser and point it to:

http://[2001:db8:AC8:C800::254]:80

SUCCESS! I get the home page from the Apache web server complete with the link to the CGI script to print my environment variables as described in my last post. That certainly comes in handy to see where the web server thinks the connection is coming from as does a 'netstat -an' on the HAProxy Qemu linux console.

Thursday, May 30, 2013

IPv4 / IPv6 Web and Proxy Server Testing in GNS3

In a previous post, I described how I got some additional packages installed on Tiny Core linux to use with Qemu in my GNS3 simulations. While that post describes how I got a DHCPv6 client loaded on my Tiny Core image, at the time I also loaded Apache. This gave me an IPv4 / IPv6 web server to test with. Additionally, Apache can be run as a proxy server, so I could test IPv4 / IPv6 proxy services with the single Apache install.

The first step was to create a configuration file for both web server and proxy. The default is installed in /usr/local/apache2/conf/httpd.conf and is suitable for the web server configuration. I copied that file to /usr/local/apache2/conf/proxy.conf and edited it. I kept only the "LoadModule" commands and then added:

ServerRoot "/usr/local/apache2"
listen 8080
User tc
Group staff
ProxyRequests On

You can get fancier, but that's all you really need for testing in a closed GNS3 lab environment.

Next, a nice home page on the web server that automatically displays some information would be nice. Printing environment variables like client IP address and server IP address will come in handy when testing through a proxy server to see what address (IPv4 or IPv6, client or proxy server) the "world" will see. Thankfully, the default install has this file. Unfortunately, it didn't work for me.

I had a permission issue and since the CGI script was really a link to the file, I couldn't change the permissions. Easy solution was to simply copy the file to the CGI bin directory and make the appropriate edits.

So first I need an index.html in /usr/local/apache2/htdocs. That looks like this:

<html>
<head>
<title>Title</title>
</head>
<body>
<h1>It works!</h1>
<a href = "cgi-bin/test-cgi-new">Environment</a>
</body>

Next, the actual /usr/local/apache2/cgi-bin/test-cgi-new script is create with:

cd /usr/local/apache2/cgi-bin
cp ./test-cgi ./test-cgi-new
chown tc test-cgi-new
chgrp staff test-cgi-new
chmod 755 test-cgi-new

Finally, a startup script for both web server and proxy server in /etc/init.d/services:

--httpd--

#!/bin/sh
case "${1}" in
  start)
    /usr/local/apache2/bin/httpd
    ;;
  stop)
    pkill httpd
    ;;
  status)
    pidof httpd
    ;;
  *)
    exit 1
    ;;
esac

--proxy--

#!/bin/sh
case "${1}" in
  start)
    /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/proxy.conf
    ;;
  stop)
    pkill httpd
    ;;
  status)
    pidof httpd
    ;;
  *)
    exit 1
    ;;
esac

Now I can start them with "sudo /etc/init.d/services/httpd start" and "sudo /etc/init.d/services/proxy start".

Of course, make sure you do this on Qemu outside of GNS3 and save your configurations by editing the appropriate "/opt/.filetool.lst" file and running "filetool" to backup as described in the previous post.

Then, I created a simple GNS3 lab with a router in the middle. I made one connection bridged to my host machine (loopback interface) and added some routes on the host to point towards the simulation networks. I made another router connection to one instance of Qemu where I run the proxy service. The final router connection goes to another instance of Qemu where I run the web server. Now I can test from my host browser on IPv4 and IPv6 to the test web server and I can also configure the simulation proxy server on my host to test out IPv4 / IPv6 proxy services to the web server in the simulation.

Next, I'll describe how I setup and tested Server Load Balancing 6 to 4 (SLB64) with HAProxy.

Wednesday, January 23, 2013

Testing DHCPv6: Part 2

In a previous post, I talked about getting a DHCPv6 client on a linux image to use with Qemu and GNS3. That post was mainly focused on documenting the steps to get the DHCPv6 client on the host and ultimately working. I neglected to talk about the DHCPv6 server that I configured on the Cisco router.

Of course, I was just bit by a minor configuration miss that I learned in that exercise and quickly forgot until gently reminded as I watched my DHCPv6 simulation NOT work.

The DHCPv6 server configuration on the router is pretty simple:

ipv6 dhcp pool DHCPv6
 address prefix 2001:DB8:A64:6800::/64
 dns-server 2001:4860:4860::8888
 domain-name dynamips.com

But what I forgot was that SLAAC is mandatory for IPv6 nodes and will work as long as router advertisements are present. So simply setting the M-bit in the router advertisements to force DHCPv6 is not enough. You need to NOT advertise the IPv6 prefix on the interface.

So the interface configuration looks like:

interface FastEthernet2/0
 ipv6 address 2001:DB8:A64:6800::1/64
 ipv6 enable
 ipv6 nd prefix 2001:DB8:A64:6800::/64 no-advertise
 ipv6 nd managed-config-flag
 no ipv6 redirects
 no ipv6 unreachables
 ipv6 dhcp relay destination 2001:DB8:A01:100::1

In the above example, I'm sending the DHCPv6 requests to the DHCPv6 server running on another Cisco router. I've set the M-bit and I've also stopped router advertisements of the prefix with the 'ipv6 nd prefix 2001:DB8:A64:6800::/64 no-advertise' command.

And now it works!

Thursday, December 20, 2012

Multicast IPv6 Anycast RP Design

Like most folks, I heard of multicast but never configured it. That changed back in 2006 when we deployed music on hold over multicast for our Cisco voice infrastructure and also installed VBrick IP television which required multicast. I did the research and created a PIM sparse mode design based on the Cisco Solution Reference Network Design for campus networks.

We used anycast rendezvous points (RP) peered with Multicast Source Discovery Protocol (MSDP). We used a site local multicast scope and properly filtered on the edge. We peered with the multicast RPs in our headquarters site and passed organization local scope groups. Overall, we had a pretty robust, fault tolerant multicast design.

I did more multicast work at my next client through 2011 including dense-mode and simplified multicast forwarding (SMF), custom code for Internet Group Management Protocol (IGMP) joins for multicast on mobile ad-hoc networks (MANET) and lots of other unique designs.

Of course, this was all on IPv4.

Multicast for IPv6 is a different beast and although I haven't seen a requirement to deploy it for a client yet, I wanted to do some testing to get up to speed before the need manifests. I was fortunate to attend the Cisco IPv6 Fundamentals, Design and Deployment class last week. Although much was review for me given my hands-on IPv6 experience over the last 4 years, the multicast module and lab was very informative.

I understood my IPv4 multicast reference design would not map to IPv6. While IPv6 supports anycast RP, there is no MSDP for IPv6. Some (very basic) background:

In a Protocol Independent Multicast Sparse-Mode (PIM-SM) design, multicast sources send their multicast streams to the Rendezvous Point (RP). Multicast listeners are directed to the RP to make the connection and start receiving traffic. To make the design redundant and fault tolerant, we use anycast RP. Anycast is the practice of configuring the same unicast address on multiple devices. Traffic is routed towards the closest instance of the address based on routing protocol metrics. This of course can result in multicast sources sending traffic to one anycast RP instance and multicast listeners being routed to a different anycast RP instance. No connection would be made in this case.

To overcome this issue, we use Multicast Source Discovery Protocol (MSDP) to peer the anycast RPs so they share information about the multicast sources. This way, no matter which instance of the anycast RP a listener connects to, it will be able to establish the stream from the multicast source and start receiving traffic.

With the above explanation, the absence of MSDP in IPv6 is a problem with an anycast RP design. Foregoing anycast RP and just using a single RP does not provide fault tolerance should the RP go down. What to do?

RFC 4610 addresses this issue and Cisco implements it in IOS 15 and other flavors like XE. However, I learned in class that Cisco had another approach they called "Anycast RP with prefix arbitration".

The concept is simple using standard routing rules of longest match prefix. Simply configure the anycast address on multiple devices with different masks. Instead of equal cost multipath routing in redundant environments, all traffic will be routed to the anycast instance with the longest prefix (anycast RP primary). Should that RP go down, all traffic will be routed to the anycast instance with the second longest prefix (anycast RP secondary), and so on (anycast RP tertiary ...). This is very similar to "floating static routes"; static routes with a manually configured admin distance to bring up a BRI interface when the primary frame-relay goes down (remember 1990's).

  • Configure primary anycast RP with longest prefix
  • Configure secondary anycast RP with second longest prefix
  • Configure tertiary anycast RP with third longest prefix
  • And so on ...
  • Advertise the anycast network from each device via routing protocol

This eliminates the need for MSDP to peer the anycast RPs since all traffic - both sources and listeners - will be routed to the same anycast RP instance. Or will it?

Consider an instance where multicast sources and / or listeners are directly connected to the devices which host the primary and secondary anycast RPs. Connected routes override any longest prefix match since they are connected. So there is a possibility where listeners won't be able to find sources. And that's what happened to me when I finished the documented multicast lab and decided to test this design.

The lab was only two routers with a client connected off each, so it's pretty obvious why it failed. I decided to test a more real-world scenario. Consider the following:

The relevant configurations:

C1#show run interface Loopback0
interface Loopback0
 description Anycast RP (Primary)
 no ip address
 ipv6 address 2001:DB8:AFE:FE00::1/120
 ipv6 enable
 ipv6 eigrp 1
end

C2#show run interface Loopback0
interface Loopback0
 description Anycast RP (Secondary)
 no ip address
 ipv6 address 2001:DB8:AFE:FE00::1/119
 ipv6 enable
 ipv6 eigrp 1
end

With anycast RP primary configured on C1 (/120 mask) and the anycast RP secondary configured on C2 (/119 mask), we expect all traffic to be routed to C1. Indeed it is from both D1 and D2:

D1#show ipv6 route 2001:db8:afe:fe00::1
Routing entry for 2001:DB8:AFE:FE00::/120
  Known via "eigrp 1", distance 90, metric 156160, type internal
  Route count is 1/1, share count 0
  Routing paths:
    FE80::C804:11FF:FE44:1C, FastEthernet1/0
      Last updated 00:00:12 ago

D2#show ipv6 route 2001:DB8:AFE:FE00::1
Routing entry for 2001:DB8:AFE:FE00::/120
  Known via "eigrp 1", distance 90, metric 156160, type internal
  Route count is 1/1, share count 0
  Routing paths:
    FE80::C804:11FF:FE44:1D, FastEthernet1/0
      Last updated 00:03:05 ago

"FastEthernet1/0" is the telltale that D1 and D2 will send their traffic for the anycast RP to C1 (see diagram above). When we shutdown the Loopback0 interface (anycast RP primary) on C1, traffic fails over:

D1#show ipv6 route 2001:db8:afe:fe00::1
Routing entry for 2001:DB8:AFE:FE00::/119
  Known via "eigrp 1", distance 90, metric 156160, type internal
  Route count is 1/1, share count 0
  Routing paths:
    FE80::C805:11FF:FE44:1C, FastEthernet1/1
      Last updated 00:03:25 ago

D2#show ipv6 route 2001:DB8:AFE:FE00::1
Routing entry for 2001:DB8:AFE:FE00::/119
  Known via "eigrp 1", distance 90, metric 156160, type internal
  Route count is 1/1, share count 0
  Routing paths:
    FE80::C805:11FF:FE44:1D, FastEthernet1/1
      Last updated 00:03:27 ago

So the solution works! But what routes do C1 and C2 see? When operating in steady state (each anycast RP interface on C1 and C2 is up), all routing doesn't point to C1:

C1#show ipv6 route 2001:DB8:AFE:FE00::1
Routing entry for 2001:DB8:AFE:FE00::1/128
  Known via "connected", distance 0, metric 0, type receive
  Route count is 1/1, share count 0
  Routing paths:
    receive via Loopback0
      Last updated 00:00:28 ago

C2#show ipv6 route 2001:DB8:AFE:FE00::1
Routing entry for 2001:DB8:AFE:FE00::1/128
  Known via "connected", distance 0, metric 0, type receive
  Route count is 1/1, share count 0
  Routing paths:
    receive via Loopback0
      Last updated 00:19:13 ago

Notice C1 and C2 each see the anycast RP address as their local Loopback0 interface. In the case of C1, that's correct. In the case of C2, it's correct (according to routing rules), but not desired (according to our anycast RP with prefix arbitration design). There isn't a way to "fix" it as it isn't broken, it just highlights a design constraint on the "Anycast RP with prefix arbitration" design:

  • Never directly connect multicast sources or listeners to a device acting as an anycast RP

This may not be a problem in the design I tested as most people won't connect end stations to the core layer. But consider collapsed core designs or instances where the RPs may be configured on distribution layer switches that connect servers which are multicast sources.

"Anycast RP with prefix arbitration" is a pretty easy, straight forward design, but like anything new, test first and understand the limitations.

Tuesday, December 18, 2012

IPv6 TFTP from IPv4

No, the title doesn't imply a great new translation technology for that indispensable file transfer protocol TFTP. Instead, this is to highlight an "oversight" - I won't go so far as to call it a "bug" - in Cisco IOS.

I'm testing with version Advanced IP Services 12.4 (24)T on a 7200 series router - just in case that matters.

For many services on Cisco routers and switches, I've been using the "source interface" command to explicitly tell the device what address to source the updates from. Normally, I point it to a loopback interface. This makes looking at logs pretty easy when DNS resolves the loopback address to the device name.

So for example:

ip flow-export source Loopback0
logging source-interface Loopback0
snmp-server trap-source Loopback0
snmp-server source-interface informs Loopback0

In most cases, we'll even use "update-source LoopbackX" for iBGP neighbors.

This makes looking at a Syslog and SNMP Trap aggregator easy. As long as they resolve addresses to names, I see content like:

Router1  Informational  Local7  Interface FastEthernet0/0 up
SwitchA  Emergency      Local6  Power supply 1 down  

Instead of:

10.254.254.1  Informational  Local7  Interface FastEthernet0/0 up
10.254.254.2  Emergency      Local6  Power supply 1 down  

Now that we've shown why this is good practice, I'll also add that we track nightly TFTP backups of configurations in TFTP logs and the same principle applies. So we use the 'ip tftp source-interface Loopback0' command. Notice however that all previous commands don't start with 'ip', the TFTP 'source-interface' command does. Big deal? With IPv6 it turns out ... YES, it is.

Granted the backup routine tested connected to the devices via IPv4 and requested a TFTP backup via SNMP to the IPv4 address of the TFTP server - so we didn't lose a night's worth of backups and wake up to an error log. The benefits of testing first! However, with IPv6 enabled and an IPv6 address on the Loopback0 interface, IPv6 TFTP should work. And in the test, it didn't.

Here's the relevant configuration:

ip tftp source-interface Loopback0

interface Loopback0
 ip address 10.254.254.1 255.255.255.255
 ipv6 address 2001:DB8:AFE:FE00::1/128
 ipv6 enable

interface FastEthernet2/0
 description To TFTP Server
 ip address 192.168.100.1 255.255.255.0
 ipv6 address 2001:DB8:192:168::1/64
 ipv6 enable

The TFTP server in the test lives at:

192.168.100.254
2001:db8:192:168::254

Again, IPv4 TFTP worked as expected. The Loopback0 address (10.254.254.1) shows in the TFTP logs. But with IPv6, something strange happened:

R1#copy run tftp
Address or name of remote host []? 2001:db8:192:168::254
Destination filename [r1-confg]?
.....
%Error opening tftp://2001:db8:192:168::254/r1-confg (Timed out)
R1#

And the resultant TFTP server log shows:

TFTP# crapps.pl -S tftpd -6
Starting MODE       -> TFTP Server
Listening on        -> [::]:69 (udp)
TFTP Root directory -> .

afe:fe01::  62506  WRQ  OCTET  r1-confg  STARTED
afe:fe01::  62506  WRQ  OCTET  r1-confg  STARTED
afe:fe01::  62506  WRQ  OCTET  r1-confg  File './r1-confg' already exists
afe:fe01::  62506  WRQ  OCTET  r1-confg  Timeout occurred on DATA packet 1
...

Who the heck is "afe:fe01::"? My Loopback0 IPv6 address is "2001:db8:afe:fe00::1". True, but my Loopback0 IPv4 address is "10.254.254.1", or in hex used directly as an IPv6 address is "afe:fe01::". I remember a saying about computers doing exactly what you tell them to. The Cisco router is sourcing the TFTP from the 'ip tftp source-interface Loopback0' - 'ip' as in "IPv4".

So is IPv6 TFTP broken? No, you just need to remove the 'source-interface' command:

R1#config term
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#no ip tftp source-interface Loopback0
R1(config)#end
R1#copy run tftp
Address or name of remote host []? 2001:db8:192:168::254
Destination filename [r1-confg]?
!!
8774 bytes copied in 5.540 secs (1584 bytes/sec)
R1#

And confirmed on the TFTP server:

TFTP# crapps.pl -S tftpd -6
Starting MODE       -> TFTP Server
Listening on        -> [::]:69 (udp)
TFTP Root directory -> .

2001:db8:192:168::1  52000  WRQ  OCTET  r1-confg  STARTED
2001:db8:192:168::1  52000  WRQ  OCTET  r1-confg  SUCCESS [8774 bytes]

Much better. Of course now the source is the interface of the router that the TFTP traverses, in this case, FastEthernet2/0. This will also be the same for IPv4 TFTP now.

Nightly TFTP backups are one of those automated tasks we set and forget. Sure there are monitors in place to catch changes and email alerts, but how often does something go wrong? Imagine waking up to an error log an no backups. Not then end of the world, but certainly not something you want to see before your first cup of coffee. Test and test again, especially when incorporating IPv6.

Friday, December 07, 2012

Testing DHCPv6

I've been doing some research into DHCPv6 for a client and beyond the talk and text, I needed some hands on testing. I can create a DHCPv6 server on a Cisco router in GNS3, but who knew creating a DHCPv6 client would be so troublesome.

I suppose I could have just used my Windows 7 x64 host and connected to the GNS3 simulation on a loopback interface. I've done this before, but I was looking for a way to do this in the simulation. I took a look at the Tiny Core 3.8.2 linux Qemu image available on the GNS3 appliances page and gave it a go. Unfortunately, Tiny Core uses 'udhcpc' as the DHCP client and it only supports IPv4. Partial success.

I had a look at Tiny Core and found that you can load packages and one package was the ISC DHCP package version 4.2.1 including client, server and relay. According to their website, 4.2.1 supports IPv6 so I thought I'd pursue.

The first step was to get the ISC DHCP package installed. Tiny Core comes with a package manager; however, you need to be online to use it and I hadn't played with the Qemu emulator (to run Tiny Core) outside of GNS3. To get network access, Qemu needs a TAP interface, which isn't available on Windows. I had to get one.

OpenVPN offers Windows software that comes with - among other things - a TAP interface driver. So simply download the latest Windows intstaller and run it. Luckily, it asks what components you'd like to install. I unchecked everything except for the Tunnel TAP interface driver. Once the install was completed, I had a new interface under Network and Sharing Center - Adapters, which I renamed to "TUN-TAP".

Simply select my physical NIC - in my case my wireless card - and the new TUN-TAP interface, right-click and select "Bridge Connections".

Armed with my new interface, I was able to launch Qemu and get Tiny Core online to add the proper packages:

C:\> qemu -hda linux-tinycore-3.8.2.img -net nic -net tap,ifname=TUN-TAP

Once loaded, I used the AppBrowser, pressed the "Connect" button and the available packages loaded. I used the search to look for "dhcp" and found "isc-dhcp.tcz". I selected "OnBoot" and pressed "Go". It installed the prerequisites and finished.

Next, I had to change Tiny Core to use 'dhclient' instead of 'udhcpc' and make the change permanent over reboots. First, I edited the "/etc/init.d/dhcp.sh" file. I commented out the line with 'udhcpc' and added two new lines after it:

/usr/local/sbin/dhclient    -sf /usr/local/sbin/dhclient-script $DEVICE >/dev/null 2>&1 &
/usr/local/sbin/dhclient -6 -sf /usr/local/sbin/dhclient-script $DEVICE >/dev/null 2>&1 &

That will load 'dhclient' (ISC DHCP client) instead of 'udhcpc' and it will do it for all interfaces and for both IPv4 and IPv6.

Finally, to make the change permanent, I edited the "/opt/.filetool.lst" file. I removed the line with "/sbin/dhclient" and replaced with:

/etc/init.d/dhcp.sh

and then ran 'filetool' and did a "Backup". Curiously, I got an error saying the backup failed, but examining the "/mnt/hda1/tce/mydata.tgz" file, I found the "/etc/init.d/dhcp.sh" file with my edits. So, I shutdown and restarted and hoped for the best.

It worked! I verified 'dhclient' was running instead of 'udhcpc':

tc@box:~$ ps -ef | grep dhc
 1562 root     /usr/local/sbin/dhclient -sf /usr/local/sbin/dhclient-script eth0
 1699 root     /usr/local/sbin/dhclient -6 -sf /usr/local/sbin/dhclient-script eth0
 1762 tc       grep dhc

The final test was to check DHCPv4 and DHCPv6 functionality in the GNS3 simulation. I had a 7200 series router configured as a DHCPv4 and DHCPv6 server and connected a Qemu host with the newly updated Tiny Core image. The host booted in the simulation and got both an IPv4 and IPv6 address. This was verified on the router by looking at:

R1>show ip dhcp binding
Bindings from all pools not associated with VRF:
IP address      Client-ID/          Lease expiration       Type
                Hardware address/
                User name
10.100.104.17   00ab.298c.3e00      Dec 07 2012 03:48 PM   Automatic
R1>show ipv6 dhcp binding
Client: FE80::2AB:29FF:FE8C:3E00
  DUID: 000100011855208300AB298C3E00
  Username : unassigned
  IA NA: IA ID 0x298C3E00, T1 43200, T2 69120
    Address: 2001:DB8:A64:6800:9D60:EF10:536A:28BF
            preferred lifetime 86400, valid lifetime 172800
            expires at Dec 09 2012 11:47 AM (172618 seconds)

The one thing to remember is that Qemu doesn't save any changes to the actual image file when in a GNS3 simulation. All changes are saved to a FLASH disk in the working directory. If that file or directory is removed, the Qemu host is back to defaults. I learned this the hard way the first time through. The answer is to load any packages and make any edits by running Qemu itself - as shown in the first command of this post - and then using the updated image in the GNS3 simulation.

NOTE: You can do the same for Micro Core linux by using the command line AppBroswer 'ab' and using the 'filetool.sh -b' command to commit the changes.

Tuesday, November 27, 2012

IPv6 over IPv4-only MPLS with 6to4

Last year, I researched, created and presented training on 6VPE technology for our internal consultants. Passing IPv6 routes and traffic over an IPv4-only MPLS network is a problem. 6VPE solves that problem from a carrier perspective allowing the MPLS carrier to provide dual-stack IPv4 and IPv6 at the LAN side interface of the customer edge devices.

But what if your MPLS provider has not rolled out IPv6 support?

I knew you could use tunnels to solve this problem from a client perspective. Further, configuring static tunnels in a full mesh over MPLS would be an awful management burden so automatic 6to4 tunnels could address that. However, I never pursued it further.

Recently, a question about this came up again and forced me to reconsider. Some research yielded Dynamic Routing Over 6to4 Automatic Tunnels which describes how to enable dynamic routing over 6to4 tunnels using BGP - specifically external BGP (eBGP). However, the article doesn't consider an MPLS backbone. I did some testing and it turns out it's not that hard to adapt this concept to an IPv4-only MPLS backbone.

Assume the following scenario:

  • MPLS provider offers IPv4-only MPLS VPN access for customers
  • Customer A wants IPv6 access
  • Customer A has many remote sites so solution must be scalable

Since Customer A wants IPv6 access and the provider doesn’t offer it, the first step is for Customer A to configure tunnel endpoints on each of the remote sites. Static tunnels such as 6in4 will require n(n - 1) tunnel endpoints – essentially an n^2 problem or management burden. Each new site almost exponentially increases the management burden.

The solution is to configure 6to4 tunnel endpoints on each remote site. 6to4 tunnels are dynamic so only a single tunnel endpoint is needed per remote site. Adding a new site now only adds 1 new tunnel interface – a linear increase.

To enable dynamic routing, the customer edge routers already use BGP to connect to the MPLS backbone. We can use the existing BGP configuration to enable internal (iBGP) sessions between the 6to4 addresses and advertise the IPv6 networks.

To begin, let's configure the 6to4 endpoints on each remote site:


ACE1
interface Tunnel2002
 ipv6 address 2002:a01:102::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

ACE2
interface Tunnel2002
 ipv6 address 2002:a01:106::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

ACE3
interface Tunnel2002
 ipv6 address 2002:a01:10a::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

At this point, the sites have reachability to the newly configured 6to4 addresses but not the IPv6 addresses on the LAN of each remote site. To enable reachability to those networks we need to enable routing.

The easiest way is to add some static routes pointing to the remote 6to4 address for the remote sites' IPv6 networks. For example, on ACE1, the static IPv6 routes to add for the four (4) IPv6 networks on ACE2 and the four (4) IPv6 networks on ACE3 are:

ipv6 route 2001:DB8:A64:6800::/54 2002:A01:106::
ipv6 route 2001:DB8:A64:6C00::/54 2002:A01:10A::

Of course, with static routing we've simply shifted the n^2 problem of tunnel endpoint management to static route management, which could actually be much worse if routes are not hierarchical like the /54 summaries above. Imagine managing several static routes per site on each remote router.

The best solution is dynamic routing and as the previous linked article described, an internal gateway routing protocol will not work as the 6to4 addresses are not on the same subnet. BGP solves this with explicit peering definitions and since the edge routers are already running BGP to the MPLS provider, we can use that configuration.

BGP peers will be configured to the 6to4 addresses so BGP routing traffic will be passed as over the 6to4 tunnels the same way data traffic is passed. We use iBGP since the customer edge routers are all in the same BGP Autonomous System. Finally, we offloaded the configuration burden of an iBGP full mesh by configuring ACE1 as a route reflector ACE2 and ACE3 as route reflector clients.


ACE1
router bgp 65100
 neighbor 2002:A01:106:: remote-as 65100
 neighbor 2002:A01:10A:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:106:: activate
  neighbor 2002:A01:106:: route-reflector-client
  neighbor 2002:A01:10A:: activate
  neighbor 2002:A01:10A:: route-reflector-client
  network 2001:DB8:A64:6400::/64
  network 2001:DB8:A64:6500::/64
  network 2001:DB8:A64:6600::/64
  network 2001:DB8:A64:6700::/64

ACE2
router bgp 65100
 neighbor 2002:A01:102:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:102:: activate
  network 2001:DB8:A64:6800::/64
  network 2001:DB8:A64:6900::/64
  network 2001:DB8:A64:6A00::/64
  network 2001:DB8:A64:6B00::/64

ACE3
router bgp 65100
 neighbor 2002:A01:102:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:102:: activate
  network 2001:DB8:A64:6C00::/64
  network 2001:DB8:A64:6D00::/64
  network 2001:DB8:A64:6E00::/64
  network 2001:DB8:A64:6F00::/64

Note that we've made no changes to the PE router - meaning the MPLS provider does not need to support IPv6 at all for this configuration to work. You will need to make sure the provider doesn't do any exotic filtering at the edge or in the MPLS backbone such as blocking IP protocol 41 (IPv6 in IPv4 encapsulation).

At this point, we can test the configuration with some BGP show commands and pings to test connectivity. Without the benefit of a live demo here, rest assured these commands produced the provided output:

ACE1#show bgp ipv6 unicast
BGP table version is 17, local router ID is 10.100.103.1

   Network          Next Hop        Metric LocPrf Weight Path
*> 2001:DB8:A64:6400::/64
                    ::                   0         32768 i
[...]
*>i2001:DB8:A64:6800::/64
                    2002:A01:106::       0    100      0 i
*>i2001:DB8:A64:6900::/64
                    2002:A01:106::       0    100      0 i
[...]
*>i2001:DB8:A64:6C00::/64
                    2002:A01:10A::       0    100      0 i
*>i2001:DB8:A64:6D00::/64
                    2002:A01:10A::       0    100      0 i

ACE1#ping ipv6 2001:db8:a64:6800::1 source 2001:db8:a64:6400::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:DB8:A64:6800::1, timeout is 2 seconds:
Packet sent with a source address of 2001:DB8:A64:6400::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 148/205/276 ms
ACE1#ping ipv6 2001:db8:a64:6c00::1 source 2001:db8:a64:6400::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:DB8:A64:6C00::1, timeout is 2 seconds:
Packet sent with a source address of 2001:DB8:A64:6400::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 128/167/204 ms

And there you have it! Dynamic routing of IPv6 over an IPv4-only MPLS network without the MPLS provider supporting IPv6.

 

Copyright © VinsWorld. All Rights Reserved.