Server operations & administration

Running a fleet of servers without losing the thread

One server is easy to administer. Ten turn the same routine gestures into a running cost: finding your way back in, re-deriving a hardening pass from memory, working out what changed since last week. This page collects the practices that hold up over time: taking stock of a machine, hardening SSH, reaching a box with no inbound port, writing runbooks people actually reopen, and keeping a trail of every operation.

07 sections07 questions09 min read

Terminal, files, scheduled commands — product preview03
web-01.eu — terminalsession #412 · re-attached

$

14:02:11 upstream timed out (110) — 2 hits

$ nginx -T | grep proxy_read_timeout

proxy_read_timeout 30s;

Unified history — every source, one list

aisystemctl reload nginxexit 0re-run
croncertbot renew --quietexit 0re-run
manualdocker system prune -fexit 0re-run
web-01.eu — /etc/nginxexplorer

conf.d/

ssl/

mime.types

nginx.conf

11keepalive_timeout 65;

12proxy_read_timeout 60s;

13gzip on;

✓ savedatomic write · -rw-r--r-- kept

$ nginx -t && systemctl reload nginx

syntax is ok · reload complete

upload · download · rename · chmod — all signed in your browser

scheduled — 3 activeagent-local
certbot renew0 3 * * 1Mon 03:00
14/14 okrun now
pg_dump nightly0 2 * * *02:00
14/14 okrun now
docker prune30 4 * * 0Sun 04:30
14/14 okrun now

runs even with the browser closed · alert after N failures

SEC.01 — Taking stock

Where do you start on a server you did not install?

With a read-only survey, before touching anything. Distribution and running kernel, failed units, listening sockets, accounts with a valid shell, authorised SSH keys, scheduled jobs, filesystem usage. An hour of inventory is what keeps you from operating blind the day the box goes down.

Order matters. Look at what listens on the network first, because that is the surface anyone can reach today. Then at what starts at boot, because that is what comes back after a reboot. Then at what consumes, because a full disk causes failures that no application log announces in advance. A server inherited from a previous provider almost always carries a forgotten public key in an authorized_keys file, or a cron job shipping data somewhere nobody watches any more.

None of it counts unless it is written down. An inventory typed into a terminal dies with the tab. The useful minimum is a few lines per machine: role, owner, what runs on it, what you are allowed to restart, and who to call. That document, not an operator's memory, is what holds at three in the morning.

  1. 01ss -tulpn: what listens and which process owns it, compared against what you believe is exposed.
  2. 02systemctl list-units --failed and systemctl list-timers: dead services and forgotten scheduled work.
  3. 03getent passwd, the sudo rules, and every authorized_keys file: who can get in, and with what rights.
  4. 04journalctl -p err -b: errors from the current boot, before one of them becomes an incident.
  5. 05df -h and du -xh --max-depth=1 /var: a full disk is still the most common and most preventable outage.

SEC.02 — Hardening SSH

How do you harden SSH without locking yourself out?

Keep a session open for the whole operation, validate the configuration with sshd -t before reloading the service, and open a second terminal to test the new settings before closing the first one. A reload leaves established sessions alone; a restart on a broken config does not.

The hardening itself is a short list of directives. Once your keys are in place and proven: PasswordAuthentication no, KbdInteractiveAuthentication no, PermitRootLogin prohibit-password or no, AllowUsers or AllowGroups to name the permitted accounts explicitly, a low MaxAuthTries, a short LoginGraceTime, agent forwarding off by default. On current distributions, put these in a dedicated file under /etc/ssh/sshd_config.d/ rather than editing the packaged config, so the next package update does not quietly revert them.

Moving SSH off port 22 cuts the volume of recorded attempts, not the actual risk: a targeted scan finds the service in seconds. The real benefit is readable logs. What secures a VPS is key-based authentication, banning offending addresses with fail2ban, a firewall that opens only what is needed, and unattended security updates. The OpenSSH documentation and the CIS Benchmarks are the two references worth keeping open while you work.

  1. 01Install your public key and confirm it works before disabling password authentication.
  2. 02Write directives into a file under /etc/ssh/sshd_config.d/, never into the file shipped by the distribution.
  3. 03Run sshd -t, reload, then open a second session to test. The first session is your way back in.
  4. 04Arrange out-of-band access (your provider's serial or KVM console) before touching firewall rules.

SEC.03 — No inbound port

How do you reach a machine behind NAT or a VPN with no inbound port?

Three options: expose SSH to the internet, jump through a bastion with ProxyJump, or have the machine open the connection itself, over an encrypted network such as WireGuard or Tailscale, or through an outbound agent. The last two need no inbound port at all.

What determines your exposure is simply this: who opens the connection. A listening port on a public address is scanned continuously, whatever number you give it, and has to be defended around the clock. A connection established outbound from the machine to a rendezvous point cannot be reached from outside; there is nothing there to find. The same reasoning is why an outbound tunnel beats a port forward on a corporate network whose perimeter firewall is not yours to change.

A bastion still has one real advantage: it concentrates access and logs, which makes auditing straightforward. Its weaknesses are equally well known, a single point of failure and an attractive target. An outbound tunnel moves the trust question to the rendezvous point instead: what does it see, and what does it keep? That is the question to put to any remote access tool, a web SSH terminal included. Does it hold your credentials, in what form, and who is able to decrypt them?

SEC.04 — Runbooks

What separates a runbook people use from a note nobody reopens?

A usable sysadmin runbook states its trigger, lists preconditions you can check, gives commands you can paste without mental translation, ends with a verification that fails when the operation failed, and describes how to roll back. Missing any of those five, it is a note rather than a procedure.

Write it during the first run, while you still remember why a flag is there and which error you hit. Fix it during the second, when the gap between what is written and what you actually type becomes visible. A runbook that has not been replayed in six months should be treated as wrong until proven otherwise.

Idempotence is what makes the difference under pressure: a procedure you can rerun without breaking the current state can be read calmly in the middle of the night. In practice that means testing before creating, writing complete configuration files instead of appending lines, and reloading a service rather than restarting it where the software allows. Say what the runbook does not cover, too. The case where the final check fails deserves a line, even if that line only names the person to call.

  1. 01Trigger: the situation that makes you open this runbook, and the ones that do not.
  2. 02Preconditions: system version, service in scope, a copy of the existing configuration.
  3. 03The exact commands, in order, with no implicit variable left to the reader's judgement.
  4. 04Verification: a command whose exit code tells you whether the operation actually worked.
  5. 05Rollback: how to get back to the previous state, and the point past which you no longer can.

SEC.05 — Multiple machines

How do you manage multiple servers without repeating the same work ten times?

By separating two needs that get conflated: holding a desired state, which is declarative configuration management, and intervening live, which is operations. A tool like Ansible converges a fleet; it does not replace the session you open at two in the morning while an incident is running.

Three habits cover most of the drift. A naming convention that encodes role and environment, because the most expensive mistake remains the right command on the wrong machine. One inventory that acts as the single source, instead of three files that disagree. And a per-machine history, so that "what changed since last week?" has an answer nobody has to reconstruct from memory.

Operations tooling is then judged on three questions: can the same operation be applied to a group of machines, can you find what was done on a given box, and can you see its current state in the same place? That is the gap Servor works on. The 150+ official recipes it ships (nginx, Caddy, Apache, PostgreSQL, MySQL, Redis, Docker, Podman, WireGuard, Tailscale, SSH hardening, fail2ban, UFW, unattended upgrades, among others) turn routine work into replayable procedures — the catalogue is searchable by intent, typing "firewall" is enough to surface ufw, and it is published openly at /recipes — and every run lands in one unified history with its output, exit code and duration, re-runnable in one click.

SEC.06 — Traceability

Who ran that command, on which machine, and what came back?

Shell history does not answer that. It belongs to one user, that user can edit it, rotation truncates it, and it says nothing about the result. A trail you can actually work from records the operator, the machine, the exact command, the timestamp, the exit code and the output.

The system pieces exist: sudo logging, auditd for sensitive syscalls, journald forwarded to a remote collector so a local compromise cannot erase the evidence. They serve a compliance audit well. They serve a team's daily question less well, which is what was done on this box last night, by whom, and whether it worked. That is an operations need before it is a security need.

Servor records every command in one place regardless of origin, whether typed by hand, run from a runbook, executed in the terminal or proposed by the AI copilot, along with its output, exit code and duration. On top of that sits a hash-chained audit log, write-only at the database level: an entry cannot be modified or deleted. For an agency operating servers on behalf of several clients, that is the difference between stating what was done and showing it.

SEC.07 — Servor day to day

What does Servor change about day-to-day operations?

Servor brings the terminal, the file explorer, scheduled commands, monitoring, status pages and recipes for all your servers into one console, with an AI copilot that proposes an action, waits for your approval, then verifies the result. The scope is operations: reaching the machine, working on it, watching it, communicating its state, recording who did what. Servor does not deploy applications and does not provision infrastructure. It operates the servers you already have, alongside whatever you deploy with.

Access goes through an agent installed on the machine, a single compiled binary published for seven targets (Linux x64 and arm64, glibc and musl, macOS x64 and arm64, Windows x64). It opens no port: the agent establishes the outbound connection, which is what makes it work behind NAT, a corporate firewall or a VPN-only network. It runs as the configured system user and never receives a credential. The web terminal is re-attachable, so closing the tab does not kill the shell — with scrollback search, copy and export, and per-user preferences — and a command started from the form runs to completion even if the browser drops. Scheduled commands follow the same logic: delivered to the agent as cron definitions, they run locally, guarded by the denied-command list, with a per-task history of the last twenty runs, an on-demand run-now, a bulk maintenance pause and an optional alert after several consecutive failures. The same agent pushes metrics every 15 to 300 seconds and runs checks itself, which makes them independent of any open session: eleven check types, from HTTP and TCP to SSL certificates, disk space, custom scripts, heartbeat and a threshold on the metrics the agent already reports, with configurable hysteresis so a single blip does not flip a monitor.

That leaves credential handling, the sensitive part of any administration console. The passphrase, the key derived with Argon2id and the X25519 private key never leave the browser; secrets are encrypted with AES-256-GCM, and every command is signed in the browser with an Ed25519 key derived from the vault, then verified on the target machine itself. The direct consequence: the server cannot read your credentials, and a compromised control plane cannot forge an execution. The trade-off is deliberate and worth knowing upfront, because losing both the passphrase and the 24-word recovery phrase makes the data permanently unrecoverable.

  1. 01Three approval modes: Plan approves command by command and is the default, Ask stays effectively read-only, Auto interrupts only on a destructive command. The guardrails lower the risk, they do not remove it.
  2. 02Strict mode: a server can be installed for supervision only, with the control plane refusing any execution on it.
  3. 03Plans: Free covers two servers; Operations at 9 EUR per month excl. tax covers ten servers with 30 monitors and 10 status pages; AI at 29 EUR per month excl. tax covers fifty servers with unlimited monitors, the copilot and 3,000 monthly credits.
  4. 04Out of scope, worth knowing before you try it: no backup or restore handled by the product, no provisioning at a hosting provider, and checks that run from a single observation point.
Agent and execution
Agent targets
7 — Linux x64/arm64 (glibc, musl), macOS x64/arm64, Windows x64
Inbound ports
none — the machine opens the connection
Metrics
pushed every 15 to 300 seconds
Checks
9 types, run by the agent
Scheduled commands
cron run locally by the agent · last 20 runs kept
Official recipes
150+ shipped · public directory at /recipes
Encryption
Argon2id → X25519 → AES-256-GCM, in the browser
Execution signature
Ed25519, verified on the target machine

SEC.08

Frequently asked

Short answers to the questions this page raises most often.

01Do you have to expose SSH to the internet to manage a server remotely?

No. A bastion jump with ProxyJump, an encrypted network such as WireGuard or Tailscale, or an agent that opens an outbound connection all give the same access with no inbound port. Anything listening on a public address has to be defended continuously; anything dialling out is not reachable from the internet.

02Does changing the SSH port actually make a server safer?

It cuts the noise from automated scanners and makes your logs readable again, and that is all: a targeted scan finds the service in seconds. Key-based authentication, disabling passwords, restricting which accounts may log in, and unattended security updates do far more to secure a VPS.

03Is a web SSH terminal less secure than a local client?

It depends entirely on who holds the key and where it is decrypted. The question to ask a vendor is specific: do the passphrase or the private key ever pass through their servers? In Servor, derivation and decryption happen in the browser, and each command is signed client-side then verified on the target machine.

04How many servers before an operations tool is worth it?

The threshold has more to do with the number of operators than the number of machines. Alone on three VPS, a notes file and a well-kept ~/.ssh/config go a long way. With two or more people on the same boxes, shared history and a record of who did what become the real requirement.

05Does Servor replace Ansible or configuration management?

No, they answer different questions. Configuration management converges a fleet toward a declared desired state. Servor covers day-to-day operations: getting in, running things, watching, recording, communicating during an incident. The two coexist without stepping on each other.

06Can recurring commands be scheduled without a crontab?

Yes. Scheduled commands are defined in the console with a cron expression, delivered to the agent and run locally on the machine, guarded by the denied-command list — no browser session required. Each task keeps its last twenty runs with their output, shows its next run in the server's local time, and can alert a channel after several consecutive failures.

07Can the AI copilot run a command without approval?

In Plan mode, the default, every command is approved in the interface before it runs; Ask stays effectively read-only and Auto interrupts only on a destructive command. A blocked-command list is enforced on both the server and the agent, and every execution is logged. The operator stays responsible for what reaches the machine.

Keep reading

The rest of the deck

Take your fleet back in hand

Install the agent on one machine and judge from there: a re-attachable terminal, recorded executions, runbooks and monitoring in the same place. The Free plan covers two servers, with no commitment.

Start for free

Free for 2 servers · no credit card · hosted in the EU