Buildroot
ShellHub maintains a Buildroot external tree, so a manufactured unit arrives with the agent already on it. Use it rather than writing a package yourself.
Prerequisites
- A Buildroot tree
- A provisioning key, so units register themselves with nobody present
Adding the external tree
$ git clone git://git.buildroot.net/buildroot
$ git clone https://github.com/shellhub-io/buildroot.git shellhub
Point Buildroot at it with BR2_EXTERNAL, here against the emulated target:
$ cd buildroot
$ make BR2_EXTERNAL=../shellhub qemu_x86_64_defconfig
Selecting the package
$ make BR2_EXTERNAL=../shellhub menuconfig
Select shellhub under External options, then build.
The package needs a toolchain with threads and Go support for your target
architecture, and pulls in ca-certificates and libxcrypt. Buildroot selects both for
you.
The external tree pins the agent version it builds. Check that pin against the version
your server expects, which it publishes at /info.
Configuring it
Configuration is a root filesystem overlay. Write the file the service reads:
$ cat > rootfs_overlay/etc/default/shellhub-agent <<-EOF
SERVER_ADDRESS="https://cloud.shellhub.io"
PRIVATE_KEY="/etc/shellhub-agent.key"
PROVISIONING_KEY="<your-provisioning-key>"
EOF
TENANT_ID is the deprecated alternative to PROVISIONING_KEY, and the two do not go together.
Set the provisioning key.
Why the tenant is the wrong one. A device registering with the tenant alone goes through the namespace’s legacy registration path, which holds it for manual review — so a production run arrives as a queue of pending devices rather than a working fleet. A provisioning key also carries tags, so a policy can cover the batch before anybody opens the console. See Using provisioning keys.
The key must be writable and must not be in the overlay
The agent generates its device key when the file is missing. Two consequences, and both of them bite in production:
PRIVATE_KEY has to point somewhere writable that survives a reboot. On a read-only
root filesystem, or a path on a volatile partition, every boot produces a new identity and
a new device in the console.
Never put a generated key in the overlay. Every unit written from that image claims the same identity, and you get a single device that appears to move between machines instead of a fleet. The overlay carries the configuration; the key is created on the device, once.
Init systems
The package installs a systemd unit or an S42shellhub sysvinit script, following the
init system your configuration selects. Neither needs configuration beyond the overlay
above.
Verifying
Write the image to two devices and start both.
Expected result: Two devices appear, each carrying the provisioning key’s tags, and each with its own identity.
Troubleshooting
| Problem | Solution |
|---|---|
| A new device appears at every boot | PRIVATE_KEY is not writable, or does not survive a reboot |
| One device that keeps changing machine | A key was baked into the overlay. Remove it |
| Devices arrive pending instead of accepted | The overlay sets TENANT_ID rather than PROVISIONING_KEY, or the key’s mode is manual |