From 51d51f5398e42f12722f7c7066fae0a664e04327 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Wed, 23 Nov 2022 13:27:01 +0800 Subject: [PATCH] hosts/plover: init --- .sops.yaml | 3 + hosts/plover/README.adoc | 18 ++ hosts/plover/default.nix | 217 +++++++++++++++++++++ hosts/plover/files/host-key.pub | 1 + hosts/plover/files/srht-webhook-public-key | 1 + hosts/plover/hardware-configuration.nix | 19 ++ hosts/plover/secrets/secrets.yaml | 34 ++++ users/nixos/plover/default.nix | 22 +++ 8 files changed, 315 insertions(+) create mode 100644 hosts/plover/README.adoc create mode 100644 hosts/plover/default.nix create mode 100644 hosts/plover/files/host-key.pub create mode 100644 hosts/plover/files/srht-webhook-public-key create mode 100644 hosts/plover/hardware-configuration.nix create mode 100644 hosts/plover/secrets/secrets.yaml create mode 100644 users/nixos/plover/default.nix diff --git a/.sops.yaml b/.sops.yaml index 3e503f48..53206a0e 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -2,9 +2,12 @@ keys: - &foo-dogsquared 8FCE86932583783E515B6FE55F2B001E20ED3763 - &foo-dogsquared-age age1say65zc678yc03tx4zexp20c9gvskvwrm4390j4x2jkepn97duhq9ptuj9 - &ni age1dm9xugju4q5gx0zty8ckw655ea904c64gv9qw9fn3lu507ck8uzsag59y8 + - &plover age1sj497yr895335rk77qqnrqyx9f7462ma3lz0a0x3w5cnla5uqgpspgggtz creation_rules: - path_regex: hosts/ni/secrets/[^/]+\.(yaml|json)$ age: *ni + - path_regex: hosts/plover/secrets/[^/]+\.(yaml|json)$ + age: *plover - path_regex: secrets/[^/]+\.(yaml|json)$ key_groups: - age: diff --git a/hosts/plover/README.adoc b/hosts/plover/README.adoc new file mode 100644 index 00000000..3d09026a --- /dev/null +++ b/hosts/plover/README.adoc @@ -0,0 +1,18 @@ += Plover, the general-purpose server + +This is Plover, a configuration meant to be used in a low-powered general-purpose machine. +It isn't much of an instance to be seriously used yet but hopefully it is getting there. + +This configuration is expected to be deployed in a Google Compute instance. + +It has a reasonable set of assumptions to keep in mind when modifying this configuration: + +- Most of the defaults are left to the link:https://github.com/NixOS/nixpkgs/tree/f92201f46109aabbbf41b8dc24bb9d342eb93a35/nixos/modules/virtualisation[image profiles from nixpkgs] including networking options and filesystems. +- No additional storage drives. +- At least 32 GB of space is assumed. + +Some of the self-hosted services from this server: + +* An nginx server which will make tie all of the self-hosted services together. +* A link:https://github.com/dani-garcia/vaultwarden[Vaultwarden] instance for a little password management. +* A link:https://gitea.io/[Gitea] instance for my personal projects. diff --git a/hosts/plover/default.nix b/hosts/plover/default.nix new file mode 100644 index 00000000..9ddd8716 --- /dev/null +++ b/hosts/plover/default.nix @@ -0,0 +1,217 @@ +{ config, options, lib, pkgs, ... }: + +let + domain = "foodogsquared.one"; + passwordManagerDomain = "vault.${domain}"; + codeForgeDomain = "forge.${domain}"; +in +{ + imports = [ + (lib.getUser "nixos" "plover") + ]; + + sops.secrets = + let + getKey = key: { + inherit key; + sopsFile = ./secrets/secrets.yaml; + }; + getSecrets = keys: + lib.listToAttrs (lib.lists.map + (secret: + lib.nameValuePair + "plover/${secret}" + (getKey secret)) + keys); + in + getSecrets [ + "ssh-key" + "gitea/db/password" + ]; + + # Be sure to upload this manually. (It's this really a good idea?) + sops.age.keyFile = "/var/lib/sops-nix/key.txt"; + + services.nginx = { + enable = true; + enableReload = true; + package = pkgs.nginxMainline; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + + virtualHosts = { + # These are just websites that are already deployed. + "www.${domain}" = { + locations."/" = { + proxyPass = "https://foodogsquared.netlify.app"; + }; + }; + "wiki.${domain}" = { + locations."/" = { + proxyPass = "https://foodogsquared-wiki.netlify.app"; + }; + }; + "search.${domain}" = { + locations."/" = { + proxyPass = "https://search.brave.com"; + }; + }; + + # Vaultwarden instance. + "${passwordManagerDomain}" = { + http2 = true; + forceSSL = true; + enableACME = true; + locations = let + port = config.services.vaultwarden.config.ROCKET_PORT; + websocketPort = config.services.vaultwarden.config.WEBSOCKET_PORT; + in { + "/" = { + proxyPass = "http://localhost:${toString port}"; + proxyWebsockets = true; + }; + + "/notifications/hub" = { + proxyPass = "http://localhost:${toString websocketPort}"; + proxyWebsockets = true; + }; + + "/notifications/hub/negotiate" = { + proxyPass = "http://localhost:${toString port}"; + proxyWebsockets = true; + }; + }; + }; + + "${codeForgeDomain}" = { + http2 = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:${config.services.gitea.httpPort}"; + }; + }; + }; + }; + + # Time to harden... + profiles.system.hardened-config.enable = true; + + security.acme = { + acceptTerms = true; + defaults.email = "admin@foodogsquared.one"; + + certs = { + "${passwordManagerDomain}".keyType = "rs2048"; + "${codeForgeDomain}" = {}; + }; + }; + + # Some additional dependencies for this system. + environment.systemPackages = with pkgs; [ + asciidoctor + ]; + + # My code forge. + services.gitea = { + inherit domain; + enable = true; + appName = "foodogsquared's code forge"; + # TODO: Use postgresql later + database = { + passwordFile = config.sops.secrets."plover/gitea/db/password".path; + #type = "postgres"; + }; + lfs.enable = true; + #mailerPasswordFile = config.sops.secrets."plover/gitea/smtp/password".path; + rootUrl = "http://${codeForgeDomain}"; + + settings = { + "repository.pull_request" = { + WORK_IN_PROGRESS_PREFIXES = "WIP:,[WIP],DRAFT,[DRAFT]"; + ADD_CO_COMMITTERS_TRAILERS = true; + }; + + ui = { + EXPLORE_PAGING_SUM = 15; + GRAPH_MAX_COMMIT_NUM = 200; + }; + + "ui.meta" = { + AUTHOR = "foodogsquared's code forge"; + DESCRIPTION = '' + foodogsquared's personal Git forge. + Mainly personal projects and some archived and mirrored codebases. + ''; + KEYWORDS = "foodogsquared,gitea,self-hosted"; + }; + + # It's a personal instance so nah... + service.DISABLE_REGISTRATION = true; + + repository = { + ENABLE_PUSH_CREATE_USER = true; + DEFAULT_PRIVATE = "public"; + DEFAULT_PRIVATE_PUSH_CREATE = true; + }; + + "markup.asciidoc" = { + ENABLED = true; + NEED_POSTPROCESS = true; + FILE_EXTENSIONS = ".adoc,.asciidoc"; + RENDER_COMMANDS = "asciidoc --out-file=- -"; + IS_INPUT_FILE = false; + }; + + # Well, collaboration between forges is nice... + federation.ENABLED = true; + + # Enable mirroring feature... + mirror.ENABLED = true; + + other = { + SHOW_FOOTER_VERSION = true; + ENABLE_SITEMAP = true; + ENABLE_FEED = true; + }; + }; + }; + + # An alternative implementation of Bitwarden written in Rust. The project + # being written in Rust is a insta-self-hosting material right there. + services.vaultwarden = { + enable = true; + config = { + DOMAIN = "https://${passwordManagerDomain}"; + + # Configuring the server. + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8222; + ROCKET_LOG = "critical"; + + # Ehh... It's only a few (or even one) users anyways so nah. Since this + # instance will not configure SMTP server, this pretty much means + # invitation is only via email at this point. + SHOW_PASSWORD_HINT = false; + + # Configuring some parts of account management which is almost + # nonexistent because this is just intended for me (at least right now). + SIGNUPS_ALLOWED = false; + SIGNUPS_VERIFY = true; + INVITATIONS_ALLOWED = true; + + # Notifications... + WEBSOCKET_ENABLED = true; + WEBSOCKET_PORT = 3012; + WEBSOCKET_ADDRESS = "0.0.0.0"; + + # Enabling web vault with whatever nixpkgs comes in. + WEB_VAULT_ENABLED = true; + WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden"; + }; + }; + + system.stateVersion = "22.11"; +} diff --git a/hosts/plover/files/host-key.pub b/hosts/plover/files/host-key.pub new file mode 100644 index 00000000..cd3c1f5d --- /dev/null +++ b/hosts/plover/files/host-key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC1z9XnJJLWLlIZhr+3GT62JWtm6HC90K4yikgvsfbp6 Plover server diff --git a/hosts/plover/files/srht-webhook-public-key b/hosts/plover/files/srht-webhook-public-key new file mode 100644 index 00000000..205abc62 --- /dev/null +++ b/hosts/plover/files/srht-webhook-public-key @@ -0,0 +1 @@ +aMvCMlRjPmXZl+s3zn0Fs9cOxkkD88B4mymz3H+IomM= diff --git a/hosts/plover/hardware-configuration.nix b/hosts/plover/hardware-configuration.nix new file mode 100644 index 00000000..839007aa --- /dev/null +++ b/hosts/plover/hardware-configuration.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, modulesPath, ... }: + +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + fileSystems."/" = { + label = "nixos"; + fsType = "ext4"; + autoResize = true; + }; + + fileSystems."/srv" = { + label = "data"; + options = [ + "discard" + "defaults" + ]; + fsType = "ext4"; + }; +} diff --git a/hosts/plover/secrets/secrets.yaml b/hosts/plover/secrets/secrets.yaml new file mode 100644 index 00000000..ff25ab87 --- /dev/null +++ b/hosts/plover/secrets/secrets.yaml @@ -0,0 +1,34 @@ +ssh-key: ENC[AES256_GCM,data:qAExtufRmVYPTLAyJ7P7baYfkvTsEFtHR8I9a1o08bZ9odl0JXTJpuX+qmm5TQyfqzn2SSJLNQjsXHoGYE9B34Y6n29R9LM7Ssc0V/zSNbv4Qzy4JYD7rbiULXE6aJLL1uU4M2C6GFlIlikZm0K9Bh8MQPyx2oJtN5AI8fuVxK0AGeRVGS5M5FaYj4ccfR//B2066Ga2KAs/xKq4rj88jxOv3sSY/S+lRuR0uixV7GI3TJK15OtVIvOX1lZIQyOrfMmdJbWaW4zezAHt8GzBr/VJJdYRv5FOWTiuIWKl80vr0YmxHs9Ol+4d0Dcm48+lxg6GUp6I1+V6/tVvKDakGV901NcVra6e0qZX4L6uHgyRQ4k939GZcCtg6e7CLtrVU31SMuC34EcSJP4DkkWis9dYVZCGwZi0+mhtDO8BzzqrH+wmlgxYh/a0lIMgUO7wN8KbWVX0XN0Tsmhc66NZkxoLDdTZSUDVqItl/Pj/21Sn6+P8m/MdvIlBbcLB0Q+RE55IfU374rGhGxHUIaUk,iv:ffYR1jqrwm94SA9OlRwjALcaGvw4tcrJDdT3YhpM2Qk=,tag:CQoclfSo/ZOuqMlC6dIMXA==,type:str] +sourcehut: + network-key: ENC[AES256_GCM,data:/wrk2b2CvOECvBJGVUuHtNMOfQf0l3leweZlDVJRTCUHlifEkxPvNyL9bZo=,iv:44VlT5ID8KXDquDOZMIEPBWl7r+JwbamRdqhBsFO4Rw=,tag:KVRe5bYuwqeCcKiiJZxRDA==,type:str] + service-key: ENC[AES256_GCM,data:wYGipx79xs/456f3tiUa/P6Pz/IVDSZc0rNxXp4g5swK+n/OwCLK4UJu5baeoHzAxv7wPilKqRbSEuQWbeJShQ==,iv:S4BzMYPZtVFhXV0g5qBxjItqCyEQ25Ct6swBut7FefQ=,tag:/asB4OAKxGm/8UWiIJzmNg==,type:str] + webhook-key: ENC[AES256_GCM,data:4QSxP6MGS+TUcfBIB3OwIzveJAC3QKeS4cjHwKfLCORrw0tHuMowNoOVnp4=,iv:nUCkIgw5lNzEha6HVjBHtGD8ZzBwOlP8yMRQ/usD/64=,tag:SJU1Q48mwf34HTjJ71q/6Q==,type:str] + smtp: + user: ENC[AES256_GCM,data:Lr/tkIk=,iv:kF7GXxsJupbGZlvvgfL6gKGZl1+W2rsr++XsVykVYOI=,tag:NcHjd1/yXWQmzzbuTGW/Dg==,type:str] + password: ENC[AES256_GCM,data:ZlFyFiA=,iv:2nSH03+WlA4xylK60DhlX32HYOnFwtXEEFwKPvdFCBw=,tag:IboFoNAGe41koc/3lTp2GQ==,type:str] +gitea: + db: + password: ENC[AES256_GCM,data:Roc8HAPbQQWYS9x7nVpGO1rb+mUDduK3CI5qxDudcQQw7sqGzaRW3ParZvUcFVQA/+5xV2pkVkpTkKJEF44G9Nv+THNSGDFX7g==,iv:zChXWYtY1BIwE0ROJYtVj3FNhJbSLh/mu7adbhliawU=,tag:Dvv/8JmxMZjLPcmXcK1INQ==,type:str] + smtp: + #ENC[AES256_GCM,data:Wd0tLHr3kQMASBa0om3y4BM=,iv:2MvRyhaJY5hgHqZOlLcIwsCMlYB/nZJk1ZLpoFSNqrI=,tag:6Rr1zMQ2ehvIwkqKBAO7uw==,type:comment] + password: null +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sj497yr895335rk77qqnrqyx9f7462ma3lz0a0x3w5cnla5uqgpspgggtz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwdnpLYXUxVDZ0Yk1JM1d5 + OUxsUVJIR3MrcVVId1ZxaHU3amZ5WThKNm04CkRMUU5nQ1RXLzhGNDVMNUVkR1lE + VHJveENMWHVrNHBscEExeDBtUFdSSkUKLS0tIDE1NlZyc1puYWVzazZJaldNTVM1 + akJBYVU2bnBoRWZBQnRFeXpZdzIrdzAK1ZOvzCL8F5+cLobdKIqPUfFJXy/LjbfF + T2VmFyqV1Gx+tnrrGhdmJyP6F24q9S5BUi0TzMCIOspPEau7pTBpaQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2022-11-24T15:12:10Z" + mac: ENC[AES256_GCM,data:rk2x9xBywOJLoga3Qz8bBThNKgm/LMlRZzTfva++kY2qaNhXlV+kRWdN/ERtYRlQ+XI87EsK82QCniqg0paGRnLiyhGluW0iMmMNlt3UthpFUfOwYZ87J/tu2l5iyaj/bd0lMgFwn2vQWelSnmDg+o6tXxzGbyAP+mVj6mnC/q8=,iv:jnctvTpNlvT49/l20BuyC25ptHuqjS62mU3ffxgJ8sE=,tag:zH3HZAEA+nIssXSYH4M+vQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/users/nixos/plover/default.nix b/users/nixos/plover/default.nix new file mode 100644 index 00000000..4f509d31 --- /dev/null +++ b/users/nixos/plover/default.nix @@ -0,0 +1,22 @@ +# This is the user that is often used for servers. +{ lib, pkgs, ... }: + +{ + users.users.plover = { + # Change this immediately pls. + initialHashedPassword = "$6$gpgBrL3.RAGa9NBp$93Ac5ZW53KcgbA9q4awVKA.bVArP7Hw1NbyakT30Mav.7obIuN17WWijT.EaBSJU6ArvdXTehC3xZ9/9oZPDR0"; + extraGroups = [ "wheel" ]; + useDefaultShell = true; + isNormalUser = true; + description = "The go-to user for server systems."; + }; + + environment.systemPackages = with pkgs; [ + wireshark-cli + bind.dnsutils + nettools + bat + fd + jq + ]; +}