Applications AWS

GLPI 11.0.12 on AWS User Guide

| Product: GLPI 11.0.12 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the GLPI 11.0.12 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg help desk, IT service and project management listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

GLPI is an open source IT service management (ITSM) and asset management platform. One web application covers the helpdesk (tickets, problems and changes with SLAs and approvals), an inventory of computers, monitors, network devices, printers, phones, software and licences, contracts, suppliers and budgets, projects, a knowledge base and reports, with profiles and entities that control what each user sees and changes.

What the cloudimg image adds:

  • No web installer and no default login. Upstream GLPI is set up in a browser wizard that writes the database settings, and seeds four well known accounts (glpi, tech, normal and post-only, each with its name as its password). On this image the wizard is not shipped and /install/ answers 404. First boot installs the database with GLPI's own console, gives the super administrator glpi a password unique to your instance, and disables tech, normal and post-only with unknown random passwords.
  • Nothing baked into the image. The image ships an empty MariaDB data directory, an empty /etc/glpi and an empty /var/lib/glpi, so every instance creates its own database, its own GLPI encryption key (glpicrypt.key) and its own OAuth key pair on first boot.
  • No database password at all. GLPI runs as its own system user, glpi, and MariaDB accepts that user only over the local socket from processes running as glpi (unix_socket authentication). MariaDB has no network listener.
  • HTTPS from the first boot. nginx serves GLPI on port 443 with a certificate generated on your instance, port 80 redirects to HTTPS, requests for a host name the instance does not serve get no answer, and the session cookie is Secure, HttpOnly and SameSite=Lax. GLPI's "remember me" sign in is off and passwords must be at least 12 characters.
  • Only GLPI's front controller runs PHP. nginx serves GLPI 11's public/ directory and hands every other request to GLPI's front controller; no other PHP file can be reached directly. The configuration, the uploaded documents, the logs and the installer answer 404, and documents and pictures are sent only by GLPI after sign in and a rights check.
  • Read only code. The GLPI code is owned by root and read only to PHP, so nothing on the web can change it, and the plugin marketplace (which downloads plugins into the code tree) is switched off.
  • Abuse limits and cross site protection. Sign in and password reset requests are rate limited per client address, sign out and GLPI's ajax endpoints refuse requests opened from other sites, and GLPI sees the real client address and the configured host name, never values a client sends in headers. The REST APIs are off until you turn them on.
  • Metadata access blocked. nginx, PHP-FPM, MariaDB, GLPI's automatic actions, first boot and the glpi-console helper are blocked from the instance metadata service, so a feed, calendar, mail or webhook address pointed at it gets nothing back, and the AMI requires IMDSv2.
  • Automatic actions from a system timer. GLPI's scheduled tasks (notifications, mail collection, SLA escalation, recurrent tickets, clean up) run every minute from a systemd timer as the glpi user, not from visitors' page loads. Telemetry to the GLPI project is off.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: GLPI 11.0.12 (the official release from GitHub, checksum verified), nginx, PHP 8.3 FPM, MariaDB 10.11, 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) from your admin network, and TCP 443 (GLPI) and TCP 80 (redirects to HTTPS) from the networks your users work from. Your asset inventory and tickets are in GLPI, so keep 80 and 443 as narrow as you can.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick GLPI 11.0.12 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (or larger for many technicians or a large inventory), 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=glpi}]'

First boot builds the database and takes about two minutes after the instance is running.

Step 2: Connect to your instance

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

Step 3: Check the services

First boot creates the database, sets the passwords and mints the certificate; nginx and GLPI's automatic actions start only after it has finished:

systemctl is-active nginx php8.3-fpm mariadb glpi-cron.timer glpi-firstboot
sudo test -f /var/lib/cloudimg/glpi-firstboot.done && echo FIRSTBOOT_DONE

All five units are active and the first boot marker is present:

active
active
active
active
active
FIRSTBOOT_DONE

Only SSH and nginx listen on network ports. MariaDB has no network listener at all and PHP-FPM uses a local socket:

sudo ss -lntp | awk 'NR>1 && $4 !~ /^127\.0\.0\.5[34]/ {split($6, p, "\""); print $4, p[2]}' | sort
0.0.0.0:22 sshd
0.0.0.0:443 nginx
0.0.0.0:80 nginx
[::]:22 sshd
[::]:443 nginx
[::]:80 nginx

Step 4: Get your URL and password

sudo cat /root/glpi-credentials.txt

The file is readable by root only:

# GLPI 11.0.12 - generated on first boot by glpi-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret.

GLPI_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/
GLPI_ADMIN_USER=glpi
GLPI_ADMIN_PASSWORD=<GLPI_ADMIN_PASSWORD>
#
# Open GLPI_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to
# https) and sign in with the user and password above (GLPI's super-admin). The other seeded accounts (tech, normal,
# post-only) are disabled with unknown passwords: enable them with a password of your own, or delete them.
# MariaDB: unix socket only (no TCP listener, no database password: GLPI runs as the OS user glpi);
#          sudo mysql glpi   (root signs in over the socket)
# Automatic actions: systemctl status glpi-cron.timer    GLPI console: sudo glpi-console <command>
# Change the password:            sudo glpi-set-password
# Change the name it serves as:   sudo glpi-set-hostname <your-dns-name>
# User guide: https://www.cloudimg.co.uk/guides/glpi-11-0-12-on-ubuntu-24-04-aws/

The URL uses the instance's public DNS name from the EC2 instance metadata, and the certificate also names the public and private IP addresses. nginx answers only to the names in the certificate. The name is fixed at first boot, so if you stop and start the instance without an Elastic IP and its public address changes, run sudo glpi-set-hostname with the new name (Step 9), or better, give the instance an Elastic IP or your own DNS name.

Step 5: Sign in

Open the GLPI_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own, Step 9). Sign in as glpi with the password from Step 4, leaving the login source on GLPI internal database:

The GLPI 11 sign in page with the Login and Password fields, the login source set to GLPI internal database and the Sign in button

You land on the Central dashboard as Super-Admin of the root entity. The menu on the left holds Assets, Assistance (the helpdesk), Management, Tools, Administration and Setup. A new GLPI shows demonstration figures on its dashboards until it has data of its own, as the banner says; select Disable demonstration to see your real (still empty) figures:

The GLPI Central dashboard after signing in as glpi, with the demonstration data banner, the asset and ticket summary tiles and the main menu on the left

To choose your own password, open the user menu (your initials, top right), select My settings and enter a new password; GLPI requires at least 12 characters with an upper case letter, a lower case letter, a digit and a symbol. Then delete or update GLPI_ADMIN_PASSWORD in /root/glpi-credentials.txt so it does not hold an old password. If you lose the glpi password, set a new one from the instance. Without an option it generates a random password and writes it to the credentials file; with --stdin it reads the password you type (20 to 72 letters and digits). Either way it enables glpi, clears its tokens and signs every session out:

sudo glpi-set-password
sudo glpi-set-password --stdin

Step 6: Inventory and helpdesk

Assets. Open Assets to manage your estate: computers, monitors, software and licences, network devices, peripherals, printers, phones, racks, PDUs, cables and more. Each type has its own list with search, saved searches and bulk actions; use Add to create items by hand or from a template, or import them with the GLPI agent (see below):

The GLPI Assets, Computers list on a new instance, empty, with the Add and Templates buttons and the full list of asset types in the menu

Helpdesk. Open Assistance, Create ticket to log an incident or request with its category, urgency, requester and attachments. Technicians assign, follow up and solve tickets, and link them to the assets, problems and changes involved. Service levels under Setup add SLA and OLA targets with escalation.

Users and entities. Add each person under Administration, Users with their own profile (Self-Service for requesters, Technician, Supervisor, Admin), or connect a directory under Setup, Authentication, LDAP directories. Administration, Entities splits the data between customers, sites or departments.

The seeded accounts. glpi is the only account that can sign in. tech, normal and post-only are disabled with random passwords nobody knows. To use one, open it under Administration, Users, set Active to Yes and give it a password of your own, or delete the ones you do not need:

sudo mysql -N -B glpi -e "SELECT CONCAT(name, ': ', IF(is_active = 1, 'active', 'disabled')) FROM glpi_users WHERE name IN ('glpi', 'tech', 'normal', 'post-only') ORDER BY id;"
glpi: active
post-only: disabled
tech: disabled
normal: disabled

Inventory agents. GLPI 11 has native inventory: the GLPI agent on each computer sends its hardware and software to GLPI. It is off on this image. Turn it on under Administration, Inventory, then allow the agents' networks to reach port 443 and point each agent at https://<your-host>/.

Step 7: Settings, e-mail and automatic actions

General settings. Setup, General holds GLPI's own configuration. URL of the application is set to the instance's address on first boot, and glpi-set-hostname keeps it in step when you change the name (Step 9), so the links in notifications always point at the right host:

The GLPI Setup, General page with the URL of the application set to the instance's https address, the login box text and the dynamic display options

E-mail. Notifications are off on a new instance. Under Setup, Notifications, enable followups by e-mail, then open Email followups configuration and set your SMTP server; Amazon SES works as the relay (port 587 with STARTTLS). To turn incoming e-mail into tickets, add a mailbox under Setup, Receivers. Allow outbound 587 (and 993 for IMAP) if you restrict egress.

Automatic actions. GLPI's scheduled tasks run every minute from glpi-cron.timer as the glpi user, from the PHP command line. Every action that GLPI allows to run from the command line is set to CLI mode, so nothing waits for a visitor's page load; watcher, which GLPI runs only internally, stays as GLPI ships it. Setup, Automatic actions shows each action, its frequency and when it last ran:

The GLPI Setup, Automatic actions list with each action's status, CLI run mode, run frequency and last run time

systemctl is-active glpi-cron.timer
systemctl show glpi-cron -p User -p Type
active
Type=oneshot
User=glpi

What the server contacts. GLPI connects only to the servers an administrator or user configures: SMTP, mail receivers, LDAP, RSS feeds, external calendars and webhooks. Telemetry to the GLPI project and the plugin marketplace are off, and the update check (Setup, Automatic actions, checkupdate) is disabled. None of the services can reach the instance metadata service (Step 10). If you want to limit these connections further, restrict the instance's outbound traffic with its security group or a network ACL to the mail, directory and feed servers you use.

The GLPI console. GLPI's command line (bin/console) runs as the glpi user in a short lived systemd unit with the same metadata block as the services. Use it for maintenance such as clearing the cache or checking the system:

sudo glpi-console --version
sudo mysql -N -B glpi -e "SELECT CONCAT('database schema: ', value) FROM glpi_configs WHERE context = 'core' AND name = 'version';"
GLPI CLI 11.0.12
database schema: 11.0.12

Step 8: The REST APIs

GLPI has a legacy REST API (/apirest.php) and the new high level API (/api.php). Both are off on this image, as is signing in to them with a user name and password:

H=$(sudo grep '^GLPI_URL=' /root/glpi-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
curl -sk -D - -o /dev/null --resolve "$H:443:127.0.0.1" "https://$H/" | tr -d '\r' \
  | grep -iE '^(x-frame-options|x-content-type-options|referrer-policy|set-cookie: glpi_)' \
  | sed -E 's/^set-cookie: glpi_[0-9a-f]+=[^;]*/set-cookie: glpi_<id>=<session>/'
sudo mysql -N -B glpi -e "SELECT name, value FROM glpi_configs WHERE context = 'core' AND name IN ('enable_api', 'enable_hlapi', 'login_remember_default', 'password_min_length', 'use_password_security') ORDER BY name;"
set-cookie: glpi_<id>=<session>; path=/; secure; HttpOnly; SameSite=Lax
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
enable_api  0
enable_hlapi    0
login_remember_default  0
password_min_length 12
use_password_security   1

To use an API, turn it on under Setup, General, API, create an API client for the networks that call it (keep the IP range as narrow as you can), and prefer user tokens (each user's Remote access keys) or OAuth clients (Setup, OAuth clients) to user names and passwords. API callers get the rights of the user they sign in as.

Step 9: Your own DNS name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name GLPI is served as. This mints a new self signed certificate for the name, points nginx and GLPI's URL of the application at it, updates the URL in /root/glpi-credentials.txt, and keeps the name across reboots:

sudo glpi-set-hostname <your-domain>

To use a certificate from a public or internal certificate authority instead (for example one issued by Let's Encrypt for <your-domain>), copy it over the generated pair and reload nginx (running glpi-set-hostname again replaces it with a self signed one):

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

Step 10: Security checks

nginx serves only the application. The installer, the configuration, GLPI's data and log files, the plugin marketplace and anything under /index.php/ answer 404, plain HTTP redirects to HTTPS, and a request for a name the instance does not serve gets no answer at all:

H=$(sudo grep '^GLPI_URL=' /root/glpi-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
for p in / /index.php /install/install.php /install/update.php /index.php/front/login.php /config/config_db.php /files/_log/sql-errors.log /marketplace/ /.git/config; do
  curl -sk -o /dev/null -w "%{http_code}  $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p"
done
curl -s -o /dev/null -w 'http:// -> %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'unknown host name -> %{http_code}\n' --resolve "other.example:443:127.0.0.1" "https://other.example/" || true
200  /
200  /index.php
404  /install/install.php
404  /install/update.php
404  /index.php/front/login.php
404  /config/config_db.php
404  /files/_log/sql-errors.log
404  /marketplace/
404  /.git/config
http:// -> 301
unknown host name -> 000

Signing out and GLPI's ajax endpoints are refused when the request comes from another site, so a link or image on another page cannot sign your users out or call GLPI on their behalf:

H=$(sudo grep '^GLPI_URL=' /root/glpi-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
curl -sk -o /dev/null -w 'cross-site sign out -> %{http_code}\n' -H 'Sec-Fetch-Site: cross-site' --resolve "$H:443:127.0.0.1" "https://$H/front/logout.php"
cross-site sign out -> 403

GLPI's database account has no password; MariaDB accepts it only over the local socket from processes running as glpi, and MariaDB does not listen on the network:

sudo mysql -N -B -e "SELECT CONCAT(User, '@', Host, ' authenticates by ', JSON_VALUE(Priv, '$.plugin'), ', password set: ', IF(IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') = '', 'no', 'yes')) FROM mysql.global_priv WHERE User = 'glpi'; SELECT CONCAT('skip_networking: ', @@skip_networking);"
glpi@localhost authenticates by unix_socket, password set: no
skip_networking: ON

The certificate was generated on this instance and names its own addresses:

H=$(sudo grep '^GLPI_URL=' /root/glpi-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
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>.compute-1.amazonaws.com, O = cloudimg
X509v3 Subject Alternative Name:
    DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost

None of the services can reach the instance metadata service, so a feed, calendar, webhook or mail server address pointed at it gets nothing back:

systemctl show nginx php8.3-fpm mariadb glpi-cron glpi-firstboot -p Id -p IPAddressDeny
IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32
Id=nginx.service

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32
Id=php8.3-fpm.service

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32
Id=mariadb.service

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32
Id=glpi-cron.service

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32
Id=glpi-firstboot.service

sudo glpi-console <command> runs GLPI's console with the same block.

Step 11: Backup, storage and maintenance

Everything you enter is in the MariaDB database glpi (/var/lib/mysql); uploaded documents and pictures, sessions, caches and GLPI's logs are under /var/lib/glpi/files, and the database settings and GLPI's encryption key are in /etc/glpi. All three are on the root volume, so the simplest backup is an EBS snapshot of it. For a consistent copy while GLPI is running:

sudo mariadb-dump --single-transaction --routines glpi | gzip > <backup-dir>/glpi-$(date +%F).sql.gz
sudo tar -C / -czf <backup-dir>/glpi-files-$(date +%F).tar.gz var/lib/glpi/files etc/glpi

Keep /etc/glpi/glpicrypt.key with the dump: GLPI encrypts stored secrets (mail, LDAP and API passwords) with it, and a restored database cannot read them without it. The dump and the key hold every password hash and secret, so store them as carefully as the instance.

To give documents and the database more room, enlarge the root volume in the EC2 console (Volumes, Modify); Ubuntu grows the file system on the next boot. If you would rather keep GLPI's data on its own EBS volume (so it can be sized, snapshotted and moved separately), attach a volume, stop GLPI, copy /var/lib/mysql and /var/lib/glpi onto it, and mount it back over the same paths with bind mounts in /etc/fstab before you start the services again; contact support if you would like help with the move.

GLPI's web installer and plugin marketplace are switched off on this image, because the code is read only to PHP. New GLPI releases arrive as new versions of this listing; a release upgrade runs GLPI's database:update from the console, and support can help you move your data to one. Operating system security updates install automatically; run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, PHP-FPM and MariaDB restart cleanly and GLPI keeps all of its data.

Component Path
GLPI /var/www/glpi (owned by root, read only to PHP; nginx serves public/)
Configuration and encryption key /etc/glpi (config_db.php, glpicrypt.key, mode 0640)
Database MariaDB database glpi (/var/lib/mysql)
Documents, sessions, caches and logs /var/lib/glpi/files
nginx site /etc/nginx/sites-available/cloudimg-glpi
Certificate and key /etc/nginx/ssl/glpi.crt, /etc/nginx/ssl/glpi.key
Automatic actions glpi-cron.timer, glpi-cron.service
Helpers /usr/local/sbin/glpi-set-password, glpi-set-hostname, glpi-console
Credentials /root/glpi-credentials.txt (mode 0600)
Source and changes /usr/share/doc/glpi/SOURCE.txt

Step 12: Security recommendations

  • Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your users and inventory agents work from.
  • Use your own DNS name and a certificate your users' browsers trust (Step 9).
  • Give each person their own GLPI user with the narrowest profile that fits, and enable or delete the seeded tech, normal and post-only accounts deliberately (Step 6). Change the glpi password if it may have been shared.
  • Leave the REST APIs off unless you need them, and then only for the networks that call them, with tokens rather than passwords (Step 8).
  • Keep the operating system patched, and snapshot the root volume regularly.

Support and licensing

GLPI is open source under the GNU General Public License version 3 or later, by Teclib' and the GLPI contributors; there is no per user, per asset or per CPU licence fee. The image ships GLPI exactly as released, with its bundled PHP and JavaScript libraries: /usr/share/doc/glpi/SOURCE.txt names the release it came from and lists every file the image leaves out or adds, and no source file is modified. The AMI price covers cloudimg's hardening, first boot setup and support.

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

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.