GNS3 Installation and Configuration

GNS3 can run on Windows, Linux or MacOS, however for large scale network simulations running it on a dedicated server machine (typically Linux) is recommended. The deployment of this can be difficult due to limited documentation, the following provides a guide for the installation of GNS3 on a dedicated Linux server, ideally with as much CPU and memory as you have available (depending on what switch hardware you seek to virtualise). 

Running on Linux uses QEMU/KVM hypervisior layer meaning that your switch/firewall/router images run emulated at high performance due to the direct access to the Kernel. When using Windows or MacOS you need to run these on a GNS3 VM which adds another layer between your lab and the host running it.

The following was built and verified with Ubuntu Linux 24.04 LTS on a Virtual Machine running on VMware ESXi 8, the VM is sized as 8 vCPU, 128GB RAM and 1TB Hard Disk. You could of course run this straight onto bare metal, if you have suitable hardware available to.

The Virtual Machine requires that the “Expose hardware extended virtualistion to the guest OS” enabled to ensure that you have nested virtualisation capability.

The guide assumes you have a working Ubuntu Linux 24.04 LTS instance running, which has network and Internet connectivity. It is recommended to have created a user to install and run GNS3 under. In my case I have a user account with sudo privileges that is used to install and run the GNS3 server.

Step 1 – Prepare and Verify

We’ll ensure we have the basics in place so we are prepared to build the server.

1.1. Check Hardware Virtualisation

Firstly we’ll check that the hardware virtualisation is exposed with:

grep -c -E 'vmx|svm' /proc/cpuinfo

Any result greater than 0 shows you have hardware virtualisation capability within the Linux instance.

1.2. Update System and Enable Universe Respository

GNS3 needs the Ubuntu universe respository, so we’ll configure APT and perform updates so the OS is up to date.

sudo apt update && sudo apt upgrade -y
sudo add-apt-repository -y universe

Now we need to add what is required for handling external PPAs (Personal Package Archive), so we can then access the GNS3 PPA to get GNS3 server.

sudo apt install -y software-properties-common curl

1.3. Enable Sudoers and Set Timezone

We want to be able to easily swap to sudo without having to retype passwords etc. so let’s just add using “visudo” our user account to the sudoers file. Add the following under the groups section:

cit-gns3-01-admin       ALL=(ALL:ALL) NOPASSWD: ALL

We need to set the timezone, if not already done:

sudo timedatectl set-timezone Europe/London

1.4. Add GNS3 PPA to APT Repository Configuration

GNS3 is published via the PPA for major releases of Ubuntu, we’ll add it and update APT.

sudo add-apt-repository -y ppa:gns3/ppa
sudo apt update

We check where it is coming from, which appears to be good:

$ apt-cache policy gns3-server
gns3-server:
  Installed: 2.2.61~noble1
  Candidate: 2.2.61~noble1
  Version table:
 *** 2.2.61~noble1 500
        500 https://ppa.launchpadcontent.net/gns3/ppa/ubuntu noble/main amd64 Packages
        100 /var/lib/dpkg/status

Step 2 – Install GNS3 Server

Now we can actually install GNS3, its recommended to be logged on as the user you wish to be running the GNS3 Server under. When creating this I had signficant problems when attempting to install under one user and run under another

2.1. – Install GNS3 Server

We’ll install GNS3 Server:

sudo apt install -y --no-install-recommends gns3-server

When prompted, allow non-superusers to be able to run GNS3, i.e. say “yes” to this.

Once GNS3 is installed check its available:

$ gns3server --version
2.2.61

2.2. – Install Libvirt and IOU Support

Install Libvirt and IOU Support (needed for Cisco images):

sudo apt install libvirt-daemon-system libvirt-clients bridge-utils ubridge dnsmasq

Enable and start the libvirtd service:

sudo systemctl enable --now libvirtd

Ensure the default network interface virbr0 is running:

sudo virsh net-start default

Check:

sudo virsh net-list --all

You should see a network named default. If it is inactive, start it and enable automatic startup:

sudo virsh net-autostart default

Enable IOU Support:

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install gns3-iou

2.3. Install Docker CE

Remove any old versions:

sudo apt remove docker docker-engine docker.io
sudo snap remove docker

Install the following packages:

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

Import the official Docker GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the appropriate repo:

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(. /etc/os-release && echo $VERSION_CODENAME) stable"

Install Docker-CE:

sudo apt update
sudo apt install docker-ce -y

2.4. Fix Permissions

We need to ensure that our current user, i.e. the one used to run the GNS3 Server will have the correct permissions, we do this with:

ubridge libvirt kvm wireshark docker

sudo usermod -aG ubridge,libvirt,kvm,wireshark,docker $(whoami)

Restart your user session by logging out and back in, or restarting the system.

Verify it is all in place as expected:

id | tr ',' '\n' | grep -E 'kvm|libvirt|ubridge'

Check the ubridge with:

getcap /usr/bin/ubridge

Its expected to get the following:

/usr/bin/ubridge cap_net_admin,cap_net_raw=eip

2.5. Install Dynamips

Although I won’t be running any Cisco images, Dynamips is worth installing so you can use the basic “Ethernet Switch” object, which can be useful in certain simple scenarios, or when you want a management network for your hardware.

sudo apt install -y dynamips

Check the build:

dynamips --version | head -1

Step 3 – Test GNS3 Server

Now it is installed, we can test it works running interactively:

gns3server --host 0.0.0.0

You should see something like:

cit-gns3-01-admin@cit-gns3-01:~$ gns3server --host 0.0.0.0
No configuration file could be found or read
2026-09-07 15:27:43 INFO run.py:218 GNS3 server version 2.2.61
2026-09-07 15:27:43 INFO run.py:220 Copyright (c) 2007-2026 GNS3 Technologies Inc.
2026-09-07 15:27:43 INFO run.py:242 Running with Python 3.12.3 and has PID 17988
2026-09-07 15:27:43 INFO run.py:248 Using system certificate store for SSL connections
2026-09-07 15:27:43 INFO run.py:78 Current locale is en_GB.UTF-8
2026-09-07 15:27:43 INFO web_server.py:349 Starting server on 0.0.0.0:3080
2026-09-07 15:27:43 INFO __init__.py:70 Load controller configuration file /home/cit-gns3-01-admin/.config/GNS3/2.2/gns3_controller.conf
2026-09-07 15:27:43 INFO __init__.py:74 Controller is starting
2026-09-07 15:27:43 INFO __init__.py:329 Installing base configs in '/home/cit-gns3-01-admin/GNS3/configs'
2026-09-07 15:27:43 INFO __init__.py:342 Installing built-in disks in '/home/cit-gns3-01-admin/GNS3/images/QEMU'
2026-09-07 15:27:43 INFO __init__.py:255 Comparing controller version 2.2.61 with config version None
2026-09-07 15:27:43 INFO appliance_manager.py:103 Installing built-in appliances in '/home/cit-gns3-01-admin/.local/share/GNS3/appliances'
2026-09-07 15:27:43 INFO compute.py:69 Create compute local
2026-09-07 15:27:43 INFO compute.py:369 Connecting to compute 'local'
2026-09-07 15:27:43 WARNING compute.py:372 Cannot connect to compute 'local': Cannot connect to host 127.0.0.1:3080 ssl:default [Connect call failed ('127.0.0.1', 3080)]
2026-09-07 15:27:43 INFO web_server.py:247 Computing image checksums...
2026-09-07 15:27:43 INFO web_server.py:249 Finished computing image checksums
2026-09-07 15:27:48 INFO compute.py:369 Connecting to compute 'local'
2026-09-07 15:27:48 INFO web_log.py:232 127.0.0.1 [07/Sep/2026:15:27:48 +0000] "GET /v2/compute/capabilities HTTP/1.1" 200 553 "-" "Python/3.12 aiohttp/3.13.5"
2026-09-07 15:27:48 INFO notification_handler.py:50 New client has connected to compute WebSocket
2026-09-07 15:27:48 INFO compute.py:436 Connected to compute 'local' WebSocket 'http://127.0.0.1:3080/v2/compute/notifications/ws'

You should also be able to reach the API, if you can then it is working correctly:

curl -s http://localhost:3080/v2/version

So a result like the following (your version may differ) is good:

{
    "local": false,
    "version": "2.2.61"
}

That’s great, but we don’t want to have this running interactively, so let’s set this to run as a Systemd service.

Step 4 – Run as Systemd Service

To run as a systemd service, we just need to first create the file as below:

sudo vim /etc/systemd/system/gns3server.service

And add this content, we need to ensure that the User and Group is changed to whatever our GNS3 Server user account will run under, i.e. the user you are logged into at the moment:

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

[Service]
Type=simple
User=cit-gns3-01-admin
Group=cit-gns3-01-admin
ExecStart=/usr/bin/gns3server --host 0.0.0.0
Restart=on-failure
RestartSec=5
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target

Reload Systemctl and enable GNS3 for a server.

sudo systemctl daemon-reload
sudo systemctl enable --now gns3server

Now check it is listening with:

sudo systemctl status gns3server --no-pager

We should see something like the following:

$ sudo systemctl status gns3server --no-pager
● gns3server.service - GNS3 server
     Loaded: loaded (/etc/systemd/system/gns3server.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-09-07 15:30:35 UTC; 10s ago
   Main PID: 18115 (gns3server)
      Tasks: 1 (limit: 154442)
     Memory: 45.0M (peak: 49.7M)
        CPU: 610ms
     CGroup: /system.slice/gns3server.service
             └─18115 /usr/share/gns3/gns3-server/bin/python /usr/bin/gns3server --host 0.0.0.0

Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 INFO __init__.py:263 Built-in appliances are installed in '/home/cit-gns3-01-admin/.local/share/GNS3/appliances'
Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 INFO compute.py:69 Create compute local
Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 INFO compute.py:369 Connecting to compute 'local'
Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 WARNING compute.py:372 Cannot connect to compute 'local': Cannot connect to host 127.0.0.1:3080 ssl:default [Connect….0.0.1', 3080)]
Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 INFO web_server.py:247 Computing image checksums...
Sep 07 15:30:36 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:36 INFO web_server.py:249 Finished computing image checksums
Sep 07 15:30:41 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:41 INFO compute.py:369 Connecting to compute 'local'
Sep 07 15:30:41 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:41 INFO web_log.py:232 127.0.0.1 [07/Sep/2026:15:30:41 +0000] "GET /v2/compute/capabilities HTTP/1.1" 200 553 "-" "Pyth…aiohttp/3.13.5"
Sep 07 15:30:41 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:41 INFO notification_handler.py:50 New client has connected to compute WebSocket
Sep 07 15:30:41 cit-gns3-01 gns3server[18115]: 2026-09-07 15:30:41 INFO compute.py:436 Connected to compute 'local' WebSocket 'http://127.0.0.1:3080/v2/compute/notifications/ws'
Hint: Some lines were ellipsized, use -l to show in full.

And then also verify it is working with:

ss -tlnp | grep 3080

Which should show GNS3 is listening on 3080:

$ ss -tlnp | grep 3080
LISTEN 0      100          0.0.0.0:3080      0.0.0.0:*    users:(("gns3server",pid=18115,fd=13))

You should also be able to reach the API, if you can then it is working correctly:

curl -s http://localhost:3080/v2/version

So a result like the following (your version may differ) is good:

{
    "local": false,
    "version": "2.2.61"
}

We are all good. You are now ready to use your GNS3 client to access the GNS3 Server and build your lab environment.

Desktop Client Install and Configuration

The full installation of the client and configuration is beyond the scope of this document, but for Windows or MacOS, just running through with the default settings during installation is all that is typically required.

Once installed, use the “Setup Wizard” (which can be found under “Help”) to select a “Remote Server”, then complete the settings. I didn’t need to set the admin username or password, all I needed to do is enter an IP address of the GNS3 server.

GNS3 Cloud Node

The GNS3 Cloud Node works effectively as a Layer 2 bridge between the physical network directly via GNS3 Server into your lab environment. So a node (for example an Ubuntu Workstation) within your lab environment can exist directly on your physical network, and can be reached by hosts on your physical network, even though its actually inside your lab. The machine can also reach the Internet, or anything permitted by the physical network for that matter.

Within this example the GNS3 Server is running on VMware, so to ensure the Cloud Node works as expected, we need to ensure the Port Group used by the So, to enable it, assuming you have installed everything as per the above, you just need to ensure the Port Group is configured as below, Promisicious Mode: Accept (and “override” if set upstream), Mac Address Changes: Accept, and Forged Transmits: Accept.

Obviously you’ll need to ensure that the interface used by your device (e.g. an Ubuntu machine) within your lab has the correct network configuration as per your physical network, for example here is the netplan for the management workstation. Its the ens3 adapter we are most interested in, this is the one that is on the same network that is bridged via the Cloud Node to the physical network.

/etc/netplan/50-cloud-init.yaml

network:
  version: 2
  ethernets:
    ens3:
      match:
        macaddress: "0c:15:60:d6:00:00"
      set-name: "ens3"
      addresses:
        - 192.168.102.112/24
      routes:
        - to: default
          via: 192.168.102.1
      nameservers:
        addresses:
          - 8.8.8.8
    ens4:
      match:
        macaddress: "0c:15:60:d6:00:01"
      set-name: "ens4"
      addresses:
        - 172.16.1.1/24

Quality of Life Settings

The screen resize can be a bit strange on Windows GNS3 Client when using Ubuntu Linux virtual machines within GNS3, to make it cope with resizing of the windows, you can install xterm, and use “resize”.

apt install xterm
resize

Put that into bash.rc to catch that, append to the end of your ~/.bashrc for it to always be available as soon as you log onto it.

# Automatically update window size on serial consoles
shopt -s checkwinsize
if [[ "$(tty)" == /dev/ttyS* ]]; then
    trap 'resize &>/dev/null' DEBUG
fi

Additional Information/Further Reading

Leave a comment