Recently I started to play a little bit with GNS3. I managed quite easy to create a virtual cisco router on GNS3 and connect from console to that router and do the initial basic setup of the router. And then it hit me! Is there any way to make the virtual cisco router inside GNS to connect to the internet? YES. Of course.
My configuration is like this:
– internet router (ADSL) which has a public IP address (WAN)
– DHCP for the local network (both cable & wireless)
– a macbook pro laptop which runs Mac OSX Yosemite, latest version
– a cisco operating system image (in my case I am using Cisco 3725 image) from here
– TunTap for Mac OSX (you need to create a virtual tap device in order to communicate with the cisco router on your local network)
I will summarize quickly how to do it:
– download and install TunTap for Mac OSX (you wont be able to see the tap0 device until you start GNS and connect the router with the cloud)
– install GNS3 for Mac OSX; open Terminal and issue the following command (to start GNS3 as root): sudo /Applications/GNS3.app/Contents/MacOS/GNS3; minimize Terminal window
– in GNS, go to Preferences, Dynamips, IOS Routers, Add New (select the downloaded cisco image). Then drag your new router in the GNS
– browse End Devices and drag a Cloud on GNS; Right click on Cloud icon and select Configure; Select the cloud, go to NIO:Tap and add manually /dev/tap0
– add a link between your cisco router (interface fa0/0 or FastEthernet 0/0) and your cloud (interface tap0)
– select cisco router and click start in order to make the router boot
So connect to your router by console (right click on router, Console). Do the basic setting of your router. After that, do enable, enter your enable password
1 2 3 4 5 6 7 8 | cisco# conf t cisco(config)# int fa0/0 cisco(config-if)#ip address 100.100.100.254 255.255.255.0 cisco(config)# ip name-server 8.8.8.8 cisco(config)# ip domain-lookup cisco(config)# ip forward-protocol nd cisco(config)# ip route 0.0.0.0 0.0.0.0 100.100.100.1 cisco(config)# ip route x.x.x.x 255.255.255.255 192.168.1.1 |
x.x.x.x – is your public internet IP (from the internet router). 192.168.1.1 is my internet router local ip address and 100.100.100.1 is the ip that we will assign to the tap0 interface.
Now we go to the mac part. Since Yosemite lacks natd binary and ipfw is no longer supported, we have to use pfctl instead for forwarding and NAT.
Open Terminal on Mac, issue sudo su, enter your password and become root.
create the following file (pfrule)
sh-3.2# cat > pfrule
1 2 3 4 | nat on en1 from tap0:network to any -> (en1) pass inet proto icmp all pass in on tap0 proto udp from any to any port domain keep state pass quick on en1 proto udp from any to any port domain keep state |
Save the file. en1 is my wireless adapter interface (the one I am using to connect). tap0 is the interface used by the Cloud inside GNS to connect with the virtual cisco router.
Now create another file (nat.sh)
sh-3.2# cat > nat.sh
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash #configure tap0 ifconfig tap0 100.100.100.1 netmask 255.255.255.0 up #enable packet forwarding sudo sysctl -w net.inet.ip.forwarding=1 sudo sysctl -w net.inet.ip.fw.enable=1 #configure & start nat pfctl -d pfctl -F all pfctl -f ./pfrule -e |
sh-3.2# sh nat.sh (to execute the above script)
We assing the tap0 interface the ip 100.100.100.1 netmask 255.255.255.0 (remember, your cisco router has 100.100.100.254). At this point we are able to ping the router from your mac and vice versa. Then we enable forwading on your MacBook making it to act as a router. Then we disable all pfctl rules and then load the rules from the pfrule file we have created earlier and enable pfctl.
And that’s it! Now you can ping google from your cisco router!
followed your instructions. i can ping the inside of my wan router and the outside of my wan router. i cannot ping beyond that. thoughts? i disable my router’s firewall.
What exactly is not working… Can you be more specific please?
Hi, your directions are good I was able to get everything working per your directions. However I excluded the following from the configuration. As I didn’t understand the purpose of it:
cisco(config)# ip route x.x.x.x 255.255.255.255 192.168.1.1
All works out to the Internet.
Thanks, can you make sure you really need that last part?
Also not sure that the NAT is necessary…?
If you add a route on your router and point it at your laptop. You take care of the reachability problems. The reason why NAT may not be good is because it causes issues when running with VPN labs etc.
In my case I added a route in my real router and pointed the 100.100.100.0/24 network at my Mac. This allowed everything to work without the need for NAT.
Thx for sharing your workaround!
@s3cf0_ol: Thank you for the tip. Indeed, there were some issues with the NAT. I did what you said and it works way better like this. The purpose of NAT was to be able to reach my Cisco router (from GNS) from the internet cause I wanted to play a little bit and be able to use the Cisco VPN client to connect through VPN (just playing around to learn some cisco commands and configurations).
Regarding ip route x.x.x.x 255.255.255.255 192.168.1.1, I think you can skip it. Initially I read some posts from internet and someone was saying that route is mandatory, but in the end I tookl it out and everything works the same way.
Thank you for reading my blog!
Thank you for this perfect manual. One week ago I did all as in this guideline and it worked perfectly, but today I again tried connect my lab to internet and it was unsuccessful. I didn’t change nat.sh and pfrule files, tap0 interface creating normally. I don’t know that can be changed in my system, but now I only can ping tap0 interface from my GNS3 router.
1 *
100.1.1.1 20 msec 32 msec
2 * * *
3 *
lo0: flags=8049 mtu 16384
options=3
inet6 ::1 prefixlen 128
inet 127.0.0.1 netmask 0xff000000
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=1
gif0: flags=8010 mtu 1280
stf0: flags=0 mtu 1280
en0: flags=8863 mtu 1500
ether 7c:d1:c3:ed:5e:5d
inet6 fe80::7ed1:c3ff:feed:5e5d%en0 prefixlen 64 scopeid 0x4
inet 192.168.1.105 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=1
media: autoselect
status: active
en1: flags=8963 mtu 1500
options=60
ether 32:00:16:be:0e:00
media: autoselect
status: inactive
p2p0: flags=8843 mtu 2304
ether 0e:d1:c3:ed:5e:5d
media: autoselect
status: inactive
awdl0: flags=8843 mtu 1452
ether 1a:6e:fc:58:20:5d
inet6 fe80::186e:fcff:fe58:205d%awdl0 prefixlen 64 scopeid 0x7
nd6 options=1
media: autoselect
status: active
bridge0: flags=8822 mtu 1500
options=63
ether 7e:d1:c3:de:b8:00
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en1 flags=3
ifmaxaddr 0 port 5 priority 0 path cost 0
media:
status: inactive
vboxnet0: flags=8843 mtu 1500
ether 0a:00:27:00:00:00
inet 192.168.56.1 netmask 0xffffff00 broadcast 192.168.56.255
tap0: flags=8843 mtu 1500
ether 1a:35:6c:70:59:b1
inet 100.1.1.1 netmask 0xffffff00 broadcast 100.1.1.255
media: autoselect
status: active
open (pid 880)
pfrule
nat on en0 from tap0:network to any -> (en0)
pass inet proto icmp all
pass in on tap0 proto udp from any to any port domain keep state
pass quick on en0 proto udp from any to any port domain keep state
nat.sh
#!/bin/bash
#configure tap0
ifconfig tap0 100.1.1.1 netmask 255.255.255.0 up
#enable packet forwarding
sudo sysctl -w net.inet.ip.forwarding=1
sudo sysctl -w net.inet.ip.fw.enable=1
#configure & start nat
pfctl -d
pfctl -F all
Sorry, I found my mistake.
I do not know how, but I deleted last string in nat.sh script.
I move it back and everything became work normally.
I am glad that you have figured it out. Thank you for reading my blog.
Hi there,
Thank you very much. It worked perfectly fine. Your blog helped a lot.
No problem. I am happy that I could help you.