From ce06f43476863da90dc60dcee606d2b6c5a89a8e Mon Sep 17 00:00:00 2001 From: sefidel Date: Wed, 29 Mar 2023 20:54:19 +0900 Subject: project: initial commit --- systems/.sops.yaml | 10 + systems/cobalt/default.nix | 303 ++++++++++++++++++++++++++++++ systems/cobalt/hardware-configuration.nix | 65 +++++++ systems/cobalt/secrets/secrets.yaml | 39 ++++ 4 files changed, 417 insertions(+) create mode 100644 systems/.sops.yaml create mode 100644 systems/cobalt/default.nix create mode 100644 systems/cobalt/hardware-configuration.nix create mode 100644 systems/cobalt/secrets/secrets.yaml (limited to 'systems') diff --git a/systems/.sops.yaml b/systems/.sops.yaml new file mode 100644 index 0000000..11331c6 --- /dev/null +++ b/systems/.sops.yaml @@ -0,0 +1,10 @@ +keys: + - &sefidel age1jt8xg0lvzj5q4f7fn7nw670qsszm3kv3caa654eh62azra4x44zss4fad8 + - &sefidel_pgp 8BDFDFB56842239382A0441B9238BC709E05516A + - &host_cobalt age14a2amn7memzvctf2nnrt6uj458x3g4jpcvs04tlkww2z02p05syqawxrwh +creation_rules: + - path_regex: cobalt/secrets/[^/]+\.yaml$ + key_groups: + - age: + - *sefidel + - *host_cobalt diff --git a/systems/cobalt/default.nix b/systems/cobalt/default.nix new file mode 100644 index 0000000..0a5cfe0 --- /dev/null +++ b/systems/cobalt/default.nix @@ -0,0 +1,303 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + ipv4 = { + address = "95.216.74.104"; + gateway = "95.216.74.65"; + netmask = "255.255.255.192"; + prefixLength = 26; # https://www.pawprint.net/designresources/netmask-converter.php + }; + ipv6 = { + address = "2a01:4f9:2b:a98::"; + gateway = "fe80::1"; + prefixLength = 64; + }; + networkInterface = "eth0"; + hostName = "cobalt"; + hostId = "712ae82a"; + hostAddr = "cobalt.exotic.sh"; + + poorObfuscation = y: x: "${x}@${y}"; +in +{ + deployment = { + targetHost = hostAddr; + targetPort = 22; + targetUser = "root"; + }; + + imports = [ ./hardware-configuration.nix ]; + + boot.supportedFilesystems = [ "zfs" ]; + networking.hostId = hostId; + + boot.loader.grub.enable = true; + # boot.loader.grub.version = 2; + boot.loader.grub.efiSupport = false; + # boot.loader.grub.device = "nodev"; + + # This should be done automatically, but explicitly declare it just in case. + boot.loader.grub.copyKernels = true; + # Make sure that you've listed all of the boot partitions here. + boot.loader.grub.mirroredBoots = [ + { path = "/boot"; devices = [ "/dev/disk/by-id/ata-ST4000NM0245-1Z2107_ZC17GW7G" ]; } + { path = "/boot-fallback"; devices = [ "/dev/disk/by-id/ata-ST4000NM0245-1Z2107_ZC17GWB2" ]; } + ]; + + # Boot normally when one of the boot partitions are missing + fileSystems."/boot".options = [ "nofail" ]; + fileSystems."/boot-fallback".options = [ "nofail" ]; + + # Erase your darlings + # boot.initrd.postDeviceCommands = lib.mkAfter ''nix systemd environ + # zfs rollback -r rpool/local/root@blank + # ''; + + # NOTE: replace these to boot.initrd.availableKernelModules? + boot.kernelModules = [ "e1000e" ]; + boot.initrd.kernelModules = [ "e1000e" ]; + + boot.kernelParams = [ + # See for documentation. + # ip=::::::::: + # The server ip refers to the NFS server -- not needed in this case. + "ip=${ipv4.address}::${ipv4.gateway}:${ipv4.netmask}:${hostName}-initrd:${networkInterface}:off:8.8.8.8" + ]; + + boot.initrd.network.enable = true; + boot.initrd.network.ssh = { + enable = true; + + # Using the same port as the actual SSH will cause clients to throw errors + # related to host key mismatch. + port = 2222; + + # This takes 'path's, not 'string's. + hostKeys = [ + /boot/initrd-ssh-key + /boot-fallback/initrd-ssh-key + ]; + + # Public ssh key to log into the initrd ssh + authorizedKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILN14b5Fu+StHeMXq4ClyLG4G+/vCAfS7adxceEFria/ openpgp:0x1D5BCD11" ]; + }; + boot.initrd.network.postCommands = '' + cat < /root/.profile + if pgrep -x "zfs" > /dev/null + then + zfs load-key -a + killall zfs + else + echo "ZFS is not running -- this could be a sign of failure." + fi + EOF + ''; + + + networking.hostName = hostName; + + networking.useDHCP = false; + networking.interfaces.${networkInterface} = { + ipv4 = { addresses = [{ address = ipv4.address; prefixLength = ipv4.prefixLength; }]; }; + ipv6 = { addresses = [{ address = ipv6.address; prefixLength = ipv6.prefixLength; }]; }; + }; + networking.defaultGateway = ipv4.gateway; + networking.defaultGateway6 = { address = ipv6.gateway; interface = networkInterface; }; + networking.nameservers = [ "8.8.8.8" ]; + + networking.firewall.enable = true; + + time.timeZone = "UTC"; + + users.users.root.initialHashedPassword = ""; # FIXME: use proper secret + users.users.root.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILN14b5Fu+StHeMXq4ClyLG4G+/vCAfS7adxceEFria/ openpgp:0x1D5BCD11" ]; + services.openssh.enable = true; + services.openssh.settings.permitRootLogin = "prohibit-password"; + + services.openssh.hostKeys = [ + { + path = "/persist/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + { + path = "/persist/ssh/ssh_host_rsa_key"; + type = "rsa"; + bits = 4096; + } + ]; + + # impermanence requirement + fileSystems."/persist".neededForBoot = true; + + environment.systemPackages = with pkgs; [ + bsd-finger + ]; + + sops.secrets.acme-envs = { + owner = "acme"; + }; + sops.secrets.matrix-server-key = { }; + sops.secrets.dendrite-envs = { }; + sops.secrets.sliding-sync-secret = { }; + sops.secrets.mjolnir-password = { owner = "mjolnir"; }; + sops.secrets.mautrix-telegram-envs = { }; + sops.secrets.turn-secret = { }; + # sops.secrets.openldap-admin-key = { + # owner = "openldap"; + # }; + + modules = { + sops.enable = true; + + services.metrics = { + enable = true; + domain = "status.exotic.sh"; + tls.acmeHost = "exotic.sh"; + }; + + services.coredns.enable = false; + services.nginx.enable = true; + services.acme = { + enable = true; + email = poorObfuscation "exotic.sh" "postmaster"; + + certs = { + "exotic.sh" = { + subDomains = [ + "git" + "matrix" + "*.labs" + "social" + "bouncer" + "meet" + "chat" + "turn" + "status" + "mail" + "todo" + ]; + }; + "nand.moe" = { + subDomains = [ ]; + }; + "sefidel.net" = { + subDomains = [ ]; + }; + }; + + secrets.acme-credentials = config.sops.secrets.acme-envs.path; + }; + + services.gitolite = { + enable = true; + adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILN14b5Fu+StHeMXq4ClyLG4G+/vCAfS7adxceEFria/ openpgp:0x1D5BCD11"; + }; + services.gitDaemon.enable = true; + services.cgit = { + enable = true; + domain = "exotic.sh"; + realHost = "git.exotic.sh"; + settings.description = "Exotic place."; + }; + services.fail2ban.enable = true; + services.postgresql.enable = true; + services.dendrite = { + enable = true; + domain = "exotic.sh"; + realHost = "matrix.exotic.sh"; + slidingSyncHost = "slidingsync.labs.exotic.sh"; + turn = { + enable = true; + domain = "turn.exotic.sh"; + shared_secret = "$TURN_SECRET"; # dendrite envs + }; + secrets = { + matrix-server-key = config.sops.secrets.matrix-server-key.path; + dendrite-envs = config.sops.secrets.dendrite-envs.path; + sliding-sync-secret = config.sops.secrets.sliding-sync-secret.path; + }; + }; + services.coturn = { + enable = true; + domain = "turn.exotic.sh"; + tls.acmeHost = "exotic.sh"; + shared_secret = config.sops.secrets.turn-secret.path; + }; + services.matrix-moderation = { + enable = true; + domain = "exotic.sh"; + secrets.userPassword = config.sops.secrets.mjolnir-password.path; + }; + services.matrix-bridge = { + enable = true; + domain = "exotic.sh"; + secrets.mautrix-envs = config.sops.secrets.mautrix-telegram-envs.path; + }; + services.element-web = { + enable = true; + hostName = "chat.exotic.sh"; + matrix = { + baseUrl = "https://matrix.exotic.sh"; + serverName = "exotic.sh"; + }; + tls.acmeHost = "exotic.sh"; + jitsi.domain = "meet.exotic.sh"; + }; + services.akkoma = { + enable = true; + domain = "exotic.sh"; + realHost = "social.exotic.sh"; + instanceName = "exotic.sh social"; + }; + services.misskey = { + enable = true; + domain = "nand.moe"; + realHost = "nand.moe"; + }; + services.soju = { + enable = true; + hostName = "bouncer.exotic.sh"; + tls.enable = true; + tls.acmeHost = "exotic.sh"; + }; + services.vikunja = { + enable = true; + domain = "exotic.sh"; + realHost = "todo.exotic.sh"; + }; + + + services.nixos-mailserver.enable = true; # TODO: replace with dovecot.nix? + + services.jitsi = { + enable = true; + hostName = "meet.exotic.sh"; + tls.acmeHost = "exotic.sh"; + }; + + services.ldap = { + enable = false; + dc = "exotic"; + tld = "sh"; + tls.acmeHost = "exotic.sh"; + secrets.rootPass = config.sops.secrets.openldap-admin-key.path; + }; + services.pubnix.enable = false; + services.userweb = { + enable = false; + domain = "exotic.sh"; + }; + + services.sefidel-web.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.05"; # Did you read the comment? +} + diff --git a/systems/cobalt/hardware-configuration.nix b/systems/cobalt/hardware-configuration.nix new file mode 100644 index 0000000..95ecb96 --- /dev/null +++ b/systems/cobalt/hardware-configuration.nix @@ -0,0 +1,65 @@ +# 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 = + [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { + device = "rpool/local/root"; + fsType = "zfs"; + }; + + fileSystems."/boot" = + { + device = "/dev/disk/by-uuid/445A-0C55"; + fsType = "vfat"; + }; + + fileSystems."/boot-fallback" = + { + device = "/dev/disk/by-uuid/445C-198F"; + fsType = "vfat"; + }; + + fileSystems."/nix" = + { + device = "rpool/local/nix"; + fsType = "zfs"; + }; + + fileSystems."/home" = + { + device = "rpool/safe/home"; + fsType = "zfs"; + }; + + fileSystems."/persist" = + { + device = "rpool/safe/persist"; + fsType = "zfs"; + }; + + 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..useDHCP`. + networking.useDHCP = lib.mkDefault false; + # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/systems/cobalt/secrets/secrets.yaml b/systems/cobalt/secrets/secrets.yaml new file mode 100644 index 0000000..8e0c0e5 --- /dev/null +++ b/systems/cobalt/secrets/secrets.yaml @@ -0,0 +1,39 @@ +acme-envs: ENC[AES256_GCM,data:9IvoY1E2VLikZgPcNnEl2e33SMgLOJsX7aVTEbld1ggl8Z77a2iau17d/ZLWs0+u,iv:gr2iHuYmtZp2eWhX0E0OKolIn/Nm5+9hJqFTYZagV4c=,tag:9mqUFzqe8+3T+Nwbu5V0Fg==,type:str] +matrix-server-key: ENC[AES256_GCM,data:MsPH8g0bc0cY+k5XvVIyi1hDpX2up7+noU9P4Dfm3Z9f1eXv7SaJhlRnR40qrk4sQN1uG0R/ro7S2z9EswX0iZx10PfjWF8Igrc9w9b2+EM/gb0O3dGskPAnDrm9JYh+gF6SsqmwJUEYh+Lx1EfuGMTWpnXZjLrimIWCfmz/1qxJECQds/aQwuA=,iv:B8yzXZ1IUVVvxFQ0MzzS5LSHZXQirnXiLoOru4S2H78=,tag:TNp1Y3C/iYgq5itqXGIt/g==,type:str] +mjolnir-password: ENC[AES256_GCM,data:dyM2VVxn1PFRXy5dgfvq3EuWyGDhDZvJOd1sTnKE5q0Arv1y,iv:DD80um8QXLybj1w4ZsxPbv3+s2NrQfpPDAEpkztkMFo=,tag:3ZEJ7V+ICh2Ip5gZt06zjA==,type:str] +mautrix-telegram-envs: ENC[AES256_GCM,data:hDfEI6tshgPHn/yPHkqO9/VZnB/vTnuyopVm2/0CKoWska66UXOHbXwvO6UXXUZldzkvKe6min3O9xjEGBC+SZdLWmfi6AxJvoKnmU2MzufNkrDG4k0turK7LwwVnm8ADZd9tEII+P3h42t78jhkgerailjP1rtVKleAZpr+ioRGhCTAE6tVWnhV4jveUwNkml+0AhMc3aY0N2PLvedw8p/jsX6Yujn2baKc7HOkvAasctqq/p8kdiTZCA+ASIVC15iR+KtGu2V7vXjDuzYU7Xv7+RbXN7rUTCBIJwyc3XxpwOmD46XR+/2iSZ3nL0PmDftbIEaA9LatjUap7mRFOwX5JruAl1XxAGdG965HZFyTHp1UggjjWvoHQmyb1xJXD5ZE+EU8obkFV0N1o7Q4XIF6/REz9+01JrOd1F5GxjoAo29JV+1lhdxGykrFcA63VLsXdsUgZflWH7Rxol2nOMI5t88+zohYJ5OpeLlRD0gVaX8dvgSzvzmZaNxASW+9tHOQBSzkZsM6jEon6ZXeAa0oh/ee+W82jHhe/ohlj0UV7TtpW/QWs3NR3mv1x41TMBawnVQ7sb9UH/sbdbajJYEAkSD/32ETSjXiQJsmhGEj5kRBNAQA16s1o0M24+UnpHo71jqQnRQpOUtFhLQqakOWvSdM4KgIXExc87Fkw+bQxLtpIup+T4WpJkCe5f5rB/jHvob33oitzjS1mam9UTtzwQjTuR/P4V8IORygDHlcq8W2PtDhWOdgtWI9cfIlqIIgu6+7Rg4+1dq5aw8j06eWrNH2NElPMji0opN+onT3VflgwGPXHlemId20Z2TXNuE6LlnUhyyxdh0rw3tVuCDcodzj4HfXk9mbjlTufyGKY41K/A6QTotiHANojizuTyulyjI3Gx1Wvzv8+Ib84SZGl9ZSsg7g6Ig5U12IJhNtZ/vMj8MHpRjxnyRmZ4jsQi9UctDKrhHjulD1WJyhBveoEv8L79c6e0xZYAwkSlxvdaOPK3OMGbbtbH8vy7WYXSwHZomwJ7BrsrQ/5lWav2xXzgM7ASnEg/rKBPr9YQYOBA==,iv:K2qdi99cjom4mzcNH26qqX3gQNSvZzuAh9QY4zmZv9I=,tag:e9/4biFz6mVsGHV/YOA1jg==,type:str] +dendrite-envs: ENC[AES256_GCM,data:67FnrGQUZWFfHAoUM/idTZlBX7aek3fbPkswB9+3pjLNQuXpIWYoa2vpdGt7zec2n9o9z0V3LdlkookjS95aPpZmKYwPaKkH2L7Jaxw=,iv:c4lEReLizcQeTTiG7cJwd+2sBH+EKBGycKeoDgJ/394=,tag:zBBxIcXn+8Q90BkPidltfQ==,type:str] +sliding-sync-secret: ENC[AES256_GCM,data:lNIlUtNbXw1/w44m7RwqmvOTmc4MYfag7Nvo0izTM6Al7eOZXjEXGgfr7b4PB3QNewghN4LEEj1ae8HqpivT/w==,iv:Qw2XLjYp3/78OuEakUDJ0Sp3fmjw36IJTg8UKTZ7UEU=,tag:tp3gACPEZNMzj+aDP3Ax4A==,type:str] +turn-secret: ENC[AES256_GCM,data:JA5/BlGwH6yIjYsFZGa8Nm8XVbOBKpre+NFybniOtlmbSx89ldKBvuqF2ZoPltJS+vzQ/+wxM/VorhF7M+s4jA==,iv:rK5SFj4VOzgfaP/LIzWTVFyCBmklGMSyd9iWbet2CVc=,tag:QycYCHH72bMMX5UubDHTlg==,type:str] +openldap-admin-key: ENC[AES256_GCM,data:WBBDPFDW6Q4sJ5+/pK8kAe6iFgJ8gGgi3eCVNvZB,iv:1rnmhu29UGsXLxD9Ptbv7P67EAYgKVk1dlkM6p0L4vA=,tag:yNRrHMI2yT8Oo7qkwxSeUg==,type:str] +sefidel-imap-pass: ENC[AES256_GCM,data:rx9hZb+BARs9gB+XLLRMLWDSx67KqkKB1/4nOOtU9i56uagMprFEeDnh8pEaioZbNlqjJRO8kWTBBvWZ,iv:WxKLp0VmwfxVFZt9cnZUbp4wn5WEHubImp8fQy2bXyg=,tag:Vzh0Ntz8iFaSIEf2wjbOKg==,type:str] +internal-imap-pass: ENC[AES256_GCM,data:ydjz/NthnJZFLrR1M+p0xEy5xhM8MbPtqE10r0s1DWDFZoyXwRRrIYefFZheW29EjY3VBfr3zWcRIbNm,iv:6hU/dHADbn4pNi0vlJG8BoyQW1ohByINSO6y+nJddfY=,tag:j67D2stmq2A+ulhFIYkZPA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1jt8xg0lvzj5q4f7fn7nw670qsszm3kv3caa654eh62azra4x44zss4fad8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvbE1CVEFaWXQ4M0lxR1dH + c2dJMGFxTS85ZDhlamRyQWl2Y3VxcXhVdm5RCml3MWl4dkZQK1Z5T3JqTnBLaVU1 + R25PdXJBVWczMGt6RkNWWllXOFJicDAKLS0tIElJYytrUHhzb2xHeTJTRy82bFJR + bm11bEpUaFJjcHB0c2pRendiakRpS2cKNa9ZrFkOLfOqEEN9ATktvrQgANceDj2c + mkUjhxPfti4jNE2c6gsq3DegJT/08QpFJYYuAx/sO2R8wld3kFVyrQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age14a2amn7memzvctf2nnrt6uj458x3g4jpcvs04tlkww2z02p05syqawxrwh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4TEpsUmRQNUxDUU00VENS + MTgxN2ZjM0NYOEdaem5yaW1XaHdlandsQmtNCk5YSzdHdTFqa1BOSkZnajJJenhY + SFdnKzI2WmhONnJ2UWJjRWNGNUhuT0kKLS0tIHNRcVo2VXJEY0tSVUEwVkF0Z2l6 + cUpBZ01CMEFjNnNuWjlYejVKajkwcGMKehqYCZP0zZHDTfJrC/5LYiE/3doa0OiM + OKXhOuUX8HF8RfkyiOSMpntxuNX2jSvd9sQRYnHkUvgm793+IuQjrg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-03-27T15:19:33Z" + mac: ENC[AES256_GCM,data:CyVH0paaTqnff98h5CSCas3YYYYAxEtyYdkjyFBfN/Nwfpe3e71O6YwLZgzAZoiaN+1FuF0kls5WmvDNdx95rEC4yvxQACA75iRyP95B5Q9iN9SGGld0Ii8wPY6s0QkJX+OL7mCllH/gC0J2gOpnPxRB9k5v5FXtKHmJtj5kfaI=,iv:ytWBOy2VTWtVlPbrXiHF5BNxbCmQ194x6aeMh1pd7vc=,tag:0J77TO1y8OTXzdODqANkEw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 -- cgit 1.4.1