GNS3 Server
Videos
Overview: GNS3 Server on Ubuntu 24.04 LTS on Azure: overview (watch on YouTube)
Launch and log in: GNS3 Server on Ubuntu 24.04 LTS on Azure: launch and log in (watch on YouTube)
Deep Dive: GNS3 Server on Ubuntu 24.04 LTS on Azure: deep dive (watch on YouTube)
Overview
GNS3 is the widely used open-source network emulation platform for designing, building and testing network topologies without physical hardware. It runs virtual labs made of emulated Cisco routers, Docker containers, QEMU virtual machines and lightweight virtual PCs. You wire them together into topologies that you can start, stop and inspect.
This SecureAnyCloud image ships the server component: the headless controller and compute engine that actually runs the labs. You drive it from the bundled browser web interface, or by pointing the GNS3 desktop client at it. Running the server on Azure rather than a laptop means that labs keep running when you close your machine, they get server-grade CPU and memory, and a whole team can share them.
This guide covers the deployment and configuration of GNS3 Server on Ubuntu 24.04 on Azure using SecureAnyCloud Azure Marketplace images.
The image installs GNS3 Server 2.2.60 and the complete emulation stack at pinned versions from the official GNS3 package archive. The archive's signing key is verified by full fingerprint before the archive is trusted. The baked versions are recorded in /var/lib/gns3/VERSION.
GNS3 runs under systemd as the unprivileged gns3 system user, bound to loopback only (127.0.0.1:3080). nginx is the sole network-facing surface. It terminates TLS on port 443, enforces HTTP basic authentication on every request and reverse proxies to GNS3. Port 80 redirects to HTTPS.
Secure by default, which matters more here than for most software. An unprotected GNS3 interface lets anyone who can reach it create and start containers and virtual machines on the host. An open interface is therefore equivalent to handing out shell access.
This image closes the interface at two independent layers using a single credential. GNS3's own HTTP authentication is enabled on the loopback listener, and nginx enforces HTTP basic authentication on every path in front of it. A unique credential is generated on each virtual machine's first boot and applied to both layers.
Only a one-way bcrypt hash is stored for nginx. The plain password is placed in a root-only file. There are no shared or default credentials, and nothing usable is baked into the image. Device consoles are bound to the loopback interface rather than the network, and you reach them over an SSH tunnel (Step 8).
What you get:
- GNS3 Server 2.2.60 run under systemd as the unprivileged
gns3system user, with projects, images and configs under/var/lib/gns3 - The complete emulation stack at pinned versions: Dynamips 0.2.23 (Cisco IOS router emulation), ubridge 1.0.1 (node networking), VPCS 0.8.3 (lightweight virtual PCs), QEMU 8.2.2 (full virtual machines) and Docker (container nodes)
- A ready-to-run Docker appliance template (
alpine:3.24.1, pinned by digest), so you can start a real node immediately without downloading anything - GNS3 bound to loopback only (
127.0.0.1:3080) with its own authentication enabled, so it is never directly exposed to the network - nginx terminating TLS on :443, enforcing HTTP basic authentication and reverse proxying to GNS3, with HSTS and sensible security headers
- Port
:80returns a301redirect to HTTPS for every path except an unauthenticated/healthzendpoint (HTTP 200) for load balancer probes - A unique API credential generated per VM on first boot and applied to both authentication layers. Only the one-way bcrypt hash is stored for nginx, and the plain password lands in a root-only file
- Device consoles pinned to loopback (
console_host = 127.0.0.1), because telnet consoles are unauthenticated by protocol - A self-signed TLS certificate regenerated per VM on first boot. Its Subject Alternative Names include the VM public IP, hostname and
127.0.0.1. Replace it with your own CA-signed certificate for production - A built-in self test at
/usr/local/bin/gns3-selftestthat proves the authenticated API end to end and starts a real emulated node - Ubuntu 24.04 LTS base with the latest security patches applied at build time
- Azure Linux Agent for seamless cloud integration and SSH key injection
- 24/7 SecureAnyCloud support with a guaranteed 24 hour response SLA
Prerequisites
- An Azure subscription with permission to deploy virtual machines
- An SSH key pair for the
azureuseraccount - A network security group that allows inbound
443from your users and22from your management network only - Choose the right VM size for the emulation you need. Read Step 1 before you deploy. Dynamips, Docker and VPCS nodes run on any size, while QEMU virtual machine nodes need a size that supports nested virtualisation.
Choose a VM size for the emulation you need
GNS3 emulates devices in several ways, and they do not all have the same hardware requirement. This is the single most important sizing decision for this image, so make it before you deploy.
These are the node types and whether each needs nested virtualisation:
- Dynamips: classic Cisco IOS routers. No nested virtualisation needed, so it runs on any VM size.
- Docker: container-based appliances and hosts. No nested virtualisation needed, so it runs on any VM size.
- VPCS: lightweight virtual PCs for testing reachability. No nested virtualisation needed, so it runs on any VM size.
- Ethernet switch, hub and cloud: built-in switching and connectivity. No nested virtualisation needed, so it runs on any VM size.
- QEMU and KVM: full virtual machines (vendor appliance images, firewalls, full OS nodes). Nested virtualisation is needed, because these nodes require /dev/kvm.
QEMU nodes are hardware-accelerated through KVM, which on Azure requires nested virtualisation. Azure's B series does not support nested virtualisation, so /dev/kvm is absent there and QEMU-based appliance nodes cannot be accelerated. The Dv3, Dsv3, Dv5 and Dsv5 series (and later) do support it.
If you will use Dynamips, Docker or VPCS nodes only, any size works. Standard_B2s is enough to get started.
If you will use QEMU virtual machine nodes, deploy on Standard_D2s_v3 or larger (any v3 or later D series). This is the recommended size for this image, and it is what the Marketplace listing recommends.
Emulation is CPU- and memory-hungry in general. Size for the lab you intend to run, not for the smallest node count.
Deploy from the Azure Portal
Locate the GNS3 Server on Ubuntu 24.04 LTS image in the Azure Marketplace and select Create.
Choose your subscription, resource group and region.
Select a VM size using Step 1 (Standard_D2s_v3 or larger if you need QEMU nodes). Provide your SSH public key for the azureuser account.
On the Networking tab, allow inbound 443 from your users, and restrict 22 to your management network.
Select Review + create, then Create. When the VM is running, browse to https://<your-public-ip>/.
Deploy from the Azure CLI
Deploy the image from the command line, restricting SSH to your management network. Replace the example values with your own before you run the command:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:gns3-server-ubuntu-24-04:default:latest
az vm create \
--resource-group my-resource-group \
--name gns3-server \
--image sac1647283583153:gns3-server-ubuntu-24-04:default:latest \
--size Standard_D2s_v3 \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
# Allow the web UI from your users and SSH from your management network only
az vm open-port --resource-group my-resource-group --name gns3-server --port 443 --priority 1001
az network nsg rule create --resource-group my-resource-group --nsg-name gns3-serverNSG \
--name allow-ssh --priority 1002 --destination-port-ranges 22 \
--source-address-prefixes <your-mgmt-cidr> --access Allow --protocol TcpWhen the VM is running, browse to https://<public-ip>/.
Retrieve your per-instance API credential
Access is protected by HTTP basic authentication at the proxy and by GNS3's own authentication behind it. Each VM generates its own username and password on first boot and writes them to a root-only file. Read the file over SSH:
ssh azureuser@<vm-ip> 'sudo cat /root/gns3-server-credentials.txt'The file contains the GNS3_USER, GNS3_PASS and GNS3_URL for this specific VM. Keep it secret, because this credential can start containers and virtual machines on the server. nginx only ever stores a one-way bcrypt hash of the password.
Issue the certificate for your public address
First boot puts the address that Azure reports into the TLS certificate, the credentials file and the login banner. With a Standard SKU public IP, the current image records the VM's private address (10.0.0.x). Standard is the Azure default and the --public-ip-sku Standard option in Step 3.
As a result, GNS3_URL points at an address you cannot reach, and the certificate does not name the public IP. Check:
sudo grep '^GNS3_URL=' /root/gns3-server-credentials.txtIf it shows a 10. address, issue a new certificate for the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:
PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/nginx/tls/gns3.key -out /etc/nginx/tls/gns3.crt \
-subj "/C=GB/O=sac/CN=$PUBLIC_IP" \
-addext "subjectAltName=IP:127.0.0.1,DNS:localhost,DNS:$(hostname -s),IP:$PRIV,IP:$PUBLIC_IP" sudo chmod 0600 /etc/nginx/tls/gns3.key
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/gns3-server-credentials.txt /etc/update-motd.d/90-gns3-server
sudo systemctl restart nginxFor a DNS name, set PUBLIC_IP to the name and write DNS:$PUBLIC_IP in place of IP:$PUBLIC_IP. Your credential does not change. The certificate is still self-signed, so the browser warning in Step 5 remains until you install a CA-signed certificate (Step 12).
Sign in and register the server in the web interface
Browse to https://<vm-ip>/. The certificate is self-signed per VM, so your browser shows a certificate warning the first time. Accept it to proceed, or place a CA-signed certificate in front (Step 12). Your browser then prompts for the basic authentication username and password from Step 4.
The GNS3 Web UI opens on its Servers page. The web interface is a client, so you tell it which GNS3 server to talk to. Click Add server and fill in the connection details for this VM. Choose Basic authorization and enter the credential from Step 4.
Once added, the server appears in the Servers table with its host, port and location, and an arrow action to open it.
Create a project
Open the server to reach its Projects page. From here, you can create a blank project, import an existing one, or open a project you already have. Projects are stored on the VM under /var/lib/gns3/projects.
Click a project to open its topology canvas.
Build and start a topology
Open the project to reach the topology canvas. Add nodes from the toolbar and drag links between their ports. Use the toolbar controls to start, pause and stop the lab. Started nodes show a green marker, and the node panel lists each node's console address.
The example below is a three-node lab: two Docker-based hosts wired to an Ethernet switch, all started. Each console is a telnet://127.0.0.1:<port> address, because consoles are deliberately bound to the loopback interface. Step 8 covers how to reach them.
You can drive the same operations from the REST API. This example creates a project, adds a Docker node from the bundled alpine:3.24.1 template, starts it, then removes the project again:
GUSER=$(sudo grep -m1 '^GNS3_USER=' /root/gns3-server-credentials.txt | cut -d= -f2-)
GPASS=$(sudo grep -m1 '^GNS3_PASS=' /root/gns3-server-credentials.txt | cut -d= -f2-)
PID=$(curl -sk -u "$GUSER:$GPASS" -X POST -H 'Content-Type: application/json' \
--data '{"name":"api-demo"}' https://127.0.0.1/v2/projects \
| sed -n 's/.*"project_id": *"\([^"]*\)".*/\1/p')
curl -sk -u "$GUSER:$GPASS" -X POST -H 'Content-Type: application/json' \
--data '{"name":"host1","node_type":"docker","compute_id":"local","console_type":"telnet", "properties":{"image":"alpine:3.24.1","adapters":1,"start_command":"/bin/sh"}}' \
-o /dev/null -w 'create node -> HTTP %{http_code}\n' https://127.0.0.1/v2/projects/$PID/nodes
curl -sk -u "$GUSER:$GPASS" -X POST -o /dev/null -w 'start nodes -> HTTP %{http_code}\n' \
https://127.0.0.1/v2/projects/$PID/nodes/start
curl -sk -u "$GUSER:$GPASS" -X DELETE -o /dev/null -w 'cleanup -> HTTP %{http_code}\n' \
https://127.0.0.1/v2/projects/$PIDThe console_type field is required when you create a node. GNS3 does not default it.
Reach a device console
Device consoles are telnet, which is unauthenticated by protocol. This image therefore binds them to the loopback interface (console_host = 127.0.0.1), so they are never reachable from the network.
To reach a console, forward its port over SSH from your workstation, then connect to the forwarded port locally:
# On your workstation. The console port is shown in the node panel, e.g. 5000.
ssh -L 5000:127.0.0.1:5000 azureuser@<vm-ip> telnet 127.0.0.1 5000Do not change console_host to 0.0.0.0. That would expose every device console to the network without authentication.
Verify the deployment
SSH to the VM as azureuser. Confirm that the services are running and that GNS3 is bound to loopback only:
systemctl is-active gns3-server nginx docker
sudo ss -tlnp | grep -E ':(80|443|3080)\b'All three services report active, and GNS3 listens on 127.0.0.1:3080 only. nginx is the only component exposed on :80 and :443.
Run the built-in self test. It reads this VM's credential and proves the whole path:
- The health probe answers.
- An unauthenticated API request is refused.
- An authenticated request succeeds.
- A project is created through the API.
- A real Docker-backed node is started.
The self test also reports the hardware virtualisation state of this VM:
sudo /usr/local/bin/gns3-selftestThe authentication gate and the API
nginx terminates TLS on port 443 and redirects plain HTTP on port 80 to HTTPS. Confirm the redirect and the unauthenticated health probe. Also confirm that the API is refused without the per-VM credential and succeeds with it:
curl -s -o /dev/null -w 'port 80 -> HTTP %{http_code}\n' http://127.0.0.1/
curl -sk -o /dev/null -w 'healthz -> HTTP %{http_code}\n' https://127.0.0.1/healthz
curl -sk -o /dev/null -w 'API, no creds -> HTTP %{http_code}\n' https://127.0.0.1/v2/version
curl -sk -o /dev/null -w 'API, direct to loopback, no creds -> HTTP %{http_code}\n' http://127.0.0.1:3080/v2/versionPort 80 returns 301 and the health endpoint returns 200. The API returns 401 without credentials, both through the proxy and when addressed directly on the loopback listener. This proves that GNS3's own authentication layer is enforcing and is not merely shadowed by nginx.
With the credential, the API answers and reports the node types this server can emulate:
GUSER=$(sudo grep -m1 '^GNS3_USER=' /root/gns3-server-credentials.txt | cut -d= -f2-)
GPASS=$(sudo grep -m1 '^GNS3_PASS=' /root/gns3-server-credentials.txt | cut -d= -f2-)
curl -sk -u "$GUSER:$GPASS" https://127.0.0.1/v2/version
curl -sk -u "$GUSER:$GPASS" https://127.0.0.1/v2/computes | jq -r '.[0].capabilities.node_types | join(", ")'Connect the GNS3 desktop client
The desktop client is the richer way to build large topologies, and it talks to this same server. In the client, choose to connect to a remote server. Supply the VM's address on port 443 with HTTPS, plus the username and password from Step 4.
The certificate is self-signed, so either accept it or install a CA-signed certificate first (Step 12).
Use a matching client version: a GNS3 2.2.x client for this 2.2.60 server.
Replace the certificate for production
The per-VM certificate is self-signed, so browsers and the desktop client warn on first use. For a real deployment, put a trusted certificate in front. The simplest approach is to point a DNS name at the VM and obtain a free certificate with Certbot:
# Point https://<your-domain> at this VM first, then:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>Alternatively, terminate TLS at an Azure Application Gateway or a load balancer in front of the VM and forward to port 443.
Baked versions and emulator inventory
The baked GNS3 and emulator versions are recorded on the VM, along with the pinned Docker appliance template and the archive signing key that was verified at build time:
cat /var/lib/gns3/VERSION dynamips --version | head -1 vpcs -v | head -1 ubridge -v qemu-system-x86_64 --version | head -1The last command in the screenshot below checks for /dev/kvm. On a B series VM it is absent. This is expected and only affects QEMU nodes, while Dynamips, Docker and VPCS nodes are unaffected. On a Standard_D2s_v3 or larger, it is present and QEMU nodes are hardware-accelerated.
Service management
systemctl status gns3-server --no-pager | head -12 sudo journalctl -u gns3-server -n 20 --no-pagerThe server log is also written to /var/log/gns3/gns3-server.log. Projects, images, configs and appliances live under /var/lib/gns3. Back up that directory to preserve your labs.
Security notes
No default login. Access is protected at two layers with a single credential generated on each VM's first boot: nginx HTTP basic authentication, and GNS3's own authentication on the loopback listener. Only a one-way bcrypt hash is stored for nginx. The plain password lives in the root-only /root/gns3-server-credentials.txt.
Treat the credential as shell access. The GNS3 API can create and start containers and virtual machines on the server. Anyone with this credential can run code on the VM. Share it accordingly. If you need per-user access, put an identity-aware proxy in front.
Loopback-only application. GNS3 binds to 127.0.0.1:3080 and is reachable only through the nginx TLS reverse proxy on :443. Keep it that way, and let nginx (or a load balancer) be the sole network-facing surface.
Consoles stay on loopback. Device telnet consoles are unauthenticated by protocol, so console_host is pinned to 127.0.0.1. Reach them over an SSH tunnel (Step 8) instead of changing that setting.
Restrict access. Allow 443 only from the networks that need it, and keep 22 restricted to your management network. Replace the self-signed certificate with a CA-signed one for production.
Rotate the credential with sudo /usr/local/sbin/gns3-write-credentials <new-user> <new-password>, then restart the services. This updates both authentication layers together.
Version pinning. The GNS3 packages are installed at exact validated versions from the official GNS3 archive, whose signing key is verified by fingerprint at build time. They are deliberately not placed on apt hold. Ubuntu's unattended upgrades apply only the security origin, so a third-party archive is never upgraded automatically. Holding packages would misrepresent the patch posture of the machine.
OS security updates continue to apply as normal. You remain free to upgrade GNS3 yourself when you choose to.
Support
This image is backed by 24/7 SecureAnyCloud support with a guaranteed 24 hour response SLA. Contact sales@secureanycloud.com for assistance.
GNS3 is open-source software distributed under the GNU General Public License v3.0 and is free. The SecureAnyCloud charge covers packaging, hardening, security patching, image maintenance and support.
Deploy on Azure
Launch GNS3 Server on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
This SecureAnyCloud 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. You wire them into topologies, then 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. This guide covers both paths.
The complete emulation stack is installed and wired at pinned versions from the official GNS3 package archive. The archive's signing key is verified by full fingerprint before the repository is trusted.
What you get:
- 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
- A dedicated EBS volume mounted at
/var/lib/gns3for projects, appliance and IOS images, node configurations and templates. It is separate from the operating system disk and independently resizable - 24/7 SecureAnyCloud support
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 interface is effectively an open door to the server. This image closes it at two independent layers using a single credential:
gns3serverlistens 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
Authorizationheader 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.txtwith mode 0600 - Nothing usable is baked into the image. The captured image carries a locked, non-functional entry on both layers. 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, described 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
- Open the product page in AWS Marketplace and choose Continue to Subscribe
- Accept the terms, then choose Continue to Configuration
- Select the software version and the Region you want to deploy into, then choose Continue to Launch
- Choose Launch through EC2 for full control of networking and storage
- Pick an instance type.
m5.largeis the recommended minimum. Read Hardware acceleration and instance sizing before you choose, because the node types you intend to run determine whether a bare-metal instance is required - Select your VPC, subnet and key pair
- Attach a security group allowing inbound TCP 22 from your management network and TCP 443 from your lab clients
- 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 the running state before the interface answers.
Launching with the AWS CLI
Replace the example values in angle brackets 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:
For the Ubuntu 24.04 LTS variant, the SSH login user is 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.txtThe 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.serviceactive active activeCheck the installed version:
gns3server --version2.2.60nginx itself serves the unauthenticated health endpoint, which is intended for load balancer probes. It requires no credential:
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/healthz200Confirming the API is closed
This check matters most. The API must refuse an unauthenticated request:
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/v2/version401A 401 means the API is closed to callers without this instance's credential. If you ever see 200 here, stop and investigate before you expose the instance.
Now prove the credential works. This command 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. It runs the health probe, both negative controls and an authenticated API call. It then creates a real project through the API and starts a real Docker-backed node. It cleans up after itself.
sudo /usr/local/bin/gns3-selftestOK 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. On a standard instance type it says 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.htmlYour browser prompts for the username and password from the credentials file, and it warns about the certificate. The certificate is self-signed and regenerated for each instance on first boot, so the warning is expected. Using 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:
- Name: any label you like, for example sac-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
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 enforces TLS and authentication.
Choose Add. The server appears in the list. Select it to open the project list for this 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.
- 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
- 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.1template ready to use - Draw links between node ports to wire the topology together
- 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.
The panel on the right lists each node with its console address. Every console address is on 127.0.0.1. This 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. This image therefore binds every console to the loopback interface, and 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. In a second terminal on your workstation, connect to the forwarded port:
telnet 127.0.0.1 5001You are now on that device's console. The same pattern works for any node. Forward the port that 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). Use the same values as 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. The GNS3 project does not support mixing a 3.x client with a 2.2 server.
Hardware acceleration and instance sizing
GNS3 emulates devices in several ways, and only one of them needs hardware virtualisation. This determines which instance type to 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. 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 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. They do not silently fall back to software emulation, which 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 appliancesIn 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.9GThe 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.
The directory layout under /var/lib/gns3 is:
- 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.
List the listening sockets:
sudo ss -tlnH | awk '{print $1, $4}' | sort -uLISTEN 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 [::]:80Port 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 and obtain a certificate for that name. Then 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, keep 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 nginxFirst boot generates a certificate only 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. A snapshot captures projects, uploaded images, configurations and templates together, and it is consistent enough for lab data.
For a file-level copy of a single project, stop its nodes first so that 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. Check also that the login and password match the credentials file exactly. Port 3080 does not work from a browser, because the server listens on loopback only by design.
The browser warns about the certificate. This is 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.logRe-running first boot. First boot is gated by a sentinel file at /var/lib/sac/data/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. This invalidates the credential currently stored in any client.
Support
Every SecureAnyCloud deployment is backed by SecureAnyCloud engineers, available 24/7 by email and live chat. Support covers deployment and instance sizing, topology and appliance configuration, importing IOS and appliance images, and reaching device consoles securely. It also covers 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. SecureAnyCloud 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.
Deploy on AWS
Launch GNS3 Server on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com