GNS3 p2p connection from host to guest

Following GNS3 networking access scenario:

A dual homed guest (virtual machine) with two physical network interfaces, 2 NIC's: * eth0 IP point to point interface, connected to the real world (192.0.2.2/30) * eth1 IP network interface, connected to virtual world (10.1.1.2/24)

Using the 192.0.2.0/30 IP point to point interface, access the running HTTP webserver on GNS3 appliance (in that case it is cacti).The HTTP access works, using a HTTP browser, from the physical host where GNS3 is running, via IP interface, to the virtual GNS3 guest running in the GNS3 topology.

Solution 1 (not working)

Initial idea, this could be done via binding the HTTP (IP Port 80) service to hosts lo (linux IP loopback) interface:

  • physical host

    • IP 127.0.0.1
    • TCP port 1080
  • virtual GNS guest

    • 192.0.2.2
    • TCP Port 80

Accessing on the host the HTTP address:

http://127.0.0.1:1080/

Would be forwarded to the guest:

http://192.0.2.2:80/

And one could access the cacti application in the guest (VM) without explicit assign of a IP address.

This did not work that way. Maybe due to the dual home attached guest (VM) and it possibly received the http access on one physical interface, and for the way back out it look up its own routing table and forwarded it via the default route pointing to eth0. No TCP session has been established.

Here the problem was there was no point to point interface on the host, it has been lacking the 192.0.2.1/30 virtual interface.

Solution 2 (not working)

Creating a loopback1 interface on physical host

root # ip link add name lo1 type dummy

Add an IP address to virtual interface on host

root # ip add add 192.0.2.1/30 dev lo1

Set loopback1 interface in no shut

root # ip link def lo1 up

In GNS3 take a cloud device (I do not like this cloud device name, since it is a virtual IP interface) and connect it physically from this cloud to the guest physical interface eth0.

This did not work as well. Even if it is a IP point-to-point interface. No ICMP Echo vice versa. From host to guest, and from guest to host.

Solution 3 (working)

3rd solution, and this one a working one. On the host crate a tap interface (tap0 layer2 interface), assign an IP address, and bring it up:

root # ip tuntap add name tap0 mode tap
root # ip addr add 192.0.2.1/30 dev tap0
root # ip link set dev tap0 up

This is where the solution has been described (it is not entirely true it is a loopback interface), but this solution with tap interace is working
Connect host to GNS3 guest

In the GNS3 application take a cloud device and add it to the topology. Configure the settings of cloud device, choose to the register tap, dd the host created tap0 interface to it.

Cloud_tap_configuration

Finally connect the guests network interface f.e. eth0 to the cloud tap0 interface. IP point to point configuration has been created.

Verify the guest has a correct IP address on the eth0 interface:

gns3@cacti#ip addr add 192.0.2.2/30 dev eth0
gns3@cacti#ip link set dev eth0 up

Add a IP routing table entry for the IP network on the guest:

gns3@cacti#ip route add 192.0.2.0/30 via 192.0.2.2

GNS3-screenshot

This way a working IP point to point configuration from the physical host to the guest running in the GNS3 topology, has been configured.

IP access to the GNS3 topology

To access all topology routers via IP pointo-to-point link to test ansible/puppet/chef automation tools in the GNS3 topology.

Before heading further that in this kind of access from the host to the guest network, note that the point of attachment to the guest network plays a major role. Also the transfer network used 192.0.2.0/30 has to be routed in your GNS topology.

Change the link from the cloud to a IP router in that case R1.

In the topology is assumed a dynamical routing protocol is running RIP/OSPF/IS-IS/EIGRP/BGP. In this case OSPF is running at R1-R3.

Adjust the interface G1/0 IP configuration R1

conf t
!
interface Gi1/0
 ip address 192.0.2.2 255.255.255.252
 ip ospf 1 area 0
 no shut
end
wr

Add a IP route on the host to the guest network via IP interface tun0

root # ip route add 10.0.0.0/8 via 192.0.2.2

The IP network used in the GNS3 topology 10.0.0.0/8 is known to the host via the 192.0.2.1 tap0, IP point-to-point interface. The host network is 192.168.178.0/24 in the example.

root # ip route

default via 192.168.178.1 dev eth0 proto dhcp src 192.168.178.101 metric 3 192.168.178.0/24 dev eth0 proto dhcp scope link src 192.168.178.101 metric 3 10.0.0.0/8 via 192.0.2.2 dev tap0 127.0.0.0/8 via 127.0.0.1 dev lo 192.0.2.0/30 dev tap0 proto kernel scope link src 192.0.2.1

IP routed access from host to guest network. Without using any IP-NAT crippled solutions. Pure IP routing.

Convert appliance suffix to QEMU

Convert guest suffix from VMWare to QEMU:

user % qemu-img convert -c -p -O qcow2 vmname.vdmk vmname.qcow2

This works for the .ova too:

user % qemu-img convert -c -p -O qcow2 vmname.ova vmname.qcow2

And for the .vdi suffix as well:

user % qemu-img convert -c -p -O qcow2 vmname.vdi vmname.qcow2
Adding serial console support to linux

Howto setup serial console access on a linux host. It works the same way on bare metal servers as on virtual machines. In this particular setup there a debian installation is used with addition to QEMU. I needed serial console access to this virutal machine as it was a headless server and it is easier to use a terminal like XTerm instead of a pop up window from the virtualization application (here QEMU).

Start the the guest (virtual machine) with following command:

user % qemu-system-i386 -boot c -hda cacti.qcow2

Login to the guest. If using GRUB legacy edit following file

user $ nano /boot/grub/menu.lst

Add a console entry (the baud rate can be 9600,19200,38400 and even higher) I personally prefer 115200 baud if configuring linux hosts. 9600 is rather slow.

📄 File /boot/grub/menu.lst

title Debian GNU/Linux 2.6.42 root (hd0,0) kernel /boot/vmlinuz-2.6.42 ro console=ttyS0,115200 earlyprint=serial,ttyS0,115200 initrd /boot/initrd.img-2.6.32-5-486

Edit the file /etc/inittab and add following entry if using for debian:

📄 File /etc/inittab

... T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100 ...

Then take sure UART serial ports is listed in /etc/securetty

ttyS0

Add username and password to the file /etc/issue

Debian GNU/Linux 3.1 \n \l

Systemusers:    root:cacti

Here the procedure explained for Linux TinyCore. Tinycore uses SYSLINUX as boot manager edit /boot/extlinux/extlinux.conf and add following console entry:

DEFAULT core
LABEL core
KERNEL /boot/vmlinuz console=ttyS0,115200n8
APPEND initrd=/boot/core.gz quiet

Add following line to the /etc/inittab file:

    ttyS0::respawn:/sbin/getty 115200 ttyS0

Then take sure UART serial ports is likset in /etc/securetty

ttyS0

Document username and password in the file /etc/issue

Login to Core Linux

Username "tc", password is not set

The last step is optional.

The procedure explaing form TinyCore has been taken form Radovans Brezular blog. The article linked is really worth reading especially if building a remastered tinycore for own purposes. Thank you Radovan.

Run cron in tinycore

To activate cron in TinyCore use following steps to set it up:

Add following entry to /opt/bootlocal.sh to startup cron automatically after each boot

crond -L /dev/null 2>&1

Using crontab -e as tc user add following crontab entry:

SHELL=/bin/sh
PATH=/usr/sbin:/usr/bin

# run a script each minute
# use absolute paths to point to scripts
* * * * * sh /home/tc/bin

Add the crontabs to .filetool.sh file to be able to backup crontabs:

echo var/spool/cron >> /opt/.filetool.lst

Run the backup script to backup manually (it is better to be safe then sorry):

filetool.sh -d
filetool.sh -b

Reboot the TinyCore guest

After the reboot verify the crontabs have been restored from backup running:

crontab -l
ICMPv6 traffic generators

Last days I have been working on a interesting project, a part of this project covered generating traffic for IPv4 and IPv6. The protocol used for this is ICMP and ICMPv6. I have chosen a very naive approach and belived and thought that can be done in no time. It's a no brainer.

Since my favourite tool of choice is CLI, my first thought has been hey I know a cool software which I know since over 1 decade let's take nmap.

Nmap ships a tool named nping I have written a simple script for generating ICMP traffic each for each minute:

#!/bin/sh
# generate random integer between 20-500 including both for nping
COUNT=$(( RANDOM % (500 - 20 + 1 ) + 20 ))

# generate random integer between 64-1400 including both
PAYLOAD=$(( RANDOM % (1472 - 64 + 1 ) + 64 ))

# ping the IPv4 target
    nping --icmp --df --delay 100ms 1.1.1.1 -c $COUNT --data-length $PAYLOAD -H

That was an easy exercise, now let's copy that and do that same for ICMPv6. Now to the interesting part. Here is a easy output from a linux host command line

user % nping -6 --icmp fc00::1

 
Starting Nping 0.6.40 ( http://nmap.org/nping ) at 2017-07-18 15:41 UTC Error opening capture device eth0 --> Error compiling our pcap filter: expression rejects all packets

There is not much to explain about the upper command line it says:

nping using the IPv6 Protocol ,and ICMP the host FC00::1

Something basic had to be wrong. Now let's read the manual about IPv6 and ICMP echo types. RFC4443 Section 4.1. It says:

4.1.  Echo Request Message

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Identifier          |        Sequence Number        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Data ...
+-+-+-+-+-

IPv6 Fields:

Destination Address

Any legal IPv6 address.

ICMPv6 Fields:

Type           128

Code           0

Identifier     An identifier to aid in matching Echo Replies
                  to this Echo Request.  May be zero.

Setting explicit icmp-type and icmp-code arguments for this ICMP request should be enough:

user % nping -6 --icmp icmp-type 128 --icmp-code 0 fc00::1

  Failed to resolve given IPv6 hostname/IP: icmp-type. Note that you can't use '/mask' or '[1-4,7,100-]' style ranges for IPv6. Error code -3: Temporary failure in name resolution Execution aborted. Nping needs at least one valid target to operate.

This error says it does not recognize a valid IPv6 address. The careful reader will see what this error says. It says it uses ICMP and the RFC says ICMPv6. Hey, Let's try with using the current version:

user % nping -6 --icmp fc00::1

  Starting Nping 0.7.50 ( https://nmap.org/nping ) at 2017-07-19 15:24 CEST libnsock nsock_pcap_set_filter(): Error compiling pcap filter: expression rejects all packets Error opening capture device eth0

Same error with the newest version of Nping. What I have been doing wrong?

A quick visit in the IRC channel and a research of the bugtracker brought the something to light I would not belive it would be true:

FIXME and TODO comments in source files

...
libnetutil/PacketParser.cc:1580:               * TODO: Implement these ICMPv6 types. */
...

ICMPv6 is not implemented in in nping.

Trying out other tools following things have been discovered,

  • ostinato IPv6 extended headers support are not implemented yet.
  • hping IPv6 support not implemented at all.

The only tools that seems to support ICMPv6 by now and are suited for the command line:

  • scapy. Now scapy tool comes with the heavy baggage of python
  • fping Another tool that also supports ICMPv6 fully.
Linux guests for GNS3

Have you ever wondered if there are even more suckless linux guests for the GNS3 network simulator? Following guests can be considered the most lightweight, and the just the right guests for your GNS3 network topology:

Distribution Alpine Linux TinyCore SliTaz
Download ISO Alpine Linux TinyCore SliTaz
Repositry Index Alpine Linux Packages TinyCore 8 Repository SliTaz Packages
Root size 40 MB 12 MB 60 MB
Installation time ~ 1 Min. 10 Min. 10 Min
ttyS0 available yes manual configuration manual configuration
Documentation best good fair
Boottime using QEMU 8 sec. 3 Sec. 15 Sec.
Available packages/builds
quagga yes no no
tac_plus no no yes
syslog server yes no no
cron yes yes yes
dhcp server yes yes no
scapy yes no no
wireshark yes yes yes
fping yes no yes
IPv6 out of the box yes no no
nmap yes yes yes

Note: Once a guest system has been installed it is hard making major upgrades. f.e. from 1.0 to 2.0 The only rolling release has been found on Slitaz.

My personal favourite is TinyCore it is the smallest guest, but it needs manual adjustments, this is the smallest and most suckless linux appliance I have been working with. It is lacking some packages I often work with. Quagga and tac_plus are not available in official repository and tac_plus and a syslog server.

For quick installation with very good documentation Alpinelinux is a good choice. But the packages are somehow big and the root file system grows very fast with each package installed. So the virtual disk needs to reflect that. Apart from that this is a nice linux guest, I have been surprised how quickly it has been installed and how good the documentation is. Without any clue it has been installed and configured very fast. I have never used it before.

Slitaz is a nice and suckless desktop distribution with quite actual packages. Using version 4.0, which is now a bit outdated, there was a base installation with only 40 packages occupying maximal 50 MB. This installation mode does not exist any more using the rolling release. While using rolling release now to install the guest it is needed to install the core versions (it means desktop version) and strip down all all unnecessary packages to around 50 installed from initially around 250. That is very time consuming. However SliTaz is the only lightweight distribution that makes it possible to build own packages form source, similar to gentoo or sourcemage. But is is not good suited for a quick and suckless guest solution in a networking testing environment. I like the build your own packages part here.

MTU size on Cisco Nexus 5000

In most cases to there is no need at all to reconfigure the system MTU size of a layer2 or layer3 PDU. The size of 1500 byte is the default. If configuring a MTU one usually does it on physical interfaces or logical interfaces. Like Ethernet or Interface VLAN if dealing with a cisco component. But a Nexus 5000 , and a Nexus 7000 series switch running NX-OS operating system will use some Jedi tricks if you do not pay attention:

Here the proof run on a n5k component:

n5k-switch# sh int e1/1 | i MTU
  MTU 1500 bytes, BW 10000000 Kbit, DLY 10 usec
n5k-switch# sh int vlan1 | i MTU
  MTU 1500 bytes, BW 1000000 Kbit, DLY 10 usec

It says clearly "My MTU is on physical and logical interfaces always 1500 bytes"

The component documentation suggests following:

!--- You can enable the Jumbo MTU 
!--- for the whole switch by setting the MTU 
!--- to its maximum size (9216 bytes) in 
!--- the policy map for the default 
!--- Ethernet system class (class-default).

n5k-switch#configure terminal
n5k-switch(config)#policy-map type network-qos jumbo
n5k-switch(config-pmap-nq)#class type network-qos class-default
n5k-switch(config-pmap-c-nq)#mtu 9216
n5k-switch(config-pmap-c-nq)#exit
n5k-switch(config-pmap-nq)#exit
n5k-switch(config)#system qos
n5k-switch(config-sys-qos)#service-policy type network-qos jumbo

Below the method described on how to verify a MTU size a nexus switch is using really:

n5k-switch# sh queuing int e1/1 | i MTU
    q-size: 469760, HW MTU: 9216 (9216 configured)
n5k-switch# sh int e1/1 | i MTU
  MTU 1500 bytes, BW 10000000 Kbit, DLY 10 usec
Interactive color and font chooser

...for the terminal! People that work often/mostly with editors and terminals have special needs for fonts, and sometimes colors to highlight the used syntax. There is one website that helps picking the right (mono) font and shows the chosen entries:

And there is a other website to choose the right color setting for the terminal and to generate the correct syntax for the .Xdefaults file: