CCE

The Wobserver's Edge Server

Contents

The Wobserver is currently in my living room running on my Homelab Build, so how do you view these pages? Surely my home IP address is not blasted on to the web via DynDNS, right? Right.

The Edge Server is a small VM co-located with AS64241 in beautiful Seattle, Washington. Yours could be on AWS, or DigitalOcean, or Hetzner, or whatever, man; it could also be your home IP address blasted on to the web via DynDNS, but it doesn't need to be. The Edge Server can establish an encrypted connection to the Wobserver using Tailscale. SSL can be terminated by an NGINX and proxied to the Nginx on the far side, or transparently proxied for termination within the Wobserver.

Base NixOS Server Manifest

This thing is "just" an Arroyo System, it pulls its configuration from my Knowledge Base.

nix:tangle ~/nix/nixos/edge.nix:noweb yes:mkdirp yes
{ config, pkgs, lib, ... }:

{
  services.nginx.on-retreat.enable = false;
  services.nginx.on-retreat.returnDate = "28 July";

  services.tailscale.useRoutingFeatures = "server";
  networking.firewall.logRefusedConnections = false;

  imports = [
    # <<arroyo_nixos_imports()>>
    
    ../nixos/akkoma-media-proxy.nix
  ];
  
  home-manager.users.rrix.imports = [
    # <<arroyo_home-manager_imports()>>
  ];
  
  system.stateVersion = lib.mkDefault "24.11";

  home-manager.users.rrix = {
    home.stateVersion = config.system.stateVersion;
    # don't ship pinentry-qt
    services.gpg-agent.pinentryPackage = lib.mkForce pkgs.pinentry-curses;
  };

  services.prometheus.exporters.node = {
    enable = true;
    enabledCollectors = [ "systemd" ];
  };

  services.openssh.enable = true;

  environment.systemPackages = with pkgs; [
    pkgs.htop
  ];
}

Helpers

lua#+name: arroyo_nixos_imports:eval arroyo:results raw
local modules = arroyo.nixos_modules("edge")
local lines = {}
for i, m in ipairs(modules) do
    table.insert(lines, "../../" .. m)
end
return table.concat(lines, "\n")
lua#+name: arroyo_home-manager_imports:eval arroyo:results raw
local modules = arroyo.home_modules("edge")
local lines = {}
for i, m in ipairs(modules) do
    table.insert(lines, "../../" .. m)
end
return table.concat(lines, "\n")

The Edge Server's Base Nginx Forwarding configuration

The Edge Server mostly exists to serve My HTTP services and My Websites from The Wobserver to the web from a stable public IP address.

It's set up as a VM King Mountain right now but can quickly come up anywhere you can get a NixOS. Build a global content distribution network on the back of Tailscale's peering agreements, today!

nix:tangle ~/nix/nixos/nginx-edge.nix:noweb yes
{ config, pkgs, lib, ... }:

let
  enabled = config.services.nginx.on-retreat.enable;
  returnDate = config.services.nginx.on-retreat.returnDate;
  retreatPage = pkgs.replaceVars ../files/on-retreat.html {
    inherit returnDate;
  };
in
{
  options.services.nginx.on-retreat = with lib; {
    enable = mkEnableOption { name = "turn off sites while offline"; };
    returnDate = mkOption { type = types.str; default = ""; };
  };

  config = {
    networking.firewall.allowedTCPPorts = [ 80 22 443 ];

    services.logrotate = {
      enable = true;
      settings.nginx = {
        frequency = "daily";
        rotate = 365;
        compress = true;
        delaycompress = true;
      };
    };

    services.nginx.virtualHosts."fontkeming.fail" = {
      serverAliases = [
        <<mkVirtualHosts()>>
      ];

      forceSSL = true;

      locations = lib.mkMerge [
        # Retreat mode: serve the 503 page
        (lib.mkIf enabled {
          "/" = {
            return = "503";
            extraConfig = ''
              error_page 503 /503.html;
            '';
          };
        })

        # Normal mode: proxy everything
        (lib.mkIf (!enabled) {
          "/" = {
            proxyPass = "http://last-bank";
            extraConfig = ''
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header X-Forwarded-Host $http_host;
              proxy_set_header Host $host;
              proxy_read_timeout 600s;
              proxy_connect_timeout 600s;

              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
            '';
          };
        })

        {
          "=/503.html" = {
            alias = retreatPage;
            extraConfig = ''
              internal;
              add_header Content-Type text/html;
            '';
          };
        }
      ];
    };
  };
}

build a new qcow2

On Retreat page

html:comments none:tangle ~/nix/files/on-retreat.html
<!DOCTYPE html>
<html>
    <head>
        <title>The Arcology Site Network is temporarily offline</title>
    </head>
    <body>
        <h1>Ryan Rix is offline and AFK right now</h1>

        <p>They will be returning from a meditation retreat on <b>@returnDate@</b> and his sites will be offline until then. Thank you for understanding.</p>
        
        <p>Please contact <a href="https://bluecliffzen.org">Blue Cliff Zen Center</a> if you need to get ahold of them despite this. Be good and be good at it.</p>
    </body>
</html>

Helpers for Hosts

lua#+name: mkVirtualHosts:eval arroyo:results raw:var tbl=nginx-common.org:hosts
local lines = {}
for i, row in ipairs(tbl) do
    table.insert(lines, '"' .. row[1] .. '"')
end
return table.concat(lines, "\n")
"fontkeming.fail"
"dns.fontkeming.fail"
"docker.fontkeming.fail"
"scanner.fontkeming.fail"
"vault.whatthefuck.computer"
"kickass.systems"
"thelionsrear.com"
"arcology.garden"
"engine.arcology.garden"
"thechanceencounter.com"
"cce.whatthefuck.computer"
"whatthefuck.computer"
"files.fontkeming.fail"
"notes.whatthefuck.computer"
"i.notes.whatthefuck.computer"
"bag.fontkeming.fail"
"ring.whatthefuck.computer"
"media.whatthefuck.computer"
"feeds.whatthefuck.computer"
"dongiverse.com"
"links.fontkeming.fail"