From ba8b726b9073444ad8c86d2e87e4ac28e91fff7b Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Mon, 9 Sep 2024 20:59:35 +0300 Subject: [PATCH] feat: add cloud --- .sops.yaml | 7 ++ hosts/cloud/default.nix | 20 ++++ secrets/cloud/secrets.yaml | 42 +++++++ systems/hosts/cloud/default.nix | 191 ++++++++++++++++++++++++++++++++ systems/hosts/default.nix | 5 + 5 files changed, 265 insertions(+) create mode 100644 hosts/cloud/default.nix create mode 100644 secrets/cloud/secrets.yaml create mode 100644 systems/hosts/cloud/default.nix diff --git a/.sops.yaml b/.sops.yaml index a8623d3..e38e016 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -6,6 +6,7 @@ keys: # LXCs - &alderaan age1h57c3pw5y450yeex3yhlarkaeur5n3le09lm4frf8d3q3qpagfzqdqxm83 - &auth age1wu70y79zuqtk2z5q3t4vvwns2qmerwsy4gn4czf5f4xhch3yquksfwq0q4 + - &cloud age17cw2ynlaw0ruga0u5678vas50k7neevuufk7gsqn8y8673g0mu8szhx4lr - &dns age1m5ktjargxxu04dn9c2uhvaw79z74mxsc4vdrkalxjn4aa8c86plqg0hyyw - &metrics age1m8u3a7rzyx2n6zjxjnfkla34yk3v77egxzd3lv9umt69lsynlaqqqfpt05 - &social age173lqcfnq2a3xwdjkdua6uqyskfhpdqp2lt4jskdkg3rfqv23vu2sgplq98 @@ -37,6 +38,12 @@ creation_rules: - *liljamo_gpg age: - *auth + - path_regex: secrets/cloud/[^/]+\.yaml$ + key_groups: + - pgp: + - *liljamo_gpg + age: + - *cloud - path_regex: secrets/dns/[^/]+\.yaml$ key_groups: - pgp: diff --git a/hosts/cloud/default.nix b/hosts/cloud/default.nix new file mode 100644 index 0000000..49283e8 --- /dev/null +++ b/hosts/cloud/default.nix @@ -0,0 +1,20 @@ +{config, ...}: { + sops.secrets.rootPwd.neededForUsers = true; + sops.secrets.liljamoPwd.neededForUsers = true; + + # Outline is under BSL1.1 + arta.unfree.allow = ["outline"]; + + roles.base = { + root.hashedPasswordFile = config.sops.secrets.rootPwd.path; + primaryUser = { + username = "liljamo"; + hashedPasswordFile = config.sops.secrets.liljamoPwd.path; + }; + }; + + roles.tailscale = { + enable = true; + enableSSH = true; + }; +} diff --git a/secrets/cloud/secrets.yaml b/secrets/cloud/secrets.yaml new file mode 100644 index 0000000..454ec9a --- /dev/null +++ b/secrets/cloud/secrets.yaml @@ -0,0 +1,42 @@ +rootPwd: ENC[AES256_GCM,data:XwfHY6qCxwYOtoKxYp+3gbx2JQpVDrq/KpFdLuSy0Mb026+ixrncicEw4E3R9iq9MnRZJpoauGxw1XQlBcvF2kx2sXZAnQxpHWGPZTunntTiDij/n6ahKbIuGqQHDAzc8KKlnRdCIebgEw==,iv:oAicqT0VJqjWI/Al/aLRDF0rEqCANmUuaml9aR1vKko=,tag:DDzOKvnsKSxZqosJM/gYnw==,type:str] +liljamoPwd: ENC[AES256_GCM,data:kp7QlA523jH3b5QyDqYAehd4vc01HqIqbbZwdVKY0mA6uiqFeUk7PMDwuH7NRnCGD8msaC3gyUUglBtWs3XGWukDA8H+lw5ZqCDaRD+KESURc3/s+LABiUf8Zwm6Dj5zWRmLctot85BWsA==,iv:VevfwnY1YpIRsSFd39cfuioPkGC3PSLlDbCXNmOuwXI=,tag:/e5L2CRWRHeppbyjAmf6gw==,type:str] +outline: + secretKey: ENC[AES256_GCM,data:POFzIrLEWmOAu2+53nD8KIJQ0q6oeDKdzpikfuNwxvjXfORwcG7QXjSU8wWfCXORbrT5knh7rcU9yvvBZXVObQ==,iv:f8dULXac9C6vnXZRvKhIc6WyVYl5eF/nrUs7ZCNdPYQ=,tag:boO+R3ny01WZfHT4WyEJ6A==,type:str] + utilsSecret: ENC[AES256_GCM,data:MUluti1wd8x0z5eIVcPi4n5cmOLBBanM9pRQYPonxbJVAGuPrrfDLGJ8OrqNJGzrN4LmdW57Mhn0kAYf6Jl4Gw==,iv:pM6QdHK1xnYdu+zIoYlBirdhWaZbgud/2IqRO22jHbM=,tag:XOfeAO8DS60Ei8Rq2VofaA==,type:str] + oidcSecret: ENC[AES256_GCM,data:Cf5yh1nXCtKhJVmXqzGvLlZ4gL41XBg4ZuvFEFtu9NcO5kfpV+T22Ntg9nbQ6WK8nThNV4wplrGAbSlOE8n1fQ==,iv:Tp+VgLdB9HxN5gi8nJLuoqrwXBAfb+njcFdGPXiUhAk=,tag:sFUlCxHnIpAhjmqg2aVbCg==,type:str] + smtpPwd: ENC[AES256_GCM,data:z+Uh6h2shWBj/iQ7Xrrh5jyH2py0hTaWxXvwMTCMXR4keoLFXEA9T039nZEkA88+26IkXMPH2Sv01ijaMVJMaaE8M0bwBqf399l03jYhpkIaJ9q6dno0bwHgg2QhF9fk/kPxne5ScazOZtSBuYun85zev82YjYGlb+5jbrpYU+M=,iv:oWYM48IY1QIiS7RSaTjfuSIIAGQrWGtDQJyA6vu3OwQ=,tag:as9Y+i9LTqtvQIhuF9bITw==,type:str] +nextcloud: + adminpass: ENC[AES256_GCM,data:DrjQXb0ua9dfemyRaoRhZ+jgiZRvH8xa7sIcj9O22O8Nmz0DvYe6sHaaIbnJKNr4vttAZSIXIZ8Z2EopxPlwlaTjsyI2/CQmW4VJq5R5GqyQdfdcLFsO/Yjc9LLGaaMqM2LEgtBPZ8MsCzIrAxOuSRPl6EGL+CUfMfsxdl4Iv8E=,iv:lEvKJ8HxcTUs1mylhqOMHs9V/KGkv5YOdHyZMnIyc78=,tag:DqK101a3idk40+MmjKOrnA==,type:str] + dbpass: ENC[AES256_GCM,data:JFjdXW1K8HwW,iv:TJQuf1uftrNs6oXi6zxquu7w7iwwKrL7ljCjVLwbVUo=,tag:7kgtyJilrO0pG1avxielKQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age17cw2ynlaw0ruga0u5678vas50k7neevuufk7gsqn8y8673g0mu8szhx4lr + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMaDBZcStOMzRpVzNBNUIx + ZmpDdkt4ZW1KUmRDUnhaN3dmK1ZseFVJMlRjCjhaTGcvR3FpMGdNcmpNeVQ1Q3lk + cUUxaTJaMG1vOVpFbGtRQkVlQkIyUVkKLS0tIHIrZk9HUkVsNjUvOFVwTmwzaFZu + TjduMkxMazUveTlUdStwRGJaRDlpaTAKW7P6B3W1tih2S81TRY7m/Me9Gr6CwZLi + Wymq21dT+Or2FR8F2LZDHG8WiUOu/8bvSZ0ZYZpfs5mCvufdRhPFaA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-09-09T17:30:36Z" + mac: ENC[AES256_GCM,data:Vhz/eGr3oC9eIil13kDrct3o1SyUB85ZQ+Ho8HSLeDyj6cgqPLqM5GoZlzE/ttR9VZN0FXJpULWMq/0jyiJbpTMh24jj0+iPTBHzagAyjeXSboOh3FQ04FIoDB20+o4gmmHhPjk1F9HuWwzc0dcO4WgHCC7QWPBL0I0uX3Vmpuw=,iv:bbohTgOSzgo4M6eeG17VSy0Tf84vI9svFnrsvKALdok=,tag:mo9MQuVgtuaDfyw7vfKz7Q==,type:str] + pgp: + - created_at: "2024-09-09T17:25:01Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4D8ab0ENzkR4wSAQdATt7SdwiDH6aKlpyPYFBTBv81i3jqM2mu8w0HuqH+TUYw + dkPasoA93vwwYBekgO1WwcLa31kY57G0DoUHx5YngKEmumFC5TGajeUioCCLGVQM + 1GYBCQIQAtIQhO5N2qT5sSPnik2uDttAma9Y0iigY9ZJ0C3AH0O5J53TZOIBVqw5 + aWHgwFoDkNULMBaM9iUjcICuXdoVXD6ILGPgXE2uhar/FCqHlv8MFQOSW/luIsGg + uYnNZ/yu4Ts= + =0s/b + -----END PGP MESSAGE----- + fp: 848EEBCEE9F0D29D25C321A658577946A65EB712 + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/systems/hosts/cloud/default.nix b/systems/hosts/cloud/default.nix new file mode 100644 index 0000000..b4ea6ca --- /dev/null +++ b/systems/hosts/cloud/default.nix @@ -0,0 +1,191 @@ +{ + config, + lib, + pkgs, + ... +}: let + outlinePort = 3000; +in { + networking.firewall.allowedTCPPorts = [80 config.services.outline.port]; + + sops.secrets."outline/secretKey" = { + owner = "outline"; + group = "outline"; + }; + sops.secrets."outline/utilsSecret" = { + owner = "outline"; + group = "outline"; + }; + sops.secrets."outline/oidcSecret" = { + owner = "outline"; + group = "outline"; + }; + sops.secrets."outline/smtpPwd" = { + owner = "outline"; + group = "outline"; + }; + sops.secrets."nextcloud/adminpass" = { + owner = "nextcloud"; + group = "nextcloud"; + }; + sops.secrets."nextcloud/dbpass" = { + owner = "nextcloud"; + group = "nextcloud"; + }; + + environment.systemPackages = with pkgs; [ + ffmpeg-headless + gnumake + nodePackages_latest.nodejs + nodePackages_latest.node-pre-gyp + python3 + ]; + users.users.nextcloud.extraGroups = ["render" "users"]; + + services = { + nextcloud = { + enable = true; + package = pkgs.nextcloud29; + caching = { + redis = true; + }; + config = { + adminpassFile = config.sops.secrets."nextcloud/adminpass".path; + adminuser = "admin"; + dbhost = "127.0.0.1:5432"; + dbname = "nextcloud"; + dbtype = "pgsql"; + dbuser = "nextcloud"; + dbpassFile = config.sops.secrets."nextcloud/dbpass".path; + }; + configureRedis = true; + settings = { + default_phone_region = "FI"; + loglevel = 2; + log_type = "file"; + maintenance_window_start = 0; # Maintenance window from UTC 0000 to 0400 + redis = { + host = "/run/redis-nextcloud/redis.sock"; + }; + trusted_domains = ["nextcloud.rustylily.home.arpa"]; + trusted_proxies = ["10.1.2.10"]; + opcache.interned_strings_buffer = 64; # Megabytes of memory to use + overwriteprotocol = "https"; + + # Programs needed for... stuff. + preview_ffmpeg_path = "${lib.getExe pkgs.ffmpeg}"; + memories.exiftool = "${lib.getExe pkgs.exiftool}"; + memories.exiftool_no_local = true; + memories.ffmpeg_path = "${pkgs.ffmpeg-headless}/bin/ffmpeg"; + memories.ffprobe_path = "${pkgs.ffmpeg-headless}/bin/ffprobe"; + memories.vod.ffmpeg = "${pkgs.ffmpeg-headless}/bin/ffmpeg"; + memories.vod.ffprobe = "${pkgs.ffmpeg-headless}/bin/ffprobe"; + }; + hostName = "cloud.liljamo.com"; + https = true; + maxUploadSize = "2048M"; + phpOptions."output_buffering" = "0"; + phpExtraExtensions = all: [all.pdlib all.bz2]; + }; + outline = { + enable = true; + port = outlinePort; + user = "outline"; + group = "outline"; + databaseUrl = "postgres://outline:outline@127.0.0.1/outline?sslmode=disable"; + redisUrl = "redis://127.0.0.1:3079"; + enableUpdateCheck = false; + maximumImportSize = 5120000; + publicUrl = "https://docs.liljamo.com"; + secretKeyFile = config.sops.secrets."outline/secretKey".path; + utilsSecretFile = config.sops.secrets."outline/utilsSecret".path; + storage = { + storageType = "local"; + }; + oidcAuthentication = { + authUrl = "https://auth.liljamo.com/api/oidc/authorization"; + clientId = "outline"; + clientSecretFile = config.sops.secrets."outline/oidcSecret".path; + displayName = "Liljamo Auth"; + scopes = ["openid" "offline_access" "profile" "email"]; + tokenUrl = "https://auth.liljamo.com/api/oidc/token"; + userinfoUrl = "https://auth.liljamo.com/api/oidc/userinfo"; + usernameClaim = "preferred_username"; + }; + smtp = { + host = "smtp.migadu.com"; + port = 465; + fromEmail = "outline@liljamo.com"; + replyEmail = "outline@liljamo.com"; + username = "outline@liljamo.com"; + passwordFile = config.sops.secrets."outline/smtpPwd".path; + }; + }; + postgresql = { + package = pkgs.postgresql_15; + enable = true; + settings.port = 5432; + ensureDatabases = ["outline" "nextcloud"]; + ensureUsers = [ + { + name = "outline"; # needs to match the user that's running outline + ensureDBOwnership = true; + } + { + name = "nextcloud"; + ensureDBOwnership = true; + } + ]; + }; + redis.servers = { + outline = { + enable = true; + bind = "127.0.0.1"; + port = 3079; + }; + nextcloud = { + enable = true; + bind = "127.0.0.1"; + port = 3179; + }; + }; + }; + + systemd = { + timers = { + nextcloud-update-files = { + wantedBy = ["timers.target"]; + timerConfig = { + OnBootSec = "2m"; + OnUnitActiveSec = "15m"; + Unit = "nextcloud-update-files.service"; + }; + }; + }; + services = { + nextcloud-cron.path = [pkgs.perl]; + nextcloud-update-files = { + bindsTo = ["postgresql.service" "phpfpm-nextcloud.service"]; + after = ["postgresql.service" "phpfpm-nextcloud.service"]; + script = '' + ${config.services.nextcloud.occ}/bin/nextcloud-occ files:scan -q --all + ${config.services.nextcloud.occ}/bin/nextcloud-occ preview:pre-generate + ''; + serviceConfig.User = "nextcloud"; + path = ["config.services.nextcloud" pkgs.perl]; + }; + nextcloud-occ-settings = { + after = ["nextcloud-setup.service"]; + serviceConfig = { + Type = "oneshot"; + User = "nextcloud"; + }; + script = '' + ${config.services.nextcloud.occ}/bin/nextcloud-occ config:app:set dav system_addressbook_exposed --value="no" + ''; + }; + }; + }; + + system.stateVersion = "24.05"; +} diff --git a/systems/hosts/default.nix b/systems/hosts/default.nix index 5fda8b0..1024e25 100644 --- a/systems/hosts/default.nix +++ b/systems/hosts/default.nix @@ -27,6 +27,11 @@ profile = lxc; modules = []; }; + cloud = { + system = "x86_64-linux"; + profile = lxc; + modules = []; + }; dns = { system = "x86_64-linux"; profile = lxc; -- 2.44.1