Observability AWS

Glances 4.5.8 on AWS User Guide

| Product: Glances 4.5.8 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Glances 4.5.8 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Zabbix & Infrastructure Monitoring AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Glances is an open source, cross platform system monitor. Its web dashboard shows, on one live page, CPU, memory, swap and load, every process with its command line, network interfaces, disk I/O, file systems, sensors and alerts, and its REST API (/api/4/...) returns the same data as JSON for scripts, dashboards and exporters.

That data is sensitive: a process list includes the command lines of everything running on the instance, which can contain other software's settings and secrets. Out of the box, glances -w serves it to anyone who can reach port 61208, with no password and permissive cross origin access. The cloudimg image adds:

  • HTTPS from the first boot. nginx serves Glances on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
  • A password unique to your instance. The whole dashboard and API sit behind HTTP Basic authentication with a password generated on first boot (stored as a bcrypt hash; the password is written to /root/glances-info.txt). No password is baked into the image, and nothing is reachable before first boot has created it.
  • Glances on loopback only, as an unprivileged user. Glances listens on 127.0.0.1:61208 and runs as the glances system user in a systemd sandbox. Only its web server runs: the XML-RPC server (glances -s) and the MCP endpoint are never started. The only open ports are 22, 80 and 443.
  • Hardened Glances settings. The cloud plugin (which reads instance metadata) is off, the public IP lookup to a third party service is off, Glances never checks PyPI for updates, does not run commands from its configuration file, accepts only your instance's host names (DNS rebinding defence) and allows cross origin API access only from your instance's own HTTPS address.
  • Metadata service blocked. Glances (including any URL checks and alert actions you configure) and nginx cannot reach the instance metadata service, and the AMI requires IMDSv2.
  • Fixed host and real client addresses. Requests for a host name the instance does not serve are dropped, nginx passes Glances a fixed host name and the real client address, and cross site requests that would change data are refused.
  • A pinned, minimal Python install. Glances 4.5.8 and its web stack are installed from exact, hash verified wheels into /opt/glances/venv. The JWT library python-jose and its dependencies (including ecdsa) are not installed, because they are only used by Glances' own --password mode, which this image does not need (nginx does the authentication). Both have open advisories with no upstream fix (CVE-2026-85394, CVE-2024-23342), so they do not ship at all.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

Glances 4.5.8 includes the upstream fixes for the security advisories published against 4.5.5 to 4.5.7 (including CVE-2026-62982, CVE-2026-68517 to CVE-2026-68520 and GHSA-48jj-p764-8x75).

What is on the image: Glances 4.5.8 (from PyPI, unmodified), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH), TCP 443 (the dashboard and API) and TCP 80 (redirects to HTTPS) from your own networks only. Never open port 61208.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Glances 4.5.8 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (Glances is light; a smaller instance is fine), your key pair and a security group as above.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=glances}]'

Step 2: Connect to your instance

Version SSH user
Glances 4.5.8 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot takes a few seconds. Then the three units are active:

systemctl is-active glances-web nginx glances-firstboot
active
active
active

Glances listens on loopback only; nginx serves ports 80 and 443:

sudo ss -tlnp | awk 'NR==1 || /glances|nginx|sshd/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer
LISTEN 127.0.0.1:61208 users:(("glances"))
LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN 0.0.0.0:22 users:(("sshd"),("systemd"))
LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:22 users:(("sshd"),("systemd"))
LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))
/opt/glances/venv/bin/python -c 'import glances, psutil; print("Glances", glances.__version__, "/ psutil", psutil.__version__)'
Glances 4.5.8 / psutil 7.2.2

Step 4: Get your URL and password

sudo cat /root/glances-info.txt

The file holds the address Glances is served as (your instance's public DNS name by default), the user name glances and the password generated on this instance:

glances_url=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
glances_username=glances
glances_password=<28 letters and digits>

Step 5: Open the dashboard

Open glances_url in your browser. The certificate is self signed (generated on your instance), so accept the browser warning once, or install your own certificate (Step 9). Your browser then asks for a user name and password: enter glances and the password from Step 4.

The dashboard shows the instance at a glance: CPU, memory, swap and load at the top, network, disk I/O, file systems and sensors on the left, and every process with its CPU and memory use, user and command line on the right. It refreshes every two seconds.

The Glances dashboard with CPU, memory and load at the top, network, disk I/O and file systems on the left and the process list on the right

The dashboard takes the same single key shortcuts as Glances in a terminal. Press m to sort the processes by memory, c by CPU, i by I/O, a to go back to automatic sorting:

The process list sorted by memory consumption

Press h for the full list of shortcuts (show or hide sections, switch units, clear alerts):

The Glances help screen listing the keyboard shortcuts

Step 6: Use the REST API

Every value on the dashboard is also available as JSON under /api/4/, with the same user name and password. The interactive API documentation is at /docs:

The interactive REST API documentation listing the Glances endpoints

On the instance, this reads the CPU statistics. The password goes to curl on stdin as a config line, so it never appears on a command line:

H=$(sudo sed -n 's#^glances_url=https://\([^/]*\)/#\1#p' /root/glances-info.txt)
sudo sed -n 's/^glances_password=\(.*\)$/user = "glances:\1"/p' /root/glances-info.txt \
  | curl -sk -K - --resolve "$H:443:127.0.0.1" "https://$H/api/4/cpu" | python3 -m json.tool | head -6
{
    "total": 1.2,
    "user": 0.8,
    "nice": 0.0,
    "system": 0.3,
    "idle": 98.5,

The plugins that are running:

H=$(sudo sed -n 's#^glances_url=https://\([^/]*\)/#\1#p' /root/glances-info.txt)
sudo sed -n 's/^glances_password=\(.*\)$/user = "glances:\1"/p' /root/glances-info.txt \
  | curl -sk -K - --resolve "$H:443:127.0.0.1" "https://$H/api/4/pluginslist"; echo
["quicklook", "sensors", "cpu", "ports", "fs", "wifi", "core", "load", "amps", "programlist", "help", "containers", "memswap", "version", "network", "uptime", "mem", "now", "ip", "psutilversion", "percpu", "diskio", "system", "alert", "folders", "processlist", "gpu", "processcount"]

From your own computer use the instance's address and the password from Step 4, for example curl -k -u glances https://<your-host>/api/4/mem (curl prompts for the password). Single values have their own paths, such as /api/4/mem/percent or /api/4/load/min1; /api/4/all returns everything at once.

Step 7: Security checks

Port 80 sends browsers to HTTPS and the health endpoint answers without a password (for load balancer checks). Everything else needs the password: no password and a wrong one are refused, yours is accepted. Unknown host names are dropped:

H=$(sudo sed -n 's#^glances_url=https://\([^/]*\)/#\1#p' /root/glances-info.txt)
curl -s -o /dev/null -w 'port 80: %{http_code} -> %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -w '\n' --resolve "$H:443:127.0.0.1" "https://$H/healthz"
curl -sk -o /dev/null -w 'no password: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/api/4/cpu"
printf 'user = "glances:wrong-password-123"\n' | curl -sk -K - -o /dev/null -w 'wrong password: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/api/4/cpu"
sudo sed -n 's/^glances_password=\(.*\)$/user = "glances:\1"/p' /root/glances-info.txt | curl -sk -K - -o /dev/null -w 'your password: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/api/4/cpu"
curl -s -o /dev/null -w 'unknown host name: %{http_code}\n' -H 'Host: example.com' http://127.0.0.1/ || true
port 80: 301 -> https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
ok
no password: 401
wrong password: 401
your password: 200
unknown host name: 000

(000 means nginx closed the connection without an answer.) The certificate was generated on this instance and names its own addresses:

H=$(sudo sed -n 's#^glances_url=https://\([^/]*\)/#\1#p' /root/glances-info.txt)
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
subject=CN = ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, O = cloudimg
X509v3 Subject Alternative Name:
    DNS:ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost

Glances runs unprivileged in a sandbox with only its web server on loopback, the cloud plugin, update check, autodiscovery and configuration commands off, and neither it nor nginx can reach the instance metadata service:

systemctl show glances-web -p User -p NoNewPrivileges -p ProtectSystem -p IPAddressDeny
systemctl show nginx -p IPAddressDeny
systemctl show glances-web -p ExecStart | grep -oE 'glances -C [^;]*'
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
User=glances
ProtectSystem=full
NoNewPrivileges=yes
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
glances -C /etc/glances/glances.conf -w --bind 127.0.0.1 --port 61208 --disable-plugin cloud --disable-check-update --disable-autodiscover --disable-config-exec

nginx checks the password, then passes Glances a fixed host name and the real client address from the connection, never values a client sends, and does not forward your credentials to Glances:

grep -E 'proxy_set_header (Host|X-Forwarded-For|X-Real-IP|Authorization)' /etc/nginx/sites-available/cloudimg-glances | sort -u
        proxy_set_header Authorization "";
        proxy_set_header Host $gl_host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;

The cloudimg settings in the Glances configuration file:

sudo grep -E '^(check_update|cors_origins|cors_credentials|webui_allowed_hosts|public_disabled|port_default_gateway)=' /etc/glances/glances.conf
check_update=false
cors_origins=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com
cors_credentials=False
webui_allowed_hosts=ec2-<public-ip-dashed>.<region>.compute.amazonaws.com,<public-ip>,<private-ip>,127.0.0.1,localhost
public_disabled=True
port_default_gateway=False

nginx also refuses a change whose Origin is another web site (HTTP 403), including a cross site WebSocket connection, and Glances itself rejects any Host that is not one of your instance's names, even from the instance.

Step 8: Configure Glances

Glances reads /etc/glances/glances.conf (the upstream configuration file with the cloudimg settings above). Edit it as root, then restart Glances:

sudo nano /etc/glances/glances.conf
sudo systemctl restart glances-web

Common changes:

  • Alert thresholds. Each plugin section has careful, warning and critical levels (for example [mem] or [fs]); the dashboard colours values and lists alerts when they are crossed.
  • Service and URL checks. The [ports] section can check TCP ports and web URLs (port_1_host=, web_1_url=) and shows them under the network panel. The default gateway ping is off because the VPC router does not answer ping; set port_default_gateway=True on networks where it does. These checks run inside Glances' sandbox, so they cannot reach the instance metadata service.
  • Application monitoring. The [amp_*] sections group processes by application (nginx, systemd, and so on).
  • Exporters. Sections such as [influxdb2], [prometheus] or [elasticsearch] configure where glances --export sends data. The image ships the web server only; an exporter needs its Python client library, which is not installed.

Two settings stay as shipped unless you have a reason to change them: --disable-config-exec in the service means backtick commands in the configuration file are not run, and alert action commands cannot chain or redirect with shell operators.

Glances runs as the unprivileged glances user. Everything on the dashboard works that way on a standard instance; running it as root would add per process I/O counters for other users' processes. To show Docker container statistics, add the user to the docker group once Docker is installed (sudo usermod -aG docker glances, then restart glances-web); membership of that group is equivalent to root, so do it only if you need the containers panel.

Step 9: Your own DNS name and certificate

Point a DNS record at the instance, then set the name Glances is served as. This mints a new self signed certificate for the name, updates nginx, Glances' allowed host names and cross origin address, and the URL in /root/glances-info.txt, and keeps the name across reboots:

sudo glances-set-hostname <your-domain>

To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx (running glances-set-hostname again replaces it with a self signed one):

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/glances.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/glances.key
sudo nginx -t && sudo systemctl reload nginx

Step 10: Change the password

glances-set-password sets a new password for the glances sign in and records it in /root/glances-info.txt. Run it without arguments for a new random password, or pass your own (16 to 128 letters and digits) on stdin:

sudo glances-set-password
printf '%s\n' '<your-new-password>' | sudo glances-set-password --stdin

To give several people their own sign in, add users to the nginx password file with htpasswd (it asks for the password), keep the file readable by nginx only, and reload nginx. Note that glances-set-password rewrites the file with the glances user alone.

sudo htpasswd -B /etc/nginx/glances.htpasswd <name>
sudo chown root:www-data /etc/nginx/glances.htpasswd && sudo chmod 0640 /etc/nginx/glances.htpasswd
sudo systemctl reload nginx

Step 11: Upgrades and components

Glances is installed in its own virtual environment from exact, hash verified wheels, and pip has been removed from it so nothing changes it by accident. The image ships the version named in the listing. To move to a newer Glances release later, snapshot the instance, create a new virtual environment next to it (python3 -m venv /opt/glances/venv-new), install the release you want into it, point ExecStart in /etc/systemd/system/glances-web.service at it and run sudo systemctl daemon-reload && sudo systemctl restart glances-web.

Component Path
Glances 4.5.8 /opt/glances/venv (glances-web.service, user glances, 127.0.0.1:61208)
Glances configuration /etc/glances/glances.conf
nginx site /etc/nginx/sites-available/cloudimg-glances
Password file (bcrypt) /etc/nginx/glances.htpasswd
Certificate and key /etc/nginx/ssl/
First boot script /usr/local/sbin/glances-firstboot.sh
Host name and password helpers /usr/local/sbin/glances-set-hostname, /usr/local/sbin/glances-set-password
Credentials /root/glances-info.txt (mode 0600)
Licence and source record /usr/share/doc/glances/

Step 12: Security recommendations

  • Allow ports 22, 80 and 443 in the security group from your own networks only, and never open port 61208.
  • Treat the dashboard password like an administrator password: the process list shows the command lines of everything on the instance. Rotate it if it may have been shared (Step 10).
  • Use your own DNS name and a certificate your browsers trust (Step 9).
  • Keep the operating system patched; unattended security upgrades are on, and sudo apt-get update && sudo apt-get upgrade applies everything else.

Support and licensing

Glances is open source under the GNU Lesser General Public License v3 (LGPL-3.0-only). The image ships it unmodified from PyPI; the licence text is at /usr/share/doc/glances/COPYING (the GNU GPL v3 it supplements is at /usr/share/common-licenses/GPL-3), and /usr/share/doc/glances/SOURCE records where the source code is published. There is no per server or per CPU licence fee. The AMI price covers cloudimg's hardening, first boot setup and support. Glances is a project of its authors; cloudimg is not affiliated with or endorsed by the Glances project.

  • Email: support@cloudimg.co.uk
  • Website: https://www.cloudimg.co.uk
  • Support: 24/7, with a 24 hour response SLA