Networking Azure

hyperglass Network Looking Glass on Ubuntu 24.04 on Azure User Guide

| Product: hyperglass Network Looking Glass on Ubuntu 24.04 LTS on Azure

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 80 as the single public listener, reverse proxying the application on 127.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, hyperglass and nginx
  • 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

hyperglass looking glass

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'

services and listening sockets

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.

query API

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:

composing a query

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

BGP route query result

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

configured 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:

query restriction

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.

abuse controls

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.