SecureLink Installer CLI
The SecureLink Installer (securelink-installer) is a universal provisioning tool that configures all SecureLink device types — dedicated edges, MTGEs, and connectors — using a one-time deployment token.
Overview
The installer handles the complete device lifecycle:
- Checks system prerequisites and installs Docker if needed
- Claims a one-time deployment token from the orchestrator
- Receives the full device bundle (identity, certificates, infrastructure endpoints, registry credentials)
- Configures VPP (DPDK or AF_PACKET), mTLS MQTT, SSH access, Docker Compose, and systemd services
- Pulls Docker images from the private registry
- Supports in-place upgrades and factory reset
Requirements
- Ubuntu 22.04 or later (x86_64)
- Root access (
sudo) - Network access to the SecureLink orchestrator
- Internet access (for Docker installation and image pull)
The installer will automatically install Docker if it's not already present. No manual Docker setup is needed.
Commands
install — Provision a New Device
Provisions a brand-new device using a one-time deployment token.
sudo ./securelink-installer install \
--token NLZ-XXXX-XXXX-XXXX \
--url https://edge-api.vsm.netlinkz.dev
| Flag | Required | Description |
|---|---|---|
--token | Yes | Deployment token (format: NLZ-XXXX-XXXX-XXXX) |
--url | Yes | Orchestrator API URL (HTTPS recommended) |
--insecure | No | Skip TLS certificate verification |
--ca-cert | No | Path to custom CA certificate |
--data-dir | No | Override data directory (default: /var/lib/edge or /var/lib/connector) |
--force | No | Skip confirmation prompts (for automated deployments) |
What Install Does
The installer performs 15 steps in order:
| Step | Action | Details |
|---|---|---|
| 1 | Preflight checks | Validates architecture (x86_64), kernel (5.4+), memory (4GB+), disk (10GB+). Auto-installs missing tools (curl, ip, ethtool, lspci). For DPDK mode, checks IOMMU is enabled. |
| 2 | Install Docker | Checks if Docker is installed. If not, downloads and runs the official Docker install script from get.docker.com, enables the service, and adds the current user to the docker group. |
| 3 | Claim token | Calls the orchestrator's provision API (POST /api/v2/provision/device), validates the token, and receives the complete device bundle. |
| 4 | Display summary | Shows device type, name, GUID, serial number, VPP mode, and tenant for confirmation. |
| 5 | Save identity | Writes identity.json to the data directory (root-owned, 0600). |
| 6 | Save discovery config | Writes discovery.json (enables future upgrades without re-provisioning). |
| 7 | Save certificates | Writes mTLS CA cert, device cert, and private key. If the MQTT broker uses a separate CA, it is appended to the trust store automatically. (Edges and MTGEs only) |
| 8 | Configure SSH access | Generates Ed25519 host key, requests host certificate from the CA, configures sshd with TrustedUserCAKeys for admin access, and writes tunnel configuration for the agent's built-in tunnel manager. (Edges and MTGEs only) |
| 9 | Configure dataplane | For DPDK mode: sets up hugepages (2 GB), loads VFIO kernel module, detects and binds NICs to vfio-pci (management interface automatically excluded). For AF_PACKET: skipped. |
| 10 | Generate VPP config | Creates vpp.conf and govpp.conf for the appropriate dataplane mode. |
| 11 | Pull Docker images | If registry credentials are provided in the bundle, logs in to the private registry, pulls agent-mqtt-cli and suricata images, and re-tags for local use. Falls back to pre-loaded images if registry is unavailable. |
| 12 | Create directories | Sets up /opt/netlinkz/config/, log directories, state directories, and a minimal Bird configuration stub. |
| 13 | Generate Docker Compose | Creates edge-compose.yml or connector-compose.yml with all required services and mTLS MQTT configuration. |
| 14 | Generate Alloy config | Creates alloy-edge.alloy for log collection via Grafana Alloy. (Edges and MTGEs only) |
| 15 | Create systemd service | Writes edge-agent.service or connector-agent.service, enables, and starts all services. |
If prerequisites fail (e.g., IOMMU not enabled for DPDK), the token is not consumed. You can fix the issue, reboot if needed, and re-run the installer with the same token.
DPDK Auto-Detection
When the orchestrator indicates DPDK mode, the installer interactively sets up the dataplane:
- IOMMU check — Verifies
intel_iommu=onoramd_iommu=onin kernel command line. If missing, prints GRUB configuration instructions and exits (token is not consumed). - Hugepages — Allocates 1024 x 2 MB hugepages (2 GB total), persisted via sysctl.
- VFIO module — Loads
vfio-pcikernel module and persists for reboot. - PCI detection — Scans PCI bus for Ethernet controllers via
lspci. - Management interface protection — Automatically detects the interface carrying the default route (SSH/management) and excludes it from DPDK binding.
- NIC binding — Unbinds selected NICs from kernel drivers and binds to
vfio-pci. - Restore service — Creates a systemd service that re-applies DPDK bindings on reboot.
MQTT Configuration
The installer configures the edge agent for mTLS MQTT:
- Protocol:
ssl://with TLS 1.2/1.3 - Server validation: Uses
MQTT_TLS_SERVER_NAMEfor SNI verification against the broker's certificate - Client authentication: Edge certificate and private key (from the provision bundle)
- Trust store: Contains both the tenant CA and the MQTT broker CA
Non-Interactive Mode
For automated deployments, use --force to skip all confirmation prompts:
sudo ./securelink-installer install \
--token NLZ-XXXX-XXXX-XXXX \
--url https://edge-api.vsm.netlinkz.dev \
--force
upgrade — Update an Existing Device
Regenerates configuration files without re-provisioning. Identity, certificates, and SSH access are preserved.
sudo ./securelink-installer upgrade --force
| Flag | Required | Description |
|---|---|---|
--data-dir | No | Override data directory (auto-detected) |
--images-dir | No | Directory containing Docker image tarballs to load |
--force | No | Skip confirmation prompts |
What Upgrade Does
- Load discovery config — Reads
discovery.jsonfrom the data directory - Load Docker images — Scans images directory for
.tar.gz/.tarfiles and loads viadocker load - Stop services — Stops Docker Compose and systemd service, removes orphaned containers
- Regenerate Docker Compose — Recreates compose file from discovery config using latest templates
- Regenerate Alloy config — Updates logging configuration
- Regenerate VPP config — Updates VPP startup configuration
- Validate SSH certificate — Checks host certificate validity and refreshes if expiring (< 30 days)
- Migrate tunnel config — If upgrading from v2.0, migrates SSH tunnel from legacy systemd service to agent-managed tunnel
- Start services — Restarts the systemd service
Typical Upgrade Workflow
# Using build-lab.sh (builds + deploys in one step)
./scripts/build-lab.sh .250
# Or manually:
scp securelink-installer agent-mqtt-cli-production.tar.gz edge@192.168.0.250:/tmp/
ssh edge@192.168.0.250 "sudo /tmp/securelink-installer upgrade --images-dir /tmp/ --force"
Upgrade requires discovery.json to exist. Devices provisioned before this feature was introduced must be re-installed with a new token.
status — Check Device State
Displays provisioning state and service health.
securelink-installer status
| Section | Shows |
|---|---|
| Identity | Device type, name, GUID, serial number, tenant |
| Discovery | Install timestamp, last upgrade, orchestrator URL, MQTT broker, Loki URL |
| Certificates | CA cert, device cert, private key (present or missing) |
| DPDK | PCI address-to-interface bindings (if applicable) |
| Configuration | Paths to compose, Alloy, VPP config files (present or missing) |
| Services | Systemd service status (active / inactive) |
| Containers | Running Docker containers |
factory-reset — Return to Factory State
Removes all provisioned data. The device must be re-provisioned with a new token.
sudo ./securelink-installer factory-reset
Factory reset permanently removes identity, certificates, SSH keys, configuration files, and DPDK bindings. The device cannot reconnect to the orchestrator without a new deployment token.
Deployment Token
Tokens are generated in the SecureLink management UI (Admin > System Settings > Deployment Tokens) or via the API. Each token:
- Follows the format
NLZ-XXXX-XXXX-XXXX(12-character body, 3 segments) - Uses an unambiguous character set (excludes
I,O,0,1) - Is single-use — once claimed, the token cannot be reused
- Must be used before it expires (configurable, default 7 days)
- Can be linked to a specific device (pre-registered) or unlinked (any device can claim it)
Device Type Differences
| Feature | Dedicated Edge | MTGE | Connector |
|---|---|---|---|
| VPP | DPDK or AF_PACKET | DPDK or AF_PACKET | None |
| Certificates | mTLS (CA + device cert + key) | mTLS | mTLS |
| SSH Tunnel | Yes (reverse tunnel to bastion) | Yes | No |
| DPDK Support | Optional | Optional | No |
| Suricata | Yes | Yes | No |
| Data Directory | /var/lib/edge | /var/lib/edge | /var/lib/connector |
| Compose File | edge-compose.yml | edge-compose.yml (EDGE_MODE=mtge) | connector-compose.yml |
Services Started
Edge / MTGE
| Container | Purpose |
|---|---|
| vpp-agent | VPP data plane (DPDK or AF_PACKET) |
| agent-mqtt-cli | Edge control agent (config sync, status publishing, SSH tunnel) |
| alloy | Log collection to Loki (Grafana Alloy) |
| dnsmasq | DNS / DHCP relay |
| bird | BGP routing daemon |
| suricata | IDS/IPS engine |
| strongswan | IPSec / IKEv2 daemon |
Connector
| Container | Purpose |
|---|---|
| connector-agent | Lightweight agent (WireGuard, iptables, routing) |
| bird | BGP routing daemon |
| strongswan | IPSec / IKEv2 daemon |
Verification
After installation, verify the device is operational:
# Check installer status
securelink-installer status
# Check systemd service
systemctl status edge-agent
# Check running containers
docker ps
# Check agent MQTT connection
docker logs agent-mqtt-cli 2>&1 | tail -20
# Check VPP interfaces (edges/MTGEs only)
docker exec vpp-agent vppctl show interface
The device should appear in the SecureLink management UI within 60 seconds (the first inform interval).
Troubleshooting
Token claim fails
- Verify the token hasn't already been used (tokens are single-use)
- Check network connectivity to the orchestrator URL
- Ensure the token hasn't expired
Docker installation fails
- Verify internet connectivity:
curl -fsSL https://get.docker.com - If behind a proxy, configure Docker proxy settings manually
- Try installing Docker manually:
curl -fsSL https://get.docker.com | sh
IOMMU not enabled (DPDK)
The installer will print GRUB configuration instructions:
- Edit
/etc/default/grub - Add
intel_iommu=on iommu=pttoGRUB_CMDLINE_LINUX - Run
sudo update-grub - Reboot
- Re-run the installer with the same token
DPDK binding fails
- Verify VT-d / IOMMU is enabled in BIOS
- Check that NICs support VFIO:
ls /sys/kernel/iommu_groups/ - Run
lspci -vto confirm Ethernet controllers are detected
MQTT connection fails
- Check the agent logs:
docker logs agent-mqtt-cli 2>&1 | grep -i mqtt - Verify the MQTT broker is reachable:
openssl s_client -connect mqtt.vsm.netlinkz.dev:8883 - Check certificates:
openssl x509 -in /var/lib/edge/certs/edge.crt -noout -dates
Services won't start
- Check Docker is running:
systemctl status docker - Check service logs:
journalctl -u edge-agent -f - Verify Docker images are loaded:
docker images
Device not appearing in UI
- Check MQTT connectivity:
docker logs agent-mqtt-cli 2>&1 | grep -i connect - Verify the MQTT URL uses
ssl://(nottcp://): checkedge-compose.yml - Check the orchestrator URL is reachable from the device