# Hardening and Tuning the Host

> engine setup can also harden and tune the machine the engine runs on. Both are off unless you ask for them. The install command from add engine runs engine setup --dedicated, which turns both on.

**URL:** https://inference.sh/docs/private/host-setup
**Last updated:** 2026-11-09

---

`engine setup` can also harden and tune the machine the engine runs on. Both are off unless you ask for them. The [install command](/docs/private/installing#install) from **add engine** runs `engine setup --dedicated`, which turns both on.

Setup is Linux only: Ubuntu 22.04+ or Debian 12+. Engine **v1.21.52** and later.

| Flag | Subcommand | Does |
|------|------------|------|
| `--harden` | `engine setup harden` | SSH by key only, unattended security updates, a check for public listeners |
| `--tune` | `engine setup tune` | CPU governor `performance`, boost on; huge page report, or a pool with `--hugepages-gib` |
| `--dedicated` | `engine setup dedicated` | Both. For a server that only runs the engine |

The subcommands run those steps alone. `engine setup --plan --dedicated` prints what setup would change and changes nothing.

```bash
sudo engine setup --dedicated --token infen-...   # full setup, hardened and tuned
sudo engine setup harden                          # harden an engine that is already set up
sudo engine setup tune --hugepages-gib 32         # tune, with a 32 GiB pool of 2 MiB pages
```

Leave both off on a computer you also use for other work (a laptop, a shared server).

---

## Harden

Three steps.

**ssh-keys-only.** Writes `/etc/ssh/sshd_config.d/00-infsh-harden.conf`:

```text
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
```

`PermitRootLogin` is left out when sshd already has `no` or `forced-commands-only`. sshd keeps a setting's first value and reads `sshd_config.d` in name order, so the `00-` name wins over drop-ins that hosting images ship (for example a `01-…conf` with `PasswordAuthentication yes`).

Before sshd reloads (a reload keeps open sessions), setup runs `sshd -t` and `sshd -T`. If either fails, or `sshd -T` still shows passwords on (`sshd_config` sets them above its `Include`, or a drop-in named before `00-infsh-harden.conf` does), setup removes its drop-in, so sshd keeps the config it had, and the step fails.

Setup refuses (exit code 2, nothing changed) when:

- no account (root, `/home/*`) has a key in `~/.ssh/authorized_keys`
- sshd has `PubkeyAuthentication no`
- `/etc/ssh/sshd_config` does not include `sshd_config.d/*.conf` (setup does not edit the main file)

A host with no SSH server skips the step.

**security-updates.** Installs `unattended-upgrades` and writes `/etc/apt/apt.conf.d/52infsh-security`: the distro's security pocket only, and `Automatic-Reboot "false"`. Setup never reboots the host for an update; `engine doctor` says when one is pending.

On a GPU host the NVIDIA driver's userspace packages (`nvidia-*`, `libnvidia-*`, `xserver-xorg-video-nvidia-*`) are excluded. Upgraded under a loaded kernel module, they stop matching it until a reboot. Apply them on a drained reboot. Canonical's prebuilt kernel modules are not excluded, so a security kernel update still boots with a driver.

**public-listeners.** A check only. It fails when anything other than sshd (or a DHCP client) listens on a public address, and names the process. Setup changes no firewall. Stop the process or bind it to a private address.

---

## Tune

**cpu-governor.** Sets every cpufreq policy's governor and energy performance preference to `performance`, and turns boost on (`cpufreq/boost`, a policy's `boost`, or `intel_pstate/no_turbo`). The systemd unit `infsh-tune.service` sets them again at every boot (`infsh-cpu-tune.service` before engine#637; see [THP always](#thp-always)). A host with no cpufreq (most VMs) has nothing to set. A boost the BIOS or CPU refuses is reported, not failed.

**hugepages.** Reports the transparent huge page (THP) mode and the 2 MiB huge page pool. THP is left as it is up to engine v1.21.52; see [THP always](#thp-always) for the next release.

`--hugepages-gib N` reserves N GiB of 2 MiB pages at boot (`/etc/sysctl.d/60-infsh-hugepages.conf`) and grows the live pool to it now. Sandbox VMs use the pool for their memory while it has room. Setup refuses when:

- less than 8 GiB, or 25% of RAM if that is more, would stay outside the pool
- N is more than the RAM
- the default huge page size is not 2048 KiB
- `/proc/sys` is read-only (a container)

A smaller N, or `0` (removes the file), takes effect at the next reboot. The live pool is never shrunk: running sandboxes may still map it. When the kernel reserves fewer pages than asked (memory too fragmented), `engine doctor` warns; free memory and run `sudo engine setup tune` again, or reboot.

SMT, C-states, the kernel command line and irqbalance are left as they are.

### THP always

Ships with engine#633/#637 (the engine release after v1.21.52).

- The hugepages step sets THP to `always` now and at every boot. Under `madvise`, sandbox VM memory gets no huge pages; under `always` it gets nearly all of it. On a Ryzen 9950X a sandbox's kernel boot went from 328 to 91 ms and its first command from 424 to 155 ms.
- THP `never` is left as it is, as the host admin's choice. `engine doctor` warns on the **Huge pages** line and prints how to change it: `echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabled`, then `sudo engine setup tune`.
- A read-only `/sys` (a container) or a kernel without THP: `not adjustable here`.
- THP's `defrag` setting is left as it is.
- One boot unit, `infsh-tune.service`, sets both the CPU settings and THP. On a host set up with v1.21.52, the next `sudo engine setup tune` writes `infsh-tune.service`, then disables and removes `infsh-cpu-tune.service`. Until then `engine doctor --tune` fails with `infsh-cpu-tune.service is still there (infsh-tune.service replaces it)`.

---

## Check with engine doctor

After a setup with `--harden` or `--tune`, `engine doctor` adds their lines by itself. `engine doctor --harden`, `--tune` and `--dedicated` (both) add them on any host.

| Line | Shows |
|------|-------|
| **SSH logins** | `keys only (passwordauthentication no, permitrootlogin …)`, or what still takes passwords |
| **Security updates** | The archive unattended-upgrades takes, no automatic reboot |
| **Public listeners** | `none`, `only sshd`, or what listens on a public address |
| **Reboot** | `none pending`, or that the distro asks for one (`/run/reboot-required`) and for which packages |
| **NVIDIA security update** | GPU hosts: NVIDIA updates held for a drained reboot |
| **CPU governor** | `performance on N policies (driver), boost on`; `not adjustable here (VM)` on a VM |
| **Huge pages** | THP mode and the pool, reserved and free; with engine#637, fails when THP is not `always` (`Firecracker's guest memory gets no huge pages`) |
| **Core pinning** | Whether boxd pins sandboxes to cores |

Each failed line names the fix, usually `sudo engine setup harden` or `sudo engine setup tune`. Without `sudo`, checks that need root to read warn instead of failing.

On macOS and Windows, `engine doctor --harden` and `--tune` print one line each: `Linux only: nothing to check on darwin` (or `windows`).

---

## Next

| Doc | Topic |
|-----|-------|
| [Installing the engine](/docs/private/installing) | Install and enroll |
| [Managing engines](/docs/private/managing-engines) | Drain, update, cloud engines |
| [Engines API](/docs/api/rest/engines) | `system_info.host_cpu` reports governor, boost, THP and the pool |
