From ec0965e2672899d25a5a3a8c072de3ea734076a2 Mon Sep 17 00:00:00 2001 From: V Date: Wed, 9 Jun 2021 15:43:16 +0200 Subject: fleet: init Co-authored-by: edef Change-Id: I36d2c4cca542ed91630b1b832f3c7a7b97b33c65 --- fleet/hosts/trieste/build-from-git.nix | 16 +++++ fleet/hosts/trieste/cgit/default.nix | 107 +++++++++++++++++++++++++++++++ fleet/hosts/trieste/cgit/ripple.svg | 8 +++ fleet/hosts/trieste/cgit/un.svg | 6 ++ fleet/hosts/trieste/cgit/unicon.svg | 6 ++ fleet/hosts/trieste/default.nix | 52 +++++++++++++++ fleet/hosts/trieste/git.nix | 47 ++++++++++++++ fleet/hosts/trieste/lists.nix | 58 +++++++++++++++++ fleet/hosts/trieste/mail.nix | 14 +++++ fleet/hosts/trieste/web.nix | 32 ++++++++++ fleet/hosts/vityaz/default.nix | 112 +++++++++++++++++++++++++++++++++ fleet/hosts/vityaz/git.nix | 67 ++++++++++++++++++++ fleet/hosts/vityaz/mail.nix | 58 +++++++++++++++++ fleet/hosts/vityaz/mumble.nix | 21 +++++++ 14 files changed, 604 insertions(+) create mode 100644 fleet/hosts/trieste/build-from-git.nix create mode 100644 fleet/hosts/trieste/cgit/default.nix create mode 100644 fleet/hosts/trieste/cgit/ripple.svg create mode 100644 fleet/hosts/trieste/cgit/un.svg create mode 100644 fleet/hosts/trieste/cgit/unicon.svg create mode 100644 fleet/hosts/trieste/default.nix create mode 100644 fleet/hosts/trieste/git.nix create mode 100644 fleet/hosts/trieste/lists.nix create mode 100644 fleet/hosts/trieste/mail.nix create mode 100644 fleet/hosts/trieste/web.nix create mode 100644 fleet/hosts/vityaz/default.nix create mode 100644 fleet/hosts/vityaz/git.nix create mode 100644 fleet/hosts/vityaz/mail.nix create mode 100644 fleet/hosts/vityaz/mumble.nix (limited to 'fleet/hosts') diff --git a/fleet/hosts/trieste/build-from-git.nix b/fleet/hosts/trieste/build-from-git.nix new file mode 100644 index 0000000..f04ef48 --- /dev/null +++ b/fleet/hosts/trieste/build-from-git.nix @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: V +# SPDX-License-Identifier: OSL-3.0 + +{ repo, pkgs ? import {} }: + +pkgs.callPackage (builtins.fetchGit { + url = repo; + # While Nix will happily just fetch from HEAD if you only pass in a + # path, it will also cache the result for an hour, making it totally + # unsuitable for what we're doing. lib.commitIdFromGitRepo, on the + # other hand, is implemented purely in Nix and does not cache lookups + # from one invocation to the next. This lets us "impurely" fetch from + # HEAD while enjoying the niceties of using builtins.fetchGit with a + # specific commit hash. + rev = pkgs.lib.commitIdFromGitRepo repo; +}).outPath {} diff --git a/fleet/hosts/trieste/cgit/default.nix b/fleet/hosts/trieste/cgit/default.nix new file mode 100644 index 0000000..23e8ab6 --- /dev/null +++ b/fleet/hosts/trieste/cgit/default.nix @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ lib, pkgs, ... }: + +with lib; + +let + cgit-webroot = pkgs.runCommand "cgit-webroot" { + extraStyles = '' + div#cgit table#header td.logo { + width: 64px; + } + + #summary { + max-width: 72ch; + margin: auto; + font-size: initial; + } + ''; + passAsFile = [ "extraStyles" ]; + } '' + ${pkgs.minify}/bin/minify --type css ${pkgs.cgit}/cgit/cgit.css $extraStylesPath -o $out/cgit.css + cp ${./un.svg} $out/un.svg # TODO(V): remove this variant, apply padding to the Sigil using CSS + cp ${./unicon.svg} $out/unicon.svg # This is the same as un.svg, but without any padding + cp ${./ripple.svg} $out/ripple.svg # This is referenced in git.nix (as config.cgit.logo, for Ripple) + cp ${pkgs.cgit}/cgit/robots.txt $out + ''; + + cgit-about-filter = pkgs.writeShellScript "cgit-about-filter" '' + # Asciidoctor's embedded mode defaults to eliding the top-level heading, for some reason. + # Fortunately we can change this behaviour using the showtitle attribute. + # See also: https://github.com/asciidoctor/asciidoctor/issues/1149 + ${pkgs.asciidoctor}/bin/asciidoctor -e -a showtitle - + ''; + + cgit-config = pkgs.writeText "cgit-config" '' + # TODO(V): sort these sanely + root-title=unfathomable software + root-desc= + # TODO(V): root-readme? what should go in here, contribution info? info about the server? info about the branch conventions? + enable-index-owner=0 + + logo=/un.svg + favicon=/unicon.svg + # TODO(V): footer=https://src.unfathomable.blue/nixos-config/commit/?id={commit} + mimetype-file=${pkgs.mime-types}/etc/mime.types + # TODO(V): repository-sort=age? + # TODO(V): robots=none? (same as noindex, nofollow) + readme=:README.adoc + clone-prefix=https://src.unfathomable.blue + agefile=info/last-modified + about-filter=${cgit-about-filter} + # TODO(edef): commit-filter, for bug tracker links + source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py + # TODO(edef): add snapshots once we start releasing things + # TODO(V): branch-sort=age? + enable-git-config=1 + + # Has to go last. + # Options set after this won't be applied due to how they're evaluated. + scan-path=/var/lib/git + # TODO(V): section-from-path? + # TODO(V): repository-specific logos + # TODO(V): other repository-specific options + ''; +in { + services.cgiserver.instances.cgit = { + description = "Lightweight Git web interface"; + application = "${pkgs.cgit}/cgit/cgit.cgi"; + environment.CGIT_CONFIG = "${cgit-config}"; + serviceConfig.SupplementaryGroups = [ "git" ]; + # TODO(V): Hardening options + }; + + # TODO(V): set up git-http-backend. Disable enable-http-clone when we've done that? + services.caddy.config = '' + src.unfathomable.blue { + import common + + root * ${cgit-webroot} + @exists file + + route { + file_server @exists + reverse_proxy unix//run/cgit/cgit.sock + } + } + ''; + + declarative.git.hooks.post-receive = [ + # Regenerate the static pack and ref indices used by the dumb git protocol + # TODO(V): Remove this once we set up git-http-backend + (pkgs.writeShellScript "update-server-info" '' + git update-server-info + '') + + # Update the last-modified timestamp that cgit uses to measure freshness + (pkgs.writeShellScript "update-agefile" '' + git for-each-ref \ + --sort=-creatordate --count=1 \ + --format='%(creatordate:iso)' \ + >info/last-modified + '') + ]; +} diff --git a/fleet/hosts/trieste/cgit/ripple.svg b/fleet/hosts/trieste/cgit/ripple.svg new file mode 100644 index 0000000..243059f --- /dev/null +++ b/fleet/hosts/trieste/cgit/ripple.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/fleet/hosts/trieste/cgit/un.svg b/fleet/hosts/trieste/cgit/un.svg new file mode 100644 index 0000000..a6201bf --- /dev/null +++ b/fleet/hosts/trieste/cgit/un.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/fleet/hosts/trieste/cgit/unicon.svg b/fleet/hosts/trieste/cgit/unicon.svg new file mode 100644 index 0000000..4753d6b --- /dev/null +++ b/fleet/hosts/trieste/cgit/unicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/fleet/hosts/trieste/default.nix b/fleet/hosts/trieste/default.nix new file mode 100644 index 0000000..08dce1f --- /dev/null +++ b/fleet/hosts/trieste/default.nix @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ lib, pkgs, ... }: + +with lib; + +{ + imports = [ + ./cgit + ./git.nix + ./lists.nix + ./mail.nix + ./web.nix + ]; + + boot.initrd.network.ssh.authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM3xBRi/sOVJnurXf1McDrODEhU4hCrKZewrUlDmu1Sl v@january" + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; + + # TODO(V): Write a proper description for this + # It's b/c the default hosts file is borked + # And we need the addresses here b/c for some reason the + # stub resolver doesn't return the domain name in PTR records + networking.hostFiles = mkForce [ + (pkgs.writeText "hosts" '' + 168.119.127.252 trieste.unfathomable.blue + 2a01:4f8:c2c:b2ae::1:f93f trieste.unfathomable.blue + '') + ]; + + networking.defaultGateway6.address = "fe80::1"; + networking.interfaces.ens3.ipv6.addresses = singleton { + address = "2a01:4f8:c2c:b2ae::1:f93f"; + prefixLength = 64; + }; + + services.caddy.config = '' + trieste.unfathomable.blue { + import common + redir / https://en.wikipedia.org/wiki/Trieste_(bathyscaphe) + error 404 + } + ''; + + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILjTET0rm61NIM8C8t95YY8PYGhuieEchTznaaIm/3IK v@january" + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; +} diff --git a/fleet/hosts/trieste/git.nix b/fleet/hosts/trieste/git.nix new file mode 100644 index 0000000..f4d4e0b --- /dev/null +++ b/fleet/hosts/trieste/git.nix @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ pkgs, ... }: + +let + root = "/var/lib/git"; +in { + users.users.git = { + isSystemUser = true; + group = "git"; + + # This lets us address remote repositories like `trieste:foo`. + home = root; + + # TODO(V): Remove the override once https://github.com/NixOS/nixpkgs/pull/128062 has made its way into stable. + shell = pkgs.git // { shellPath = "/bin/git-shell"; }; + + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDXELHAMjO/BzoBFgTW9ln3td2WnXw9VGF3zpMBiswsx git@vityaz" + ]; + }; + + users.groups.git = {}; + + systemd.tmpfiles.rules = [ + "d ${root} 0750 git git" + ]; + + declarative.git.repositories = { + ripple = { + description = "A build system for the next decade"; + config.cgit = { + # This is added to the webroot in cgit.nix. It would be nice if we could do that modularly. + # Another option is to simply hotlink https://ripple.unfathomable.blue/icon.svg + # Yet another option is to keep the SVG in Git, and link to the raw file from trunk. + logo = "/ripple.svg"; + + homepage = "https://ripple.unfathomable.blue/"; + }; + }; + + ripple-website.description = "Source code for https://ripple.unfathomable.blue/"; + nixos-config.description = "NixOS configuration for Unfathomable infrastructure"; + }; +} diff --git a/fleet/hosts/trieste/lists.nix b/fleet/hosts/trieste/lists.nix new file mode 100644 index 0000000..a4e9a69 --- /dev/null +++ b/fleet/hosts/trieste/lists.nix @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: V +# SPDX-License-Identifier: OSL-3.0 + +{ lib, pkgs, ... }: + +with lib; + +{ + # Block HTML e-mail + # FIXME(V): This is global, and will affect anyone sending HTML mail to e.g. postmaster@ + # We should fix this, and limit it to just the list: this is possible using http://mlmmj.org/docs/readme-access/ + # Unfortunately this doesn't let us pick an error message, though. So maybe not. + services.postfix = { + enableHeaderChecks = true; + headerChecks = [ + { + pattern = ''/^Content-Type: text\/html/''; # This feels kind of brittle, but should work in 99% of cases. + action = "REJECT HTML e-mail is not allowed on this list. See https://useplaintext.email/ for more information."; + } + ]; + }; + + services.mlmmj = { + enablePostfix = true; + enablePublicInbox = true; + + control.customheaders = [ "X-Clacks-Overhead: GNU Terry Pratchett" ]; + + lists."lists.unfathomable.blue" = { + ripple-announce = { + description = "Progress updates and other major announcements about Ripple"; + moderators = [ + "v@unfathomable.blue" + "edef@unfathomable.blue" + ]; + # FIXME(V): This doesn't have quite the effect I was looking for. + # It submits non-moderator posts for review, rather than outright rejecting them as I'd wanted. + # Perhaps this is good, though, as it allows guest posts? + # Downside is there's no immediate rejection, so the user is left with the impression that their mail disappeared… + # Maybe http://mlmmj.org/docs/readme-access/ would be more appropriate? + control.modonlypost = true; + }; + ripple-devel.description = "Technical discourse and patches for Ripple"; + ripple-discuss.description = "General discussion about Ripple"; + # TODO(V): ripple-commits, read-only commit notifications + }; + }; + + # By default, the index 404s with the rather confusing message "no inboxes, yet", even when there are inboxes configured. + services.public-inbox.settings.publicinbox.wwwlisting = "all"; + + services.caddy.config = '' + lists.unfathomable.blue { + import common + reverse_proxy unix//run/public-inbox/httpd.sock + } + ''; +} diff --git a/fleet/hosts/trieste/mail.nix b/fleet/hosts/trieste/mail.nix new file mode 100644 index 0000000..a9258d2 --- /dev/null +++ b/fleet/hosts/trieste/mail.nix @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: V +# SPDX-License-Identifier: OSL-3.0 + +{ pkgs, ... }: + +{ + services.postfix = { + # Disable delivery to local users + localRecipients = []; + + # Forward administrative mail to vityaz + postmasterAlias = "postmaster@unfathomable.blue"; + }; +} diff --git a/fleet/hosts/trieste/web.nix b/fleet/hosts/trieste/web.nix new file mode 100644 index 0000000..d32fc44 --- /dev/null +++ b/fleet/hosts/trieste/web.nix @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: V +# SPDX-License-Identifier: OSL-3.0 + +{ pkgs, ... }: + +{ + systemd.tmpfiles.rules = [ + "d /var/lib/www - git git" + ]; + + declarative.git.repositories.ripple-website.hooks.post-receive = [ + (pkgs.writeShellScript "update-ripple-website" '' + nix-build ${./build-from-git.nix} \ + --argstr repo /var/lib/git/ripple-website \ + -o /var/lib/www/ripple + '') + ]; + + services.caddy.config = '' + unfathomable.blue { + import common + respond / "the depths await" + error 404 + } + + ripple.unfathomable.blue { + import common + root * /var/lib/www/ripple + file_server + } + ''; +} diff --git a/fleet/hosts/vityaz/default.nix b/fleet/hosts/vityaz/default.nix new file mode 100644 index 0000000..18a4c03 --- /dev/null +++ b/fleet/hosts/vityaz/default.nix @@ -0,0 +1,112 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ + ./git.nix + ./mail.nix + ./mumble.nix + ]; + + boot.initrd.network.ssh.authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJ8Ms9z95InM7oGJLuo7DdDPh3r5xKnglvBSZ7FTTZ8 v@january" + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; + + # TODO(V): Write a proper description for this + # It's b/c the default hosts file is borked + # And we need the addresses here b/c for some reason the + # stub resolver doesn't return the domain name in PTR records + networking.hostFiles = mkForce [ + (pkgs.writeText "hosts" '' + 157.90.172.8 vityaz.unfathomable.blue + 2a01:4f8:1c0c:46a9::1:f93f vityaz.unfathomable.blue + '') + ]; + + networking.defaultGateway6.address = "fe80::1"; + networking.interfaces.ens3.ipv6.addresses = singleton { + address = "2a01:4f8:1c0c:46a9::1:f93f"; + prefixLength = 64; + }; + + networking.wireguard.interfaces.wg0 = { + ips = [ "10.102.120.0" ]; + listenPort = 51820; + privateKeyFile = "/etc/wireguard/0.key"; + generatePrivateKeyFile = true; + + peers = mapAttrsToList (address: publicKey: { + inherit publicKey; + allowedIPs = [ "10.102.120.${address}/32" ]; + }) { + "1" = "z6JrEDvTyIB7cPh4RzeyAihNl+pzgHxv08TMyeynQX4="; # january + "2" = "KSigo7Ny3TTOSPBYDOCVm+K92/pIfgawlfAxK/UBfxA="; # jaguar + "3" = "1EcmBoRykRep8IagzhtJ4zZU0r7gx5W7nZFh2m1wSE8="; # OnePlus 5T + "4" = "TqKlPfBk1McfYNk6S7ZtSj/GnyisGWneozQrh0eh1C8="; # wallaby + "5" = "kuEkbQ+6mOGwkNkOHqpnxM/TI3gpc2sQ6L15UxsOMDI="; # M1 + }; + + preSetup = '' + ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -o wg0 -s 10.102.120.0/24 -d 10.102.120.0/24 -j ACCEPT + ''; + + postShutdown = '' + ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -o wg0 -s 10.102.120.0/24 -d 10.102.120.0/24 -j ACCEPT + ''; + }; + + networking.firewall.interfaces.ens3.allowedUDPPorts = [ config.networking.wireguard.interfaces.wg0.listenPort ]; + + networking.firewall.extraCommands = '' + iptables -P FORWARD DROP + ''; + + boot.kernel.sysctl."net.ipv4.conf.wg0.forwarding" = true; + + services.caddy.config = '' + vityaz.unfathomable.blue { + import common + redir / https://en.wikipedia.org/wiki/Vityaz-D_Autonomous_Underwater_Vehicle + error 404 + } + ''; + + users.users = { + root = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDz+gGXZUvQiLcDgvon28dErFsbii2cVXJ5wVlsUgaBZ v@january" + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; + }; + + v = { + isNormalUser = true; + description = "V"; + + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILKMEXEIK2PIRkXYb3RCVN15q9DhKsQlbMhHa5BxQyuz v@january" + ]; + + packages = with pkgs; [ + ]; + }; + + edef = { + isNormalUser = true; + description = "edef"; + + openssh.authorizedKeys.keys = [ + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; + + packages = with pkgs; [ + ]; + }; + }; +} diff --git a/fleet/hosts/vityaz/git.nix b/fleet/hosts/vityaz/git.nix new file mode 100644 index 0000000..66f26db --- /dev/null +++ b/fleet/hosts/vityaz/git.nix @@ -0,0 +1,67 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ lib, pkgs, ... }: + +with lib; + +{ + # TODO(edef): could we somehow make this use DynamicUser? + users.users.git = { + isSystemUser = true; + + group = "git"; + + home = "/var/lib/git"; + createHome = true; + + useDefaultShell = true; + + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFovWcdS0vQAJiEvwjEIUOv7eip52oX7rVOEMQDJkSL6 v@january" + "cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvb/7ojfcbKvHIyjnrNUOOgzy44tCkgXY9HLuyFta1jQOE9pFIK19B4dR9bOglPKf145CCL0mSFJNNqmNwwavU2uRn+TQrW+U1dQAk8Gt+gh3O49YE854hwwyMU+xD6bIuUdfxPr+r5al/Ov5Km28ZMlHOs3FoAP0hInK+eAibioxL5rVJOtgicrOVCkGoXEgnuG+LRbOYTwzdClhRUxiPjK8alCbcJQ53AeZHO4G6w9wTr+W5ILCfvW4OmUXCX01sKzaBiQuuFCF6M/H4LlnsPWLMra2twXxkOIhZblwC+lncps9lQaUgiD4koZeOCORvHW00G0L39ilFbbnVcL6Itp/m8RRWm/xRxS4RMnsdV/AhvpRLrhL3lfQ7E2oCeSM36v1S9rdg6a47zcnpL+ahG76Gz39Y7KmVRQciNx7ezbwxj3Q5lZtFykgdfGIAN+bT8ijXMO6m68g60i9Bz4IoMZGkiJGqMYLTxMQ+oRgR3Ro5lbj7E11YBHyeimoBYXYGHMkiuxopQZ7lIj3plxIzhmUlXJBA4jMw9KGHdYaLhaicIYhvQmCTAjrkt2HvxEe6lU8iws2Qv+pB6tAGundN36RVVWAckeQPZ4ZsgDP8V2FfibZ1nsrQ+zBKqaslYMAHs01Cf0Hm0PnCqagf230xaobu0iooNuXx44QKoDnB+w== openpgp:0x803010E7" + ]; + + packages = with pkgs; [ + git + ]; + }; + + users.groups.git = {}; + + # TODO(V): Enable the reflog? + declarative.git.repositories = flip genAttrs (repo: { + hooks.post-receive = [ + # FIXME(V): There are more than a number of issues with this! + # - non-generic (we could use $GIT_DIR or such) + # - requires an explicit remote (we could add this to the config) + # - only updates trunk (even if other branches were pushed) + # - has no way to filter specific branches from being published + # - does not synchronize tags + (pkgs.writeShellScript "sync-repository" '' + git push trieste:${repo} trunk + '') + ]; + }) [ + # TODO(V): Take the list of public repositories from hosts/trieste/git.nix + # (or do the inverse) + # (or put this information in a shared location) + "ripple" + "ripple-website" + "nixos-config" + + # Note: private repositories are currently not configured here. + # If we find it acceptable to leak their names, they could take advantage of this module as well. + ]; + + # TODO(V): Linting hooks (honestly, these should just go in CI) + # - reuse lint + # - check there's a (owner) for every TODO, FIXME, XXX, etc + # - make sure everything has been run through rustfmt + + # TODO(V): An equivalent of Bors ("Tolby"?) for our workflow + # (or, at least, a queue of commits that must individually pass CI to get merged) + + # TODO(V): Set up CI +} diff --git a/fleet/hosts/vityaz/mail.nix b/fleet/hosts/vityaz/mail.nix new file mode 100644 index 0000000..58d6866 --- /dev/null +++ b/fleet/hosts/vityaz/mail.nix @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: V +# SPDX-FileCopyrightText: edef +# SPDX-License-Identifier: OSL-3.0 + +{ pkgs, ... }: + +{ + services.postfix = { + # TODO(V): Set myorigin to $mydomain? + + # We accept mail to ourselves and to the apex + destination = [ "$myhostname" "$mydomain" ]; + + # TODO(V): Restrict authorized_submit_users to system users + + # TODO(V): Authenticate users + networks = [ + # Defaults + "127.0.0.1/32" + "157.90.172.8/32" + "10.102.120.0/32" + "[::1]/128" + "[2a01:4f8:1c0c:46a9::1:f93f]/128" + "[fe80::9400:ff:feae:b407]/128" + + # Intranet + "10.102.120.0/24" + ]; + + # Wait, why is this enabled here? + recipientDelimiter = "+"; + + # TODO(V): postscreen + DNSBLs + # TODO(V): postgrey + + rootAlias = "v, edef"; + + # TODO(V): Forward mails to root to both edef & V + # TODO(V): Forward mails to postmaster to both edef & V + # TODO(V): Add extra aliases (Alyssa has abuse, noc, security, hostmaster, usenet, news, webmaster, www, uucp, and ftp) + # TODO(V): Add more notify_classes + }; + + systemd.user.paths.mail = { + description = "New mail trigger"; + wantedBy = [ "paths.target" ]; + pathConfig.PathChanged = "/var/mail/%u/new"; + unitConfig.ConditionPathExists = "%h/.notmuch-config"; + }; + + systemd.user.services.mail = { + description = "New mail indexing"; + serviceConfig = { + Type = "exec"; + ExecStart = "${pkgs.notmuch}/bin/notmuch new"; + }; + }; +} diff --git a/fleet/hosts/vityaz/mumble.nix b/fleet/hosts/vityaz/mumble.nix new file mode 100644 index 0000000..dffc6a6 --- /dev/null +++ b/fleet/hosts/vityaz/mumble.nix @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: V +# SPDX-License-Identifier: OSL-3.0 + +{ config, ... }: + +{ + services.murmur = { + enable = true; + + # This isn't actually the hostname, it's the address to bind on. + hostName = builtins.head config.networking.wireguard.interfaces.wg0.ips; + + # Another misleading name— it's also used as the root channel name. + registerName = "Pool"; + }; + + networking.firewall.interfaces.wg0 = { + allowedTCPPorts = [ config.services.murmur.port ]; + allowedUDPPorts = [ config.services.murmur.port ]; + }; +} -- cgit 1.4.1