Skip to content

Instantly share code, notes, and snippets.

@tsettle
Last active April 25, 2022 17:17
Show Gist options
  • Save tsettle/6fd9ba38836ab2855dddc5c524cab6d7 to your computer and use it in GitHub Desktop.
Save tsettle/6fd9ba38836ab2855dddc5c524cab6d7 to your computer and use it in GitHub Desktop.
GNS3 Server on Debian

GNS3 Server on Debian

Generally speaking, this was a rather annoying process to figure out, but between the official GNS3 documentation and more than a few Google searches for other information, I finally managed to figure it all out. I hope someone can tell me an easier way to do this, but for now, here's how I did it.

Install Debian Server

Not much to say here... I did a vanilla install

Bridge Networking

This was actually the last things I figured out, and it took a bit of effort. I'm not saying that Debian's network configuration is difficult, but I'm a reluctant Linux user at best and prefer RHEL based distributions, simply because that's what I've been using for the last 25 years.

Anyways, once I got all the bits for GNS3 up and running, I found that transferring files into the appliances was painfully slow. Turns out this is due to the way GNS3 interfaces with the host. The solution is to move the physical interface into a bridge, then use the bridge interface to connect your lab to the outside world.

Setting up the bridge was relatively easy, but then we have to deal with the firewall. Specifically, we need to prevent the bridge from forwarding packets to netfilter.

To get started, install bridge-utils:

$ apt install bridge-utils

Then we need to load the kernel module and apply a few sysctl variables:

$ modprobe br_netfilter
$ sysctl net.bridge.bridge-nf-call-arptables=0
$ sysctl net.bridge.bridge-nf-call-ip6tables=0
$ sysctl net.bridge.bridge-nf-call-iptables=0

Next, let's make it permanent by creating a file /etc/sysctl.d/bridge.conf:

net.bridge.bridge-nf-call-arptables=0
net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0

Normally, this should be enough, but the sysctl.conf is processed before networking is started (and the bridge modules are loaded), so these directives are ignored. To get around this, we need to force load the module at startup.

Create a file /etc/modules-load.d/bridge.conf with a single line:

br_netfilter

With that sorted out, we can configure our network. There are many ways to do this, but for my purposes, it's as easy as editing /etc/network/interfaces. You probably want to make a backup of this file before you get started.

# Automatically load our interfaces
auto lo0 eth0 br0

# Loopback interface
iface lo0 inet loopback

# iface eth0 inet dhcp
iface eth0 inet manual

iface br0 inet static
  bridge_ports eth0
  address 192.168.0.18
  netmask 255.255.255.0
  gateway 192.168.0.1
  dns-domain mynet.local
  dns-nameservers 8.8.8.8,8.8.4.4

You should be able to apply these changes by issuing the command systemctl restart networking, but you may want to go ahead and reboot to ensure that the changes are applied at startup. If you're anything like me, you'll leave your server running for weeks or months without rebooting, then you'll be stuck figuring some of this stuff out all over again.

Installing the GNS server

Honestly, the docs at https://docs.gns3.com/docs/getting-started/installation/linux/ were more than adequate, however, I just want the server, so we'll leave a few things out.

Let's start by installing some requisite packages.

$ apt install -y \
  python3-pip python3-pyqt5 python3-pyqt5.qtsvg python3-pyqt5.qtwebsockets \
  qemu qemu-kvm qemu-utils libvirt-clients libvirt-daemon-system virtinst \
  apt-transport-https ca-certificates curl gnupg2 software-properties-common

With that out of the way, we can get on with installing everything else.

GNS3 Server

$ pip3 install gns3-server

Docker (apparently this is optional?)

$ curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
$ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable edge"
$ apt update
$ apt install -y docker-ce

Add the following lines to your /etc/apt/sources.list:

deb http://ppa.launchpad.net/gns3/ppa/ubuntu bionic main
deb-src http://ppa.launchpad.net/gns3/ppa/ubuntu bionic main

Get the GPG key

$ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F88F6D313016330404F710FC9A2FD067A2E3EF7B

Install dynamips and ubridge

$ apt-get update
$ apt install dynamips ubridge

Apparently, installing other things from this repo is bad, so comment these lines in /etc/apt/sources.list:

#deb http://ppa.launchpad.net/gns3/ppa/ubuntu bionic main
#deb-src http://ppa.launchpad.net/gns3/ppa/ubuntu bionic main

Now we need to add a user to run the server

$ useradd -m -d /opt/gns3 gns3
$ for group in kvm libvirt docker ubridge; do
    usermod -aG $group gns3
  done

Test server funcionality

root@gns3:~# su gns3 -c gns3server
No configuration file could be found or read
2022-04-25 10:52:55 INFO run.py:219 GNS3 server version 2.2.31
2022-04-25 10:52:55 INFO run.py:221 Copyright (c) 2007-2022 GNS3 Technologies Inc.
2022-04-25 10:52:55 INFO run.py:243 Running with Python 3.9.2 and has PID 23800
2022-04-25 10:52:55 INFO run.py:79 Current locale is en_US.UTF-8
2022-04-25 10:52:55 INFO web_server.py:318 Starting server on 0.0.0.0:3080
2022-04-25 10:52:55 INFO __init__.py:63 Load controller configuration file /opt/gns3/.config/GNS3/2.2/gns3_controller.conf
2022-04-25 10:52:55 INFO __init__.py:67 Controller is starting
2022-04-25 10:52:55 INFO compute.py:64 Create compute local
2022-04-25 10:52:55 INFO compute.py:364 Connecting to compute 'local'
2022-04-25 10:52:55 INFO web_log.py:206 127.0.0.1 [25/Apr/2022:14:52:55 +0000] "GET /v2/compute/capabilities HTTP/1.1" 200 552 "-" "Python/3.9 aiohttp/3.7.4.post0"
2022-04-25 10:52:55 INFO notification_handler.py:50 New client has connected to compute WebSocket
2022-04-25 10:52:55 INFO compute.py:434 Connected to compute 'local' WebSocket 'http://127.0.0.1:3080/v2/compute/notifications/ws'
^C
Session terminated, killing shell... ...killed.

You can send an interrupt (CTRL-C) to kill it, or if you're so inclined, you can do some more extensive testing from your client to verify that things are functioning as expected.

When you're satisfied the server is doing what it's supposed to do, we need to create a unit file in order to run this as a service.

/lib/systemd/system/gns3.service

[Unit]
Description=GNS3 server
Wants=network-online.target
After=network.target network-online.target

[Service]
User=gns3
Group=gns3
ExecStart=/usr/bin/gns3server

[Install]
WantedBy=multi-user.target

Disaster

So, I went through all that, only to have GNS3 crash on me as soon as I fired up my first QEMU appliance (MikroTik CHR).

Back to the drawing board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment