sitescope a small health monitor and status page for a few hosts

Start

Getting started

Add the flake, turn on a hub and its agents, store two tokens in the vault, unlock it. Most of the work is writing down what you expect your hosts to look like.

Requirements

Add the flake

inputs.sitescope.url = "github:toppk/sitescope";
inputs.sitescope.inputs.nixpkgs.follows = "nixpkgs";

and import inputs.sitescope.nixosModules.default on each host.

Write the environment file

On every host, outside the Nix store and readable only by root:

# /var/lib/sitescope-secrets/sitescope.env
SITESCOPE_AGENT_TOKEN=<the same long random value on every host>
SITESCOPE_HEARTBEAT_URL=https://hc-ping.com/<uuid>     # hub only

openssl rand -hex 32 makes a good token.

Turn on the hub

On the host that watches the others (it can watch itself too):

services.sitescope = {
  enable = true;
  role = "hub";
  agent = { enable = true; listenAddress = "10.0.0.2"; };   # this host's wg0 address
  environmentFile = "/var/lib/sitescope-secrets/sitescope.env";
  settings = import ./sitescope-settings.nix { inherit lib; };
};
users.users.alice.extraGroups = [ "sitescope-admin" ];
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 9105 ];

Point the reverse proxy for your status hostname at 127.0.0.1:8470.

Turn on the agents

On every other host:

services.sitescope = {
  enable = true;
  role = "agent";
  listenAddress = "10.0.0.3";    # this host's wg0 address
  environmentFile = "/var/lib/sitescope-secrets/sitescope.env";
};
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 9105 ];

The agent turns on its postfix and Knot sections by itself when those services are enabled on the host.

Describe what you expect

settings is where the hosts, zones, certificates and URLs go. A minimal start:

{
  alerts = { enabled = true; from = "sitescope@example.org"; to = [ "ops@example.org" ]; digestTime = "08:00"; };
  hub.publicURL = "https://status.example.org";
  hosts.hosts = [
    { name = "a"; url = "http://10.0.0.1:9105"; knot = true; }
    { name = "b"; url = "http://10.0.0.2:9105"; postfix = true; }
  ];
  dns = { zones = [ "example.org" ]; primary = "10.0.0.1"; };
  tls.targets = [ { name = "www.example.org"; } ];
  http.targets = [ { name = "www"; url = "https://www.example.org/"; } ];
}

Configuration lists every key, and Checks what each section checks. Before deploying, try it:

nix build github:toppk/sitescope
nix eval --json .#nixosConfigurations.hub.config.services.sitescope.settings > /tmp/sitescope.json
./result/bin/sitescope check -config /tmp/sitescope.json

Set up the vault

After the first deploy, on the hub host:

sudo -u sitescope sitescope vault set linode_token        # creates the vault, asks for a new passphrase twice
sudo -u sitescope sitescope vault set cloudflare_token
sudo -u sitescope sitescope vault set-password            # password for the detail view (user "admin")
sitescope unlock

The hub sends “vault LOCKED” email every time it starts, and the hub.vault check warns if the vault is still locked 15 minutes later. Run sitescope unlock again after each restart. See Vault and secrets.