Skip to content

Design for installation & update process

Marek Rogalski edited this page Jun 27, 2023 · 12 revisions

Goals

  • install with a single shell command
  • install by downloading & running a single binary file
  • entire config stored in a single file, easy to export from web UI
  • APT-resistant update mechanism
  • automatic updates by default
  • opt-out of automatic updates (needs auth)

Assumptions

  • install directory is always /opt/gatekeeper/
  • OS services are always managed through systemd

Installation

Single command version:

curl https://github.com/mafik/gatekeeper/releases/gatekeeper-latest -o gatekeeper && chmod +x gatekeeper && sudo ./gatekeeper
  1. (if not root) Gain root privileges (execve sudo argv[0])
  2. (if not installed and PORTABLE not in env) Install
    • explain the process on STDOUT
    • show 10-second countdown
    • unpack embedded files to /opt/gatekeeper/
    • link the systemd service
    • start the service
    • execve journalctl -fu gatekeeper
  3. Otherwise (root & PORTABLE or running from /opt/gatekeeper/) - proceed to Startup

Startup

  1. Show greeting on STDOUT
  2. Update /opt/gatekeeper/ based on embedded files
  3. Check each network interface and classify into (WAN, LAN, IGNORE)
    • also find a free private IP subnet (preferably 10.0.0.1/16)
  4. (if not configured) Configure the WAN interface with DHCP
  5. (if not configured) Configure the LAN interface with 10.0.0.1/16
  6. Start DNS, DHCP & HTTP servers
  7. Notify systemd about completed startup, respond to watchdog pings
  8. Pick a random time uniformly between 0 and 24h, after specified time, and then after every 24h, perform Update

Update

  1. Gatekeeper receives an update package (through regular polling or push message)
    1. HTTPS polling
      • no-go due to reliance on additional actors that might exploit the network
    2. TCP Polling
      • Periodically connect to a central server (TCP port 1338)
      • Encrypt connection (hardcoded ECC key, then switch to AES-256)
      • Client advertises its version
      • Server may provide update package in the response
      • [+] gradual rollouts with stability monitoring on the central server
      • [-] centralized (single point of failure, ongoing maintenance costs) (at 1e6 clients, ~12 connections / second)
    3. Push message
      • Gatekeeper instances form an overlay network
      • All connections encrypted (DH + AES-256)
      • Peers advertise their versions
      • When a peer has a more recent version and more than 24 hours of uptime (maybe less for urgent updates), it pushes its update to other peers
      • [+] distributed, arbitrary number of peers
      • [-] self-supervised rollout (no monitoring, potential catastrophic failure on bad update)
      • note: interesting library for overlay networks https://github.com/hmatuschek/libovlnet/tree/master/src
  2. Update is verified against hardcoded ECC key
  3. Server replaces its own binary with the updated one and requests systemd restart

Configuration

All configuration is done through environment variables. Default (read-only) values are stored at /opt/gatekeeper/gatekeeper.service but may be overridden using systemctl edit.

Gatekeeper persists its own configuration by altering /etc/systemd/system/gatekeeper.service.d/override.conf (the same as systemctl edit).

TODOs

  • Installation
    • (optional) Function that restarts the current process as root (execve sudo argv[0], also graphically - with something like gksu)
    • Installation check (not running under systemd and no PORTABLE in env)
    • Installation explainer & countdown
    • Embed necessary files in the binary
    • Extract embedded files during installation
    • systemctl enable --now /opt/gatekeeper/gatekeeper.service during installation
    • execve journalctl -fu gatekeeper after installation completes
  • Startup
    • Classify network interfaces into LAN / WAN / IGNORE
    • Find a free private IP subnet
    • (if not configured) Configure WAN interface with DHCP
    • (if not configured) Configure LAN interface
      • Assign IP & network mask
      • Bring interface up
      • Enable IP forwarding
      • Enable NAT masquerade
    • Start DHCP, DNS & HTTP servers
    • Notify systemd about completed startup
    • Respond to watchdog pings
  • (Proper, mesh-based) Update
    • Functions for ECC crypto
    • Functions for AES crypto
    • Functions for signing ELF files with ECC keys & verifying signatures
    • Functions for secure communication
    • Update server & code for the client
    • Schedule & periodically run updates
    • Replace own binary & restart after update
  • (Hacky, HTTP-based) Update
    • Functions for ECC crypto
    • Functions for signing ELF files with ECC keys & verifying signatures
    • Well-known URL for distributing updates
    • Schedule & periodically run updates
    • Replace own binary & restart after update