Networking AWS

GNS3 Server on AWS User Guide

| Product: GNS3 Server on AWS

Overview

This image runs GNS3 Server 2.2, the headless controller and compute engine of the GNS3 network emulation platform. GNS3 lets you build virtual network labs out of emulated Cisco routers, Docker containers and lightweight virtual PCs, wire them into topologies, and start, stop and inspect them, all without physical hardware.

The image ships the server component, not the desktop GUI client. You drive it either from the bundled browser Web UI or by pointing the GNS3 desktop client at the server. Both paths are covered below.

The complete emulation stack is installed and wired at pinned versions from the official GNS3 package archive, whose signing key is verified by full fingerprint before the repository is trusted:

  • Dynamips, the Cisco IOS router emulator behind classic routing and switching labs
  • ubridge, the network bridge that connects emulated nodes to each other
  • VPCS, the lightweight virtual PC emulator used for endpoint nodes
  • Docker, the container back end for Docker appliance nodes, with a pinned Alpine template already pulled
  • QEMU, for appliance nodes on bare metal instance types

Projects, appliance and IOS images, node configurations and templates live on a dedicated EBS volume mounted at /var/lib/gns3, separate from the operating system disk and independently resizable. Appliance disk images are large, so keeping them off the root volume matters.

Security model

An unprotected GNS3 interface lets anyone who can reach it create and run containers and virtual machines on the host. An open one is effectively an open door to the server, so this image closes it at two independent layers using a single credential:

  • gns3server listens on 127.0.0.1:3080 only, with its own HTTP authentication enabled
  • nginx on port 443 terminates TLS and enforces HTTP basic authentication on every path, forwarding the Authorization header upstream so one credential satisfies both layers
  • A unique username and password are generated on each instance's first boot and applied to both layers. Only the one way bcrypt hash reaches the nginx password file; the plain password is written to /root/gns3-server-credentials.txt with mode 0600
  • Nothing usable is baked into the image. The captured image carries a locked placeholder on both layers, so no two instances share a credential and none is published anywhere

Device telnet consoles are pinned to the loopback interface, because the telnet console protocol is unauthenticated by design. You reach them through an SSH tunnel, covered later in this guide.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region
  • A security group allowing inbound TCP 22 from your management network, and inbound TCP 443 from the clients that will reach the lab
  • An SSH client on your workstation, and a modern browser

Launching from the AWS Marketplace

  1. Open the product page in AWS Marketplace and choose Continue to Subscribe
  2. Accept the terms, then choose Continue to Configuration
  3. Select the software version and the Region you want to deploy into, then choose Continue to Launch
  4. Choose Launch through EC2 for full control of networking and storage
  5. Pick an instance type. m5.large is the recommended minimum. See Hardware acceleration and instance sizing before you choose, because the node types you intend to run determine whether a bare metal instance is required
  6. Select your VPC, subnet and key pair
  7. Attach a security group allowing inbound TCP 22 from your management network and TCP 443 from your lab clients
  8. Launch, and wait for the instance to reach the 2/2 checks passed state

First boot generates this instance's TLS certificate and API credential and starts the emulation stack. Allow a minute or two after the instance reaches running state before the interface answers.

Launching with the AWS CLI

Replace the placeholders with values for your account and Region.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <your-key-pair> \
  --security-group-ids <your-security-group-id> \
  --subnet-id <your-subnet-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=gns3-server}]'

Connecting to your instance

Connect over SSH using the key pair you selected at launch. The login user depends on the operating system variant you launched:

OS variant SSH login user
Ubuntu 24.04 LTS ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>

Retrieving this instance's API credential

The username and password are generated on this instance's first boot and written to a root only file. Read them with:

sudo cat /root/gns3-server-credentials.txt

The file contains a GNS3_USER line, a GNS3_PASS line and a GNS3_URL line pointing at this instance's public address. Treat the file as sensitive: the GNS3 API can run containers and virtual machines on this host, so anyone holding the credential can execute code on the instance.

Verifying the server is running

Confirm all three units are active:

systemctl is-active gns3-server.service nginx.service docker.service
active
active
active

Check the installed version:

gns3server --version
2.2.60

The unauthenticated health endpoint is served by nginx itself and is intended for load balancer probes. It requires no credential:

curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/healthz
200

Confirming the API is closed

This is the check that matters most. An unauthenticated request to the API must be refused:

curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/v2/version
401

A 401 means the API is closed to callers without this instance's credential. If you ever see 200 here, stop and investigate before exposing the instance.

Now prove the credential works. This block reads the password into a shell variable and never prints it:

sudo bash -c 'U=$(grep -m1 "^GNS3_USER=" /root/gns3-server-credentials.txt | cut -d= -f2-); P=$(grep -m1 "^GNS3_PASS=" /root/gns3-server-credentials.txt | cut -d= -f2-); curl -sk -u "$U:$P" https://127.0.0.1/v2/version'
{
    "local": false,
    "version": "2.2.60"
}

Full round trip self test

The image ships a self test that exercises the whole appliance end to end: the health probe, both negative controls, an authenticated API call, creating a real project through the API, and starting a real Docker backed node. It cleans up after itself.

sudo /usr/local/bin/gns3-selftest
OK gns3 self-test passed: healthz 200, unauth /v2/version 401, unauth /v2/projects 401, authenticated API 200 (GNS3 2.2.60), project created via API, Docker-backed node started
     hardware virtualisation (/dev/kvm): ABSENT - this instance type does not expose /dev/kvm, so QEMU/KVM appliance nodes cannot run here. On AWS, /dev/kvm is available ONLY on BARE METAL instance types (for example m5.metal or c5.metal) - AWS does not offer nested virtualisation on standard virtualised instance types. Dynamips, Docker and VPCS nodes (verified above) are unaffected and work on every instance type.

The final line reports the hardware virtualisation state of the instance you are on, honestly. On a standard instance type it will say absent, which is expected and is explained below.

Opening the Web UI

The GNS3 Web UI is a browser application served by the same server. Open it at:

https://<public-ip>/static/web-ui/index.html

Your browser will prompt for the username and password from the credentials file, and will warn about the certificate. The certificate is self signed and regenerated for each instance on first boot, so the warning is expected. Replacing it with your own CA signed certificate is covered under Using your own certificate.

Pointing the Web UI at this server

The Web UI is a client that must be told which GNS3 server to talk to. On first load it shows an empty Servers list. This is normal, and it is the one configuration step you need to do.

Choose Add server and fill the dialog exactly as follows:

Field Value
Name any label you like, for example cloudimg-gns3
Location Remote
Host this instance's public address
Port 443
Protocol HTTPS
Authorization Basic authorization
Login the GNS3_USER value from the credentials file
Password the GNS3_PASS value from the credentials file

Adding this server in the GNS3 Web UI, using HTTPS on port 443 with basic authorization

Port 443 and protocol HTTPS are important. The server itself listens only on loopback, so the Web UI must connect through the nginx reverse proxy on 443, which is what enforces TLS and authentication.

Choose Add. The server appears in the list, and following it opens the project list for this instance.

The project list served by the instance

Building your first topology

From the project list, choose Add blank project, give it a name, and open it. You are now on the topology canvas.

  1. Use the + control in the top toolbar to add nodes. An Ethernet switch is a good starting point because it is a built in node and needs no emulator or image
  2. Add endpoint nodes. VPCS nodes are lightweight virtual PCs and run on any instance type. Docker nodes run containers, and the image ships a pinned alpine:3.24.1 template ready to use
  3. Draw links between node ports to wire the topology together
  4. Press the play control to start all nodes. Node indicators turn green as each one comes up

The screenshot below shows a running four node lab: two VPCS hosts and a Docker backed node, all wired to an Ethernet switch, all started.

A running GNS3 lab: two VPCS hosts and a Docker node wired to an Ethernet switch, all started

The panel on the right lists each node with its console address. Note that every console address is on 127.0.0.1. That is deliberate, and the next section explains how to reach them.

Reaching device consoles

Device consoles use the telnet protocol, which has no authentication. Exposing them to the network would let anyone reach the command line of your emulated devices, so this image binds every console to the loopback interface. The console ports are never opened in the security group.

To reach a console, forward its port over SSH from your workstation. Use the port shown next to the node in the Web UI, for example 5001:

ssh -i /path/to/your-key.pem -L 5001:127.0.0.1:5001 ubuntu@<public-ip>

Leave that session open, and in a second terminal on your workstation connect to the forwarded port:

telnet 127.0.0.1 5001

You are now on that device's console. The same pattern works for any node: forward the port the Web UI shows for it.

Using the GNS3 desktop client

The GNS3 desktop client can drive this server instead of the browser UI. In the client, add a remote server (sometimes shown as a remote controller) with the same values you used for the Web UI: this instance's address, port 443, protocol HTTPS, and the username and password from the credentials file.

The desktop client version should match the server's 2.2 series. Mixing a 3.x client with a 2.2 server is not supported by the GNS3 project.

Hardware acceleration and instance sizing

GNS3 emulates devices in several ways, and only one of them needs hardware virtualisation. This determines which instance type you should launch.

These node types run on any EC2 instance type, including the recommended m5.large:

  • Dynamips nodes, which emulate Cisco IOS routers. This covers classic routing and switching labs
  • Docker nodes, which run containers as network appliances
  • VPCS nodes, lightweight virtual PC endpoints
  • Ethernet switch and other built in nodes

QEMU appliance nodes require /dev/kvm, and on AWS /dev/kvm is available only on bare metal instance types such as m5.metal or c5.metal. AWS does not offer nested virtualisation on standard virtualised instance types, so no amount of configuration will make QEMU appliance nodes run on an m5.large.

The image installs the full stack either way. QEMU nodes are deliberately configured to fail fast with a clear error on an instance without /dev/kvm, rather than silently falling back to software emulation that would be far too slow to be usable.

Check the hardware virtualisation state of the instance you are on:

test -e /dev/kvm && echo "/dev/kvm present: QEMU appliance nodes can run here" || echo "/dev/kvm absent: use Dynamips, Docker and VPCS nodes, or launch a bare metal instance type for QEMU appliances"
/dev/kvm absent: use Dynamips, Docker and VPCS nodes, or launch a bare metal instance type for QEMU appliances

In short: if your labs are built from Cisco IOS routers, containers and virtual PCs, a standard instance type is the right choice. If you need QEMU based appliances such as vendor firewall or virtual router images, launch a bare metal instance type.

Beyond that, size on node count. Each emulated node consumes memory and CPU on this single host, so scale the instance up as your topologies grow.

Storage layout

Projects, images, configurations and appliance templates live on a dedicated EBS volume:

findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/gns3
/dev/nvme1n1 /var/lib/gns3 ext4   48.9G

The volume is mounted from /etc/fstab by filesystem UUID, so it re attaches correctly on every reboot and on every instance launched from this image. To grow it, modify the EBS volume in the AWS console, then extend the filesystem on the instance with resize2fs.

Directory layout under /var/lib/gns3:

Path Contents
projects/ your topologies and their node state
images/ appliance and IOS images you upload
configs/ node configuration files
appliances/ appliance template definitions

Network model

Only three ports are reachable from the network. Everything else, including the GNS3 server itself and every device console, is bound to loopback:

sudo ss -tlnH | awk '{print $1, $4}' | sort -u
LISTEN 0.0.0.0:22
LISTEN 0.0.0.0:443
LISTEN 0.0.0.0:80
LISTEN 127.0.0.1:3080
LISTEN 127.0.0.1:40231
LISTEN 127.0.0.53%lo:53
LISTEN 127.0.0.54:53
LISTEN [::]:22
LISTEN [::]:443
LISTEN [::]:80

Port 3080 is the GNS3 server, on loopback only. Port 80 serves the health endpoint and redirects everything else to HTTPS:

curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' http://127.0.0.1/
301 -> https://127.0.0.1/

Using your own certificate

The certificate generated on first boot is self signed, which is why browsers warn. To use a CA signed certificate for a domain you control, point DNS at the instance, obtain a certificate for that name, and replace the certificate and key that nginx serves.

The certificate and key live at /etc/nginx/tls/gns3.crt and /etc/nginx/tls/gns3.key. Replace both files with your own, keeping the key readable only by root, then reload nginx.

sudo install -m 0644 /path/to/your.crt /etc/nginx/tls/gns3.crt
sudo install -m 0600 /path/to/your.key /etc/nginx/tls/gns3.key
sudo nginx -t && sudo systemctl reload nginx

Note that first boot only generates a certificate once, on the instance's first start, so a replacement certificate is not overwritten on later reboots.

Backup

Everything worth preserving is on the data volume. The simplest and most reliable backup is an EBS snapshot of the volume mounted at /var/lib/gns3, which captures projects, uploaded images, configurations and templates together and is consistent enough for lab data.

For a file level copy of a single project, stop its nodes first so no node is mid write, then archive that project's directory under /var/lib/gns3/projects/ and copy it off the instance.

Maintenance

The instance applies operating system security updates automatically through unattended upgrades, which is enabled on every instance launched from this image.

GNS3 itself is installed at a pinned version from the official GNS3 package archive and is not upgraded automatically, so a lab you build is not disturbed by an unattended version change. When you want to move to a newer GNS3 release, plan it as a deliberate change: back up the data volume first, and check that your desktop client version still matches the server series.

Troubleshooting

The Web UI shows an empty Servers list. This is the expected first load state. Follow Pointing the Web UI at this server. The Web UI is a browser side client and does not assume which server it should talk to.

The Web UI cannot connect after adding the server. Check that you used port 443, protocol HTTPS and Basic authorization, and that the login and password match the credentials file exactly. Port 3080 will not work from a browser, because the server listens on loopback only by design.

The browser warns about the certificate. Expected. The certificate is self signed per instance. Accept it for lab use, or install your own certificate as described above.

A QEMU appliance node will not start. Check the hardware virtualisation state as shown above. On a standard instance type /dev/kvm is absent and QEMU appliance nodes cannot run. Use Dynamips, Docker or VPCS nodes, or relaunch on a bare metal instance type.

Nodes show as stopped after reopening a project. Closing a project stops its nodes. Reopen the project and press the start control to bring them back up.

Checking service logs. The server logs to the journal and to its own log file:

sudo journalctl -u gns3-server.service -n 50 --no-pager
sudo tail -n 50 /var/log/gns3/gns3-server.log

Re running first boot. First boot is gated by a sentinel file at /var/lib/cloudimg/gns3-server-firstboot.done. It runs once per instance. Removing the sentinel and restarting gns3-server-firstboot.service regenerates the certificate and rotates the credential, which will invalidate the credential currently stored in any client.

Support

Every cloudimg deployment is backed by cloudimg engineers available 24/7 by email and live chat. Support covers deployment and instance sizing, topology and appliance configuration, importing IOS and appliance images, reaching device consoles securely, installing your own CA signed certificate, credential management, backup and restore, and GNS3 upgrades and troubleshooting. Critical issues receive a one hour average response time.

GNS3 is a trademark of its respective owner. cloudimg is not affiliated with, endorsed by or sponsored by the GNS3 project. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.