From f475b1f56cc8cc760df54e4c17092906b0497dc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicolas=20=E2=80=9CNiols=E2=80=9D=20Jeannerod?=
 <nicolas.jeannerod@moduscreate.com>
Date: Wed, 15 Jan 2025 16:22:35 +0100
Subject: [PATCH] Move web server definition to `infra`

---
 README.md                         |   4 -
 infra/README.org                  |   1 +
 infra/flake-part.nix              |  18 ++
 infra/vm02117/default.nix         |  27 +++
 infra/vm02117/website.nix         |  71 ++++++++
 keys/systems/vm02117.pub          |   1 +
 server/README.md                  |  15 --
 server/configuration.nix          | 275 ------------------------------
 server/default.nix                |  46 -----
 server/hardware-configuration.nix |  34 ----
 server/shell.nix                  |   1 -
 11 files changed, 118 insertions(+), 375 deletions(-)
 create mode 100644 infra/vm02117/default.nix
 create mode 100644 infra/vm02117/website.nix
 create mode 100644 keys/systems/vm02117.pub
 delete mode 100644 server/README.md
 delete mode 100644 server/configuration.nix
 delete mode 100644 server/default.nix
 delete mode 100644 server/hardware-configuration.nix
 delete mode 100644 server/shell.nix

diff --git a/README.md b/README.md
index 71ce7496..88f19fd2 100644
--- a/README.md
+++ b/README.md
@@ -24,10 +24,6 @@ details as to what they are for. As an overview:
 - [`secrets/`](./secrets) contains the secrets that need to get injected into
   machine configurations.
 
-- [`server/`](./server) contains the configuration of the VM hosting the
-  website. This should be integrated into `infra/` shortly in the future, as
-  tracked in https://git.fediversity.eu/Fediversity/Fediversity/issues/31.
-
 - [`services/`](./services) contains our effort to make Fediverse applications
   work seemlessly together in our specific setting.
 
diff --git a/infra/README.org b/infra/README.org
index 80cbd011..fd193229 100644
--- a/infra/README.org
+++ b/infra/README.org
@@ -29,6 +29,7 @@ infrastructure.
 | Machine | Proxmox     | Description            | Deployment |
 |---------+-------------+------------------------+------------|
 | vm02116 | Procolix    | Forgejo                | ~git~      |
+| vm02117 | Procolix    | Web server             | ~web~      |
 | vm02179 | Procolix    | /unused/               | ~other~    |
 | vm02186 | Procolix    | /unused/               | ~other~    |
 | vm02187 | Procolix    | Wiki                   | ~web~      |
diff --git a/infra/flake-part.nix b/infra/flake-part.nix
index cf99d619..c2a154e5 100644
--- a/infra/flake-part.nix
+++ b/infra/flake-part.nix
@@ -51,6 +51,24 @@
       providers.local = inputs.nixops4-nixos.modules.nixops4Provider.local;
 
       resources = {
+        vm02117 = {
+          type = providers.local.exec;
+          imports = [ inputs.nixops4-nixos.modules.nixops4Resource.nixos ];
+          ssh = {
+            host = "185.206.232.106";
+            opts = "";
+            hostPublicKey = self.keys.systems.vm02117;
+          };
+          nixpkgs = inputs.nixpkgs;
+          nixos.module = {
+            imports = [
+              ./vm02117
+              self.nixosModules.ageSecrets
+              { fediversity.hostPublicKey = self.keys.systems.vm02117; }
+            ];
+          };
+        };
+
         vm02187 = {
           type = providers.local.exec;
           imports = [ inputs.nixops4-nixos.modules.nixops4Resource.nixos ];
diff --git a/infra/vm02117/default.nix b/infra/vm02117/default.nix
new file mode 100644
index 00000000..7096fcd7
--- /dev/null
+++ b/infra/vm02117/default.nix
@@ -0,0 +1,27 @@
+{
+  imports = [
+    ../common
+  ];
+
+  procolix.vm = {
+    name = "vm02117";
+    ip4 = "185.206.232.106";
+    ip6 = "2a00:51c0:12:1201::106";
+  };
+
+  ## vm02117 is running on old hardware based on a Xen VM environment, so it
+  ## needs these extra options. Once the VM gets moved to a newer node, these
+  ## two options can safely be removed.
+  boot.initrd.availableKernelModules = [ "xen_blkfront" ];
+  services.xe-guest-utilities.enable = true;
+
+  fileSystems."/" = {
+    device = "/dev/disk/by-uuid/5aa392a8-c9ba-4181-976f-b3b30db350a1";
+    fsType = "ext4";
+  };
+
+  fileSystems."/boot" = {
+    device = "/dev/disk/by-uuid/FC6D-610F";
+    fsType = "vfat";
+  };
+}
diff --git a/infra/vm02117/website.nix b/infra/vm02117/website.nix
new file mode 100644
index 00000000..856cfe5e
--- /dev/null
+++ b/infra/vm02117/website.nix
@@ -0,0 +1,71 @@
+{
+  services.nginx.enable = true;
+
+  services.nginx.virtualHosts."www.oid.foundation" = {
+    useACMEHost = "oid.foundation";
+    forceSSL = true;
+    globalRedirect = "oid.foundation";
+  };
+
+  services.nginx.virtualHosts."oid.foundation" = {
+    enableACME = true;
+    forceSSL = true;
+    root = "/var/www/oid.foundation";
+
+  };
+
+  services.nginx.virtualHosts."fediversity.eu" = {
+    useACMEHost = "www.fediversity.eu";
+    forceSSL = true;
+    globalRedirect = "www.fediversity.eu";
+    locations."/.well-known/matrix/client" = {
+      extraConfig = ''
+        return 200 '{"m.homeserver": {"base_url": "https://matrix.fediversity.eu", "public_baseurl": "https://matrix.fediversity.eu"}}';
+        default_type application/json;
+        add_header Access-Control-Allow-Origin "*";
+        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
+      '';
+    };
+    locations."/.well-known/matrix/server" = {
+      extraConfig = ''
+        return 200 '{"m.server": "matrix.fediversity.eu:443"}';
+        default_type application/json;
+        add_header Access-Control-Allow-Origin "*";
+        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
+      '';
+    };
+  };
+
+  services.nginx.virtualHosts."www.fediversity.eu" = {
+    enableACME = true;
+    forceSSL = true;
+    root = "${(import ../../website { }).build}";
+    locations."/.well-known/matrix/client" = {
+      extraConfig = ''
+        return 200 '{"m.homeserver": {"base_url": "https://matrix.fediversity.eu", "public_baseurl": "https://matrix.fediversity.eu"}}';
+        default_type application/json;
+        add_header Access-Control-Allow-Origin "*";
+        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
+      '';
+    };
+    locations."/.well-known/matrix/server" = {
+      extraConfig = ''
+        return 200 '{"m.server": "matrix.fediversity.eu:443"}';
+        default_type application/json;
+        add_header Access-Control-Allow-Origin "*";
+        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
+      '';
+    };
+  };
+
+  security.acme = {
+    acceptTerms = true;
+    defaults.email = "beheer@procolix.com";
+    certs."www.fediversity.eu".extraDomainNames = [ "fediversity.eu" ];
+    certs."oid.foundation".extraDomainNames = [ "www.oid.foundation" ];
+  };
+}
diff --git a/keys/systems/vm02117.pub b/keys/systems/vm02117.pub
new file mode 100644
index 00000000..fa671552
--- /dev/null
+++ b/keys/systems/vm02117.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOrmZ9eMPLDSiayphFhPi7vry5P2VlEr7BvIjtnpN7Td
diff --git a/server/README.md b/server/README.md
deleted file mode 100644
index 8b544140..00000000
--- a/server/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# fediversity.eu webserver
-
-This directory contains the configuration for the server hosting https://fediversity.eu
-
-Build the configuration:
-
-```bash
-nix-build -A machine
-```
-
-Deploy via SSH:
-
-```bash
-env SSH_OPTS="..." nix-shell --run deploy-webserver
-```
diff --git a/server/configuration.nix b/server/configuration.nix
deleted file mode 100644
index 0ffa90ca..00000000
--- a/server/configuration.nix
+++ /dev/null
@@ -1,275 +0,0 @@
-# Edit this configuration file to define what should be installed on
-# your system.  Help is available in the configuration.nix(5) man page
-# and in the NixOS manual (accessible by running ‘nixos-help’).
-
-{ config, pkgs, ... }:
-
-{
-  imports =
-    [
-      # Include the results of the hardware scan.
-      ./hardware-configuration.nix
-    ];
-
-  # Use the systemd-boot EFI boot loader.
-  boot.loader.systemd-boot.enable = true;
-  boot.loader.efi.canTouchEfiVariables = true;
-
-  services.nginx.enable = true;
-  services.nginx.virtualHosts."www.oid.foundation" = {
-    useACMEHost = "oid.foundation";
-    forceSSL = true;
-    globalRedirect = "oid.foundation";
-  };
-  services.nginx.virtualHosts."oid.foundation" = {
-    enableACME = true;
-    forceSSL = true;
-    root = "/var/www/oid.foundation";
-
-  };
-  services.nginx.virtualHosts."fediversity.eu" = {
-    useACMEHost = "www.fediversity.eu";
-    forceSSL = true;
-    globalRedirect = "www.fediversity.eu";
-    locations."/.well-known/matrix/client" = {
-      extraConfig = ''
-        	return 200 '{"m.homeserver": {"base_url": "https://matrix.fediversity.eu", "public_baseurl": "https://matrix.fediversity.eu"}}';
-        	default_type application/json;
-        	add_header Access-Control-Allow-Origin "*";
-        	add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
-        	add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
-      '';
-    };
-    locations."/.well-known/matrix/server" = {
-      extraConfig = ''
-        	return 200 '{"m.server": "matrix.fediversity.eu:443"}';
-        	default_type application/json;
-        	add_header Access-Control-Allow-Origin "*";
-        	add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
-        	add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
-      '';
-    };
-  };
-  services.nginx.virtualHosts."www.fediversity.eu" = {
-    enableACME = true;
-    forceSSL = true;
-    root = "${(import ../website { }).build}";
-    locations."/.well-known/matrix/client" = {
-      extraConfig = ''
-        	return 200 '{"m.homeserver": {"base_url": "https://matrix.fediversity.eu", "public_baseurl": "https://matrix.fediversity.eu"}}';
-        	default_type application/json;
-        	add_header Access-Control-Allow-Origin "*";
-        	add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
-        	add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
-      '';
-    };
-    locations."/.well-known/matrix/server" = {
-      extraConfig = ''
-        	return 200 '{"m.server": "matrix.fediversity.eu:443"}';
-        	default_type application/json;
-        	add_header Access-Control-Allow-Origin "*";
-        	add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
-        	add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
-      '';
-    };
-  };
-  security.acme = {
-    acceptTerms = true;
-    defaults.email = "beheer@procolix.com";
-    certs."www.fediversity.eu".extraDomainNames = [ "fediversity.eu" ];
-    certs."oid.foundation".extraDomainNames = [ "www.oid.foundation" ];
-  };
-
-  networking = {
-    hostName = "vm02117";
-    domain = "procolix.com";
-    interfaces = {
-      eth0 = {
-        ipv4 = {
-          addresses = [
-            {
-              address = "185.206.232.106";
-              prefixLength = 24;
-            }
-          ];
-        };
-        ipv6 = {
-          addresses = [
-            {
-              address = "2a00:51c0:12:1201::106";
-              prefixLength = 64;
-            }
-          ];
-        };
-      };
-    };
-    defaultGateway = {
-      address = "185.206.232.1";
-      interface = "eth0";
-    };
-    defaultGateway6 = {
-      address = "2a00:51c0:12:1201::1";
-      interface = "eth0";
-    };
-    nameservers = [ "95.215.185.6" "95.215.185.7" ];
-    firewall.enable = false;
-    nftables = {
-      enable = true;
-      ruleset = ''
-        #!/usr/sbin/nft -f
-
-        flush ruleset
-
-        ########### define usefull variables here #####################
-        define wan        = eth0
-        define ssh_allow  = {
-                    83.161.147.127/32, # host801 ipv4
-                    95.215.185.92/32,  # host088 ipv4
-                    95.215.185.211/32, # host089 ipv4
-                    95.215.185.34/32,  # nagios2 ipv4
-                    95.215.185.181/32, # ansible.procolix.com
-                    95.215.185.235,        # ansible-hq
-                    185.206.232.76,    # vpn4
-                }
-        define snmp_allow = {
-                    95.215.185.31/32,   # cacti ipv4
-                }
-        define nrpe_allow = {
-                    95.215.185.34/32,   # nagios2 ipv4
-                }
-
-        ########### here starts the automated bit #####################
-        table inet filter {
-            chain input {
-                type filter hook input priority 0;
-                policy drop;
-
-                # established/related connections
-                ct state established,related accept
-                ct state invalid drop
-
-                # Limit ping requests.
-                ip protocol icmp icmp type echo-request limit rate over 10/second burst 50 packets drop
-                ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 50 packets drop
-
-                # loopback interface
-                iifname lo accept
-
-                # icmp
-                ip protocol icmp icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } accept
-                # Without the nd-* ones ipv6 will not work.
-                ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, echo-reply, echo-request, nd-neighbor-solicit,  nd-router-advert, nd-neighbor-advert, packet-too-big, parameter-problem, time-exceeded } accept
-
-                # open tcp ports: sshd (22)
-                ip saddr $ssh_allow tcp dport {ssh} accept
-
-                # open tcp ports: snmp (161)
-                ip saddr $snmp_allow udp dport {snmp} accept
-
-                # open tcp ports: nrpe (5666)
-                ip saddr $nrpe_allow tcp dport {nrpe} accept
-
-                # open tcp ports: http (80,443)
-                tcp dport {http,https} accept
-            }
-            chain forward {
-                type filter hook forward priority 0;
-            }
-            chain output {
-                type filter hook output priority 0;
-            }
-        }
-
-        table ip nat {
-            chain postrouting {
-            }
-            chain prerouting {
-            }
-        }
-      '';
-    };
-  };
-
-
-  # Set your time zone.
-  time.timeZone = "Europe/Amsterdam";
-
-  # Select internationalisation properties.
-  i18n.defaultLocale = "en_US.UTF-8";
-
-  security.sudo.wheelNeedsPassword = false;
-  # Define a user account. Don't forget to set a password with ‘passwd’.
-  users.users.procolix = {
-    isNormalUser = true;
-    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
-    openssh.authorizedKeys.keys = [
-      "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAotfCIjLoDlHOe+++kVS1xiBPaS8mC5FypgrxDrDVst6SHxMTca2+IScMajzUZajenvNAoZOwIsyAPacT8OHeyFvV5Y7G874Qa+cZVqJxLht9gdXxr1GNabU3RfhhCh272dUeIKIqfgsRsM2HzdnZCMDavS1Yo+f+RhhHhnJIua+NdVFo21vPrpsz+Cd0M1NhojARLajrTHvEXW0KskUnkbfgxT0vL9jeRZxdgMS+a9ZoR5dbzOxQHWfbP8N04Xc+7CweMlvKwlWuAE/xDb5XLNHorfGWFvZuVhptJN8jPaaVS25wsmsF5IbaAuSZfzCtBdFQhIloUhy0L6ZisubHjQ== procolix@sshnode1"
-      "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuT3C0f3nyQ7SwUvXcFmEYEgwL+crY6iK0Bhoi9yfn4soz3fhfMKyKSwc/0RIlRnrz3xnkyJiV0vFeU7AC1ixbGCS3T9uc0G1x0Yedd9n2yR8ZJmkdyfjZ5KE4YvqZ3f6UZn5Mtj+7tGmyp+ee+clLSHzsqeyDiX0FIgFmqiiAVJD6qeKPFAHeWz9b2MOXIBIw+fSLOpx0rosCgesOmPc8lgFvo+dMKpSlPkCuGLBPj2ObT4sLjc98NC5z8sNJMu3o5bMbiCDR9JWgx9nKj+NlALwk3Y/nzHSL/DNcnP5vz2zbX2CBKjx6ju0IXh6YKlJJVyMsH9QjwYkgDQVmy8amQ== procolix@sshnode2"
-    ];
-    packages = with pkgs; [
-    ];
-  };
-  users.users.laurens = {
-    isNormalUser = true;
-    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
-    openssh.authorizedKeys.keys = [
-      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBbK4ZB0Xnpf8yyK4QOI2HvjgQINI3GKi7/O2VEsYXUb laurenshof@Laurenss-MacBook-Air.local"
-    ];
-    packages = with pkgs; [
-    ];
-  };
-  users.users.valentin = {
-    isNormalUser = true;
-    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
-    openssh.authorizedKeys.keys = [
-      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJg5TlS1NGCRZwMjDgBkXeFUXqooqRlM8fJdBAQ4buPg"
-    ];
-    packages = with pkgs; [
-    ];
-  };
-  users.users.niols = {
-    isNormalUser = true;
-    extraGroups = [ "wheel" ];
-    openssh.authorizedKeys.keys = [
-      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEElREJN0AC7lbp+5X204pQ5r030IbgCllsIxyU3iiKY"
-    ];
-  };
-  # List packages installed in system profile. To search, run:
-  # $ nix search wget
-  environment.systemPackages = with pkgs; [
-    (pkgs.vim_configurable.customize {
-      name = "vim";
-      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
-        start = [ vim-nix ]; # load plugin on startup
-      };
-      vimrcConfig.customRC = ''
-        " your custom vimrc
-        set nocompatible
-        set backspace=indent,eol,start
-        " Turn on syntax highlighting by default
-        syntax on
-        " ...
-      '';
-    })
-    wget
-    git
-  ];
-
-  # List services that you want to enable:
-
-  # Enable the OpenSSH daemon.
-  services.openssh.enable = true;
-  services.openssh.settings.PasswordAuthentication = false;
-
-  # Enable xe-guest-utilities
-  services.xe-guest-utilities.enable = true;
-
-  # This value determines the NixOS release from which the default
-  # settings for stateful data, like file locations and database versions
-  # on your system were taken. It‘s perfectly fine and recommended to leave
-  # this value at the release version of the first install of this system.
-  # Before changing this value read the documentation for this option
-  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
-  system.stateVersion = "23.11"; # Did you read the comment?
-
-}
diff --git a/server/default.nix b/server/default.nix
deleted file mode 100644
index cfdae5bd..00000000
--- a/server/default.nix
+++ /dev/null
@@ -1,46 +0,0 @@
-{ sources ? import ../website/npins
-, system ? builtins.currentSystem
-, pkgs ? import sources.nixpkgs {
-    inherit system;
-    config = { };
-    overlays = [ ];
-  }
-, lib ? import "${sources.nixpkgs}/lib"
-}:
-let
-  # TODO: don't hard code target hosts; wire all of it up with NixOps4
-  host = "vm02117.procolix.com";
-  deploy = pkgs.writeShellApplication {
-    name = "deploy-webserver";
-    text = ''
-      # HACK: decouple system evaluation from shell evaluation
-      # the structured way for using this hack is encoded in https://github.com/fricklerhandwerk/lazy-drv
-      result="$(nix-build ${toString ./.} -A machine --no-out-link --eval-store auto --store ssh-ng://${host})"
-      # shellcheck disable=SC2087
-      ssh ${host} << EOF
-      sudo nix-env -p /nix/var/nix/profiles/system --set "$result"
-      sudo "$result"/bin/switch-to-configuration switch
-      EOF
-    '';
-  };
-  nixos-configuration = config:
-    import "${pkgs.path}/nixos/lib/eval-config.nix" {
-      modules = [
-        config
-      ];
-      system = null;
-    };
-in
-rec {
-  nixos = nixos-configuration ./configuration.nix;
-  machine = nixos.config.system.build.toplevel;
-  shell = pkgs.mkShellNoCC {
-    packages = with pkgs; [
-      deploy
-    ];
-    env = {
-      # TODO: reusing other pins for now; wire up the whole repo to use the same dependencies
-      NPINS_DIRECTORY = toString ../website/npins;
-    };
-  };
-}
diff --git a/server/hardware-configuration.nix b/server/hardware-configuration.nix
deleted file mode 100644
index c14f4759..00000000
--- a/server/hardware-configuration.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-# Do not modify this file!  It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations.  Please make changes
-# to /etc/nixos/configuration.nix instead.
-{ config, lib, pkgs, modulesPath, ... }:
-
-{
-  imports = [ ];
-
-  boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "sr_mod" "xen_blkfront" ];
-  boot.initrd.kernelModules = [ "dm-snapshot" ];
-  boot.kernelModules = [ ];
-  boot.extraModulePackages = [ ];
-
-  fileSystems."/" =
-    { device = "/dev/disk/by-uuid/5aa392a8-c9ba-4181-976f-b3b30db350a1";
-      fsType = "ext4";
-    };
-
-  fileSystems."/boot" =
-    { device = "/dev/disk/by-uuid/FC6D-610F";
-      fsType = "vfat";
-    };
-
-  swapDevices = [ ];
-
-  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
-  # (the default) this is the recommended approach. When using systemd-networkd it's
-  # still possible to use this option, but it's recommended to use it in conjunction
-  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
-  networking.useDHCP = lib.mkDefault true;
-  # networking.interfaces.enX0.useDHCP = lib.mkDefault true;
-
-  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-}
diff --git a/server/shell.nix b/server/shell.nix
deleted file mode 100644
index a6bdf202..00000000
--- a/server/shell.nix
+++ /dev/null
@@ -1 +0,0 @@
-(import ./. { }).shell