hyperglass Network Looking Glass on Ubuntu 24.04 on Azure User Guide
Overview
This image runs hyperglass 2.0.4, the modern open source network looking glass, on Ubuntu 24.04 LTS. A looking glass is the public web page network operators publish so that peers, customers and downstream networks can run read only diagnostic queries against the operator's own routers without holding an account on the network. hyperglass supports BGP Route, BGP Community, BGP AS Path, Ping and Traceroute queries across Cisco IOS, IOS XR, NX-OS, Juniper, Arista EOS, BIRD, FRR, Huawei, MikroTik, Nokia SR OS, OpenBGPD, TNSR and VyOS, and presents them through a genuinely polished interface rather than the hand rolled CGI script this category is known for.
cloudimg delivers hyperglass fully installed behind an nginx reverse proxy, with Redis as the state store and query cache, all managed by systemd, so a working looking glass answers within minutes of launch.
What is included:
- hyperglass 2.0.4 installed from the official release into
/opt/hyperglass, running in a dedicated Python 3.12 virtual environment - Redis 7 as the state store and query result cache, bound to loopback only
- nginx on port
80as the single public listener, reverse proxying the application on127.0.0.1:8001 - Node.js 22 LTS and pnpm, because hyperglass derives its user interface from your configuration and rebuilds it whenever you change settings
- Three systemd units enabled and active:
redis-server,hyperglassandnginx - Abuse controls switched on by default: per source address rate limiting on query submission, a query result cache, and a policy that refuses queries aimed at private, loopback, link local, multicast and reserved address space
- Secure by default: no operator credential and no router credential ship in the image. On first boot a unique operator password is generated and written to a root only file
- A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
- 24/7 cloudimg support

Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is the recommended size. NSG inbound: allow 22/tcp from your management network and 80/tcp from wherever your looking glass audience is, which for a public looking glass is the internet. The appliance also needs outbound SSH (22/tcp) to your routers, since that is how hyperglass collects output.
hyperglass serves plain HTTP on port 80. A looking glass is a public web page, so terminate TLS in front of it with your own domain before you advertise it (see the last step).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for hyperglass by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name hyperglass \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
# Open the HTTP port so visitors can reach the looking glass
az vm open-port --resource-group <your-rg> --name hyperglass --port 80 --priority 900
Step 3 - Retrieve the per VM operator credentials
Nothing secret is baked into the image. On the very first boot, a one shot service (hyperglass-firstboot.service) generates an operator password unique to your instance, writes it into an nginx credentials file, and records it in /root/hyperglass-credentials.txt, readable only by root.
The looking glass itself is anonymous by design and needs no credentials. These credentials gate the operator only appliance administration page at /admin/.
SSH in as azureuser and read them:
sudo cat /root/hyperglass-credentials.txt
# hyperglass — per-VM credentials, generated on first boot by
# hyperglass-firstboot.service. These are unique to THIS VM. Store them safely.
hyperglass.url=http://203.0.113.10/
hyperglass.admin.url=http://203.0.113.10/admin/
hyperglass.admin.user=cloudimg-admin
hyperglass.admin.pass=****************************
# Canonical keys consumed by the cloudimg smoke verifier + guide substitution:
HYPERGLASS_ADMIN_USER=cloudimg-admin
HYPERGLASS_ADMIN_PASSWORD=****************************
Step 4 - Confirm the services are running
for s in redis-server hyperglass nginx; do printf '%-16s %s\n' "$s" "$(systemctl is-active $s)"; done
redis-server active
hyperglass active
nginx active
Only nginx is publicly reachable. The application and Redis both listen on loopback:
sudo ss -ltnp | grep -E ':(80|8001|6379)\s'

Step 5 - Open the looking glass
Browse to http://<your-vm-public-ip>/. You will see the hyperglass interface with a Location selector listing the devices you have configured, a Query Type selector, and a Target field.
Confirm it answers from the command line too:
curl -s -o /dev/null -w 'looking glass: HTTP %{http_code}\n' http://127.0.0.1/
looking glass: HTTP 200
The image ships with a single placeholder device so that hyperglass starts and the interface is coherent before you have configured anything. It is 192.0.2.1, an address from the IETF documentation range that is never routed, with REPLACE_ME credentials. It cannot reach any real network. Step 7 replaces it.
curl -s http://127.0.0.1/api/devices | python3 -m json.tool
[
{
"id": "example_router",
"name": "Example Router",
"group": "Example Site"
}
]
Step 6 - Query from the API
Everything the web interface does is available over the same HTTP API, so you can script it or drive it from monitoring.
List the query types your devices expose:
curl -s http://127.0.0.1/api/queries | python3 -m json.tool
[
"BGP Community",
"Traceroute",
"Ping",
"BGP AS Path",
"BGP Route"
]
Read the looking glass parameters:
curl -s http://127.0.0.1/api/info | python3 -m json.tool
{
"name": "Looking Glass",
"organization": "Example Network",
"primary_asn": 65001,
"version": "2.0.4"
}
A query is a POST to /api/query with the device id, the directive id and the target. Every response, success or failure, uses the same envelope: output, level and keywords.

Until you have added a real router, a query against the shipped placeholder returns a clean, well formed timeout rather than a hang or a stack trace, which is the correct behaviour for a device that does not answer:
curl -s -m 60 -H 'Content-Type: application/json' \
-d '{"queryLocation":"example_router","queryTarget":"1.1.1.0/24","queryType":"__hyperglass_cisco_ios_bgp_route__"}' \
http://127.0.0.1/api/query | python3 -c 'import json,sys; r=json.load(sys.stdin); print("level:", r["level"]); print("output:", str(r["output"]).split(chr(10))[0])'
level: danger
output: Request timed out. (TCP connection to device failed.
Step 7 - Add your own routers
This is the one step that turns the appliance into your looking glass. Edit the devices file:
$ sudo nano /etc/hyperglass/devices.yaml
Replace the placeholder entry with your own router. A minimal Cisco IOS device looks like this:
devices:
- name: Core Router LON1
description: London core router
address: 198.51.100.7
platform: cisco_ios
port: 22
group: London
credential:
username: lookingglass
password: "your-router-password"
# The built-in Ping and Traceroute directives issue
# ping {target} repeat 5 source {source4}
# so every device must declare the source addresses its own router should
# send probes from. These are usually the router's loopback addresses.
attrs:
source4: "198.51.100.7"
source6: "2001:db8:100::7"
# Inherit every built-in directive for this platform: BGP Route,
# BGP Community, BGP AS Path, Ping and Traceroute.
directives:
- builtins: true
Use a dedicated, least privilege, read only account on the router. A looking glass only ever needs to run show commands. Key based authentication is supported instead of a password:
credential:
username: lookingglass
key: /etc/hyperglass/keys/router.pem
Supported platform values are cisco_ios, cisco_xr, cisco_nxos, juniper, arista_eos, bird, frr, huawei, mikrotik, nokia_sros, openbgpd, tnsr and vyos.
Once a real router is configured, visitors pick it, choose a query type and enter a target:

and hyperglass returns the router's own output, rendered:

Apply the change. hyperglass derives its interface from your configuration, so this rebuilds the interface and restarts the service:
sudo hyperglass-apply
Confirm hyperglass parsed your device:
sudo hyperglass-cli devices

Branding lives in /etc/hyperglass/config.yaml: set org_name, site_title and primary_asn to your own, then run sudo hyperglass-apply again.
Step 8 - Understand the abuse controls
A looking glass is deliberately public, and it executes commands on your routers on behalf of anonymous visitors. This image therefore ships its protections switched on, rather than leaving them to you.
Non public targets are refused. Queries aimed at private, loopback, link local, multicast or reserved address space are rejected before your router is ever contacted, so nobody can use your looking glass to map your internal network:
curl -s -H 'Content-Type: application/json' \
-d '{"queryLocation":"example_router","queryTarget":"10.0.0.0/8","queryType":"__hyperglass_cisco_ios_bgp_route__"}' \
http://127.0.0.1/api/query | python3 -m json.tool
{
"output": "10.0.0.0/8 is not valid. ('10.0.0.0/8' is in private address space. This looking glass only accepts publicly routable targets.)",
"level": "warning",
"keywords": [
"private address space",
"'10.0.0.0/8' is in private address space. This looking glass only accepts publicly routable targets.",
"10.0.0.0/8"
]
}
Visitors see the same refusal in the interface:

This policy is implemented as a hyperglass input plugin at /etc/hyperglass/plugins/cloudimg_public_targets.py. To allow address space you legitimately route, such as CGNAT, add it to the ALLOW_EXTRA list at the top of that file and run sudo hyperglass-apply.
Query submission is rate limited to 12 requests per minute per source address, with a burst of 5, returning HTTP 429 beyond that. Tune it in /etc/nginx/conf.d/hyperglass-limits.conf and reload nginx with sudo nginx -t && sudo systemctl reload nginx.
Identical queries are cached for 120 seconds in Redis instead of being re-run against your routers. Change cache.timeout in /etc/hyperglass/config.yaml.

Step 9 - The operator only administration page
The looking glass is anonymous, but the appliance administration page at /admin/ is not. It is protected with the per VM credentials from Step 3 and summarises this instance, where its configuration lives, and the abuse controls in force.
Anonymous access is refused:
curl -s -o /dev/null -w 'anonymous /admin/ -> HTTP %{http_code}\n' http://127.0.0.1/admin/
anonymous /admin/ -> HTTP 401
With the per VM credentials it opens:
curl -s -o /dev/null -w 'authenticated /admin/ -> HTTP %{http_code}\n' -u "cloudimg-admin:<HYPERGLASS_ADMIN_PASSWORD>" http://127.0.0.1/admin/
authenticated /admin/ -> HTTP 200
To change the operator password, write a new one on stdin so it never reaches your shell history or the system journal:
$ printf '%s\n' 'your-new-password' | sudo htpasswd -i -B /etc/nginx/hyperglass.htpasswd cloudimg-admin
Updating password for user cloudimg-admin
Step 10 - Enable HTTPS with your own domain
Point a DNS record such as lg.example.net at the VM's public IP, then:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain> -m <your-email> --agree-tos --redirect -n
Certbot edits the nginx site in place and installs a renewal timer. The rate limiting and the /admin/ protection are preserved because they live in the same server block.
Administration and support
| Task | Command |
|---|---|
| Service status | systemctl status hyperglass |
| Application logs | journalctl -u hyperglass -f |
| Edit routers | sudo nano /etc/hyperglass/devices.yaml |
| Edit branding and query settings | sudo nano /etc/hyperglass/config.yaml |
| Apply configuration changes | sudo hyperglass-apply |
| Inspect parsed devices | sudo hyperglass-cli devices |
| Inspect parsed settings | sudo hyperglass-cli params |
| Clear the query cache | sudo hyperglass-cli clear-cache |
| Operator credentials | sudo cat /root/hyperglass-credentials.txt |
hyperglass is published under the BSD 3 Clause Clear licence. This is a repackaged open source product; cloudimg charges for support services, not for the software. Our engineers provide 24/7 support for deployment, upgrades, TLS termination, router onboarding, custom query directives and scaling. Contact support@cloudimg.co.uk.