Systemd

Scouter Analytics Service

Depdendencies
pacman -S \
  elixir \
  erlang-asn1 \
  erlang-public_key \
  erlang-ssl \
  erlang-parsetools \
  erlang-syntax_tools \
  erlang-xmerl \
  erlang-sasl

There are many protective directives set here to harden the service as best we can.

/etc/systemd/system/analytics.service
[Unit]
Wants=network-online.target
After=network-online.target
Description=Analytics
PartOf=analytics.target
After=local-fs.target

[Service]
Restart=on-failure
DynamicUser=yes
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=disconnected
Type=notify
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
DevicePolicy=closed
LockPersonality=true
MemoryAccounting=true
MemoryDenyWriteExecute=true
ProcSubset=pid
ProtectClock=true
StateDirectory=scouter
Environment=HOME=%T
Environment=EVENT_DATABASE_PATH=%S/scouter/events.duckdb
Environment=DATABASE_PATH=%S/scouter/scouter.db
ExecStart=/opt/scouter/bin/scouter start

[Install]
WantedBy=multi-user.target default.target

Sockets

Alongside hardening directives, Scouter Analytics uses socket activation to avoid binding to priviliged ports and further reduce vulnerabilities.

An added benefit of socket activation is that zero downtime upgrades come for free. New and active connections are held by the socket systemd creates and are consumed by Scouter Analytics after startup.

There are two sockets: one for the dashboard; and one for the telemetry endpoint, where user visits are recorded.

/etc/systemd/system/analytics-dashboard.socket
[Unit]
Description=Scouter Dashboard Socket
PartOf=analytics.target

[Socket]
ListenStream=%t/scouter/dashboard.socket
Service=analytics.service
/etc/systemd/system/analytics-telemetry.socket
[Unit]
Description=Scouter Analytics Telemetry Socket
PartOf=analytics.target

[Socket]
ListenStream=%t/scouter/telemetry.socket
Service=analytics.service

Configuration

You'll need to set the *_HOST values to the domain you're using for Scouter Analytics. It's possible for both to share the same value.

Generate secret keys with openssl rand -base64 64 | tr -d '\n'

Generate signing salts with openssl rand -base64 32 | tr -d '\n'

/etc/systemd/system/analytics.service.d/web.conf
[Service]
Environment=DASHBOARD_HOST=
Environment=DASHBOARD_SOCKET=analytics-dashboard.socket
Environment=DASHBOARD_SECRET_KEY_BASE=
Environment=DASHBOARD_SIGNING_SALT=
Environment=TELEMETRY_HOST=
Environment=TELEMETRY_SOCKET=analytics-telemetry.socket
Environment=TELEMETRY_SECRET_KEY_BASE=
Environment=TELEMETRY_SIGNING_SALT=
/etc/systemd/system/analytics.service.d/other.conf
[Service]
Environment=AWS_ACCESS_KEY_ID=
Environment=AWS_SECRET_KEY=
Environment=S3_ENDPOINT=
Environment=RUN_MIGRATIONS=yes

Finally, a target unit groups all the previous units under a single name for ease of operation.

/etc/systemd/system/analytics.target
[Unit]
Description=Scouter Analytics
Requires=network.target analytics-dashboard.socket analytics-telemetry.socket
After=network.target

[Install]
WantedBy=multi-user.target