XMS Installation Manual
1. Introduction
This guide covers installation and initial configuration of XMS, plus optional advanced configuration and troubleshooting.
2. Prerequisites
2.1 System Requirements
- Hardware: Minimum 2 CPU cores, 8 GB RAM, 40 GB storage (60 GB recommended for production)
- Architecture:
amd64/x86_64 - OS: Ubuntu 22.04 LTS recommended (modern Debian-based systems with
systemdare typically suitable)
Required software:
- If you install using the official XMS OVA, these are already preinstalled.
- Docker Engine (
docker) - Docker Compose (
docker compose) jqcertbot(only if you plan to use Let's Encrypt)
2.2 Network and DNS Requirements
- Two static IPv4 addresses on the XMS host:
- One for XMS HTTPS/UI/API
- One for MQTT TLS
- Two DNS records:
XMS_FQDN(for examplexms.example.com)MQTT_FQDN(for examplemqtt.example.com)- Firewall:
443/TCPopen to XMS IP443/TCPopen to MQTT IP80/TCPopen to XMS IP only if using Let's Encrypt22/TCPfor SSH administration
2.3 External Database (Optional)
If using external database instead of internal PostgreSQL container:
- Use a PostgreSQL version supported by your XMS release
- Enable extension:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
- Ensure XMS host can reach the database host
2.4 Acquiring and Installing XMS
Retrieve and run the installer script:
wget https://share.xertified.net/install/xms_install_ubuntu_release.sh
chmod 750 xms_install_ubuntu_release.sh
./xms_install_ubuntu_release.sh
You will be prompted for your account key. After successful validation, package repository access is configured and XMS package installation starts.
3. Installation and Setup
3.1 Run the Setup Tool
If you use the XMS OVA image, first configure networking:
sudo xms-network-setup
Then run setup:
cd /usr/share/xms
./xms-setup.sh
For unattended setup (when configuration is already saved):
./xms-setup.sh --setup
3.2 Configure XMS
From the menu, select Configure XMS. The script walks you through each setting:
- XMS FQDN — The domain name for the XMS web UI and API (for example
xms.example.com). Must resolve to the XMS IP in DNS. - XMS IP — The local IP address on this host for the XMS interface. Verify with
ip addr. - MQTT FQDN — The domain name for the MQTT service (for example
mqtt.example.com). Must resolve to the MQTT IP. - MQTT IP — The local IP for MQTT. Must be a different IP than XMS.
- Database type —
Internaluses a bundled PostgreSQL container (recommended for most deployments).Externalconnects to your own PostgreSQL instance (see 2.3). - Database FQDN — Only prompted if you selected
External. - TLS source — How the HTTPS certificate for Nginx is obtained. Options:
Let's Encrypt(automatic, requires the XMS FQDN to be publicly reachable on port 80),Generate self-signed(quick for lab/testing, causes browser warnings),Issue via XMS CA(uses the built-in CA, requiresCA_TYPEto be configured), orFile(provide paths to your own certificate and key files). - User source —
Keycloakmanages users locally (recommended for first install).Microsoft Entra IDrequires additional Azure configuration (see 4.4). - Create initial XMS user —
Yescreates anxmsadminaccount with a generated password. ChooseNoonly if you plan to bootstrap users manually.
After confirming the summary, configuration is written to .env/.config and related templates are updated.
3.3 Start Setup
Back in the menu, select Start setup.
The setup process will:
- Validate external DB credentials (if external DB)
- Apply required file permissions
- Verify database access
- Configure Keycloak realm (if needed)
- Issue internal service certificates (if needed)
- Configure/import TLS certificate according to selected TLS source
- Optionally create
xmsadmin, enable group sync, and assignsuperadmin - Apply final permissions
- Enable and restart
xmsservice
3.4 Validate Installation
Run:
systemctl status xms
cd /usr/share/xms
docker compose ps
Then verify:
- Core services are
running/healthy(nginx,auth-api,xot-api,directory-sync,mqtt,dashboard, pluspostgresif internal DB) - Open
https://<XMS_FQDN> - Log in using created credentials (or external IdP login)
3.5 Main Menu Reference
Menu options are state-dependent:
Configure XMS: Save/update installation settingsStart setup: Run setup with saved settingsConfigure Entra ID Sync: Appears when user source is Entra ID/AzurePrint full system status: Runsscripts/get-status.sh
4. Advanced Configuration (Optional)
4.1 OVA First-Login Hardening
If you deployed from OVA, complete these hardening steps after initial setup:
- Change the default password.
- Add your SSH public key to
~/.ssh/authorized_keys. - Remove temporary password-auth override and restart SSH:
sudo rm /etc/ssh/sshd_config.d/99-ova-default-password.conf
sudo systemctl restart ssh
- Remove
/etc/motdsetup banner if no longer needed.
For package updates on OVA deployments, configure APR repository access:
sudo xertified-repo-setup
4.2 Release vs Testing Package Track (Automation)
If you install via Ansible automation, you can choose repository track:
- Release track:
ansible-playbook -K playbook_setup_xms.yml
- Testing track:
ansible-playbook -K playbook_setup_xms.yml -e testing=true
Testing mode switches repository key/component/distribution to testing variants.
4.3 External CA
Default is integrated CA. If needed, configure external CA after base setup.
-
Telia Cygate (
CA_TYPE=CYGATE) -
Set
CA_TYPE=CYGATE,CYGATE_URL,CYGATE_ISSUERin/etc/xms/config/env -
Place in
/etc/xms/secrets/ca-manager/:cygate-issuer.pemcygate-issuer-ca.pemcygate-ra.pemcygate-ra-key.pem
-
Net iD Portal (
CA_TYPE=NIP) -
Set
CA_TYPE=NIP,NIP_FQDNin/etc/xms/config/env - Set
SECMAKER_PWfor the Net iD Portal API certificate.pfx
4.4 Identity Source and Synchronization
- For Entra ID authentication/synchronization, see:
- Microsoft Entra ID Integration for XMS
- In setup, selecting Entra ID enables
Configure Entra ID Syncin the menu.
External Identity Providers (OIDC)
If you want users to authenticate via an external provider (for example Microsoft Entra ID) instead of local Keycloak users, configure an OIDC Identity Provider in Keycloak:
- Open the Keycloak Administration Console (
https://<XMS_FQDN>/idp), select thexmsrealm, and navigate to Identity Providers → OpenID Connect v1.0. - Fill in Client ID, Client Secret, and Discovery endpoint from your provider's app registration.
- Under Advanced, set Scopes to
openid profile. - Go to the Mappers tab, click Add mapper, and create a mapper with:
- Name:
oid - Sync mode override:
Force - Mapper type:
Attribute Importer - Claim:
oid - User Attribute Name:
oid
For Azure-specific app registration setup, see Microsoft Entra ID Integration for XMS.
Keycloak Login Theme
When using an external identity provider, change the login theme so users are redirected to the provider instead of seeing a username/password form (which could cause them to enter external credentials into Keycloak).
In the Keycloak Administration Console, select the xms realm → Realm settings → Themes tab, and set the login theme to xertified.
Do not change the login theme for the master realm — this will break admin access.
If you are authenticating users directly in Keycloak (no external provider), leave the theme at its default value keycloak.
4.5 User and Role Bootstrapping
If you are not relying on the auto-created xmsadmin, you need to create users and assign roles manually.
Creating Users via Keycloak UI
- Retrieve Keycloak admin credentials:
cat /etc/xms/secrets/keycloak/admin-credentials
-
Navigate to
https://<XMS_FQDN>/idp→ Administration Console and log in asxadmin. -
Switch to the
xmsrealm (top-left dropdown). All XMS user management must be done in this realm. -
Create groups via the Groups menu (create groups first so you can assign membership during user creation).
-
Navigate to Users → Add user. Assign at least one group — users without group membership are not synchronized by
directory-sync. -
Go to the Credentials tab and set the password. Set Temporary to off for a permanent password.
Creating Users via Script
cd /usr/share/xms/scripts
./keycloak-create-user.sh --username 'operator1' --group 'Operators' --password 'ComplexP@ss!' --email 'op1@domain.tld'
This creates the user in Keycloak but does not assign an XMS role — see below.
Setting User Roles
Users synced from Keycloak initially receive the role none, which prevents login. You must assign a role for the user to have access.
If you already have a working superadmin account, change roles in the XMS UI: Users → select user → XMS Access dropdown.
Otherwise, use the script:
cd /usr/share/xms
scripts/xms-set-user-role.sh --email admin@example.com --role superadmin
scripts/xms-set-user-role.sh --userid f4a5b1c2-d3e4-f5a6-b7c8-d9e0f1a2b3c4 --role admin
Available roles: none, admin, superadmin. The script handles starting directory-sync if needed and waits for the user to appear in the database. For external databases, ensure psql is installed on the XMS host.
4.6 Ticket Lifetime Tuning (LEASE_SETTINGS)
If your deployment uses customized ticket lifetimes, tune your lease/ticket settings in your XMS runtime configuration (commonly exposed as LEASE_SETTINGS in XMS configuration).
Guidelines:
- Shorter lifetimes improve revocation responsiveness
- Longer lifetimes improve resilience during temporary control-plane outages
- Validate changes in a staging environment before production
After changing ticket/lease settings, restart XMS services and verify policy/ticket behavior from a test client.
4.7 Keycloak with LDAPS (Certificate Trust)
When Keycloak federates against LDAPS, Keycloak must trust the LDAP server certificate chain.
Typical approach:
- Export LDAP server root/intermediate certificates
- Import them into the trust store used by
auth-api/Keycloak runtime - Restart
auth-apiand test LDAP bind/search
If LDAPS bind fails, check docker compose logs auth-api for trust-chain and hostname verification errors.
4.8 TLS Operations Notes
- Let's Encrypt (
scripts/setup-letsencrypt.sh) requires: XMS_FQDNresolving publicly to the XMS host- TCP
80reachable during ACME challenge certbotinstalled- File-based TLS requires valid existing certificate/key paths during configuration.
- Issue via XMS CA is only available when
CA_TYPEis configured.
4.9 Nginx IP Access Control
Restrict access to sensitive XMS endpoints by editing files in /usr/share/xms/config/nginx/:
access-admin.conf: Controls access to the Keycloak admin console (/idp/admin/*). Addallow <IP>;lines for trusted administrator IPs, then uncommentdeny all;to enforce.access-restricted.conf: Controls other restricted application paths. IPs fromaccess-admin.confare automatically included. Uncommentdeny all;to enforce.
After modifying, reload Nginx:
cd /usr/share/xms
docker compose exec nginx nginx -s reload
4.10 Benthos Configuration
The benthos service processes or forwards MQTT messages. If enabled, ensure its configuration (/usr/share/xms/config/benthos/benthos.yaml) has the correct MQTT password — it must match MQTT_XMS_PASSWORD in your .env file.
4.11 Removing Stored Keycloak Credentials
Setup stores Keycloak admin and user credentials in /etc/xms/secrets/keycloak. These are used by helper scripts (keycloak-create-user.sh, xms-set-user-role.sh, etc.) for post-setup configuration. Once setup is complete, copy these credentials to a secure credential management system and remove them from the host. The files are not needed during normal operation, but removing them will prevent the helper scripts from functioning.
4.12 NTP
XMS has NTP enabled by default and can act as a time server for connected XoT devices. This is useful in air-gapped or restricted environments where external NTP servers are not reachable. XoT-Locks can be configured in the XMS to use the XMS as their NTP source.
4.13 Upgrading XMS
sudo apt update
sudo apt upgrade xms
The upgrade stops the XMS service, loads new Docker images, preserves configuration in /etc/xms/config/ and /etc/xms/secrets/, applies database migrations on service start, and restarts XMS.
Verify after upgrading:
systemctl status xms
docker compose ps
Check the Release Notes for version-specific upgrade notes.
5. Troubleshooting
5.1 Installation Issues
-
If
Start setupis missing in the menu: -
Run
Configure XMSfirst and save configuration - Ensure both XMS and MQTT IPs are configured on local interfaces
-
For OVA deployments, run
sudo xms-network-setup -
Run status snapshot:
cd /usr/share/xms/scripts
./get-status.sh --all
- Review setup logs (
/var/log/xms-setup/, fallback/tmp) - Re-run setup in debug mode:
XMS_SETUP_DEBUG=1 ./xms-setup.sh --setup
- If auto user creation fails, bootstrap manually with:
./scripts/keycloak-create-user.sh./scripts/xms-set-user-role.sh --email <user_email> --role superadmin
5.2 Operational Issues
- Check service/container state:
systemctl status xms
cd /usr/share/xms
docker compose ps
- Check logs:
journalctl -u xms
cd /usr/share/xms
docker compose logs auth-api
docker compose logs xot-api
docker compose logs directory-sync
docker compose logs postgres
- Re-apply permissions if file access errors appear:
/usr/share/xms/scripts/set-permissions.sh
- Verify
.envand.configfor IP/FQDN/credential mismatches - For sync/login issues, verify group membership and assigned XMS role
6. Reference: XMS Services Overview
XMS is composed of multiple Docker services managed by systemd service xms.
Key components:
nginx: HTTPS entrypoint and reverse proxydashboard: Admin web interfacexot-api: Core backend API and business logicmqtt: Mosquitto broker for device communicationauth-api: Keycloak-based identity/authenticationca-manager: Certificate issuance and managementdirectory-sync: User/group synchronization into XMS DBlocal-discovery(optional): Local discovery for isolated setups
Additional optional/supporting services can include postgres, mqtt-metrics-collector, and benthos.
XoT-WebAccess is a separate component deployed independently. See the XoT-WebAccess Installation Guide for details.