From b4bd51410c607e3b4775e12133ee8ad95b24ee26 Mon Sep 17 00:00:00 2001 From: DACHXY Date: Mon, 21 Apr 2025 14:52:42 +0800 Subject: [PATCH] feat: add nextcloud --- system/dev/dn-server/default.nix | 11 +- system/dev/dn-server/nextcloud.nix | 99 ++++++++++++++ system/dev/dn-server/nginx.nix | 30 +++++ system/dev/dn-server/services.nix | 204 +++++++++++++++++++++++++---- system/dev/dn-server/step-ca.nix | 20 +++ system/modules/ca.nix | 28 ++++ system/modules/networking.nix | 5 +- system/modules/presets/basic.nix | 1 + system/modules/presets/minimal.nix | 2 + system/modules/services.nix | 10 +- 10 files changed, 373 insertions(+), 37 deletions(-) create mode 100644 system/dev/dn-server/nextcloud.nix create mode 100644 system/dev/dn-server/nginx.nix create mode 100644 system/dev/dn-server/step-ca.nix create mode 100644 system/modules/ca.nix diff --git a/system/dev/dn-server/default.nix b/system/dev/dn-server/default.nix index cc2307a..71e8817 100644 --- a/system/dev/dn-server/default.nix +++ b/system/dev/dn-server/default.nix @@ -11,11 +11,13 @@ intel-bus-id = settings.nvidia.intel-bus-id; nvidia-bus-id = settings.nvidia.nvidia-bus-id; }) - ./hardware-configuration.nix ./boot.nix - ./packages.nix - ./services.nix + ./hardware-configuration.nix ./networking.nix + ./services.nix + ./nginx.nix + ./nextcloud.nix + # ./step-ca.nix ../../modules/presets/minimal.nix ../../modules/bluetooth.nix ../../modules/cuda.nix @@ -24,6 +26,7 @@ environment.systemPackages = with pkgs; [ ferium + openssl ]; home-manager = { @@ -40,7 +43,7 @@ { home.packages = with pkgs; [ inputs.ghostty.packages.${system}.default - (python3.withPacakges ( + (python3.withPackages ( p: with p; [ pip ] diff --git a/system/dev/dn-server/nextcloud.nix b/system/dev/dn-server/nextcloud.nix new file mode 100644 index 0000000..7f8d8d5 --- /dev/null +++ b/system/dev/dn-server/nextcloud.nix @@ -0,0 +1,99 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + imports = [ + "${ + fetchTarball { + url = "https://github.com/onny/nixos-nextcloud-testumgebung/archive/fa6f062830b4bc3cedb9694c1dbf01d5fdf775ac.tar.gz"; + sha256 = "0gzd0276b8da3ykapgqks2zhsqdv4jjvbv97dsxg0hgrhb74z0fs"; + } + }/nextcloud-extras.nix" + ]; + + services.postgresql = { + enable = true; + authentication = lib.mkOverride 10 '' + #type database DBuser origin-address auth-method + local all all trust + ''; + ensureUsers = [ + { + name = "nextcloud"; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ + "nextcloud" + ]; + }; + + services.nextcloud = { + enable = true; + package = pkgs.nextcloud31; + configureRedis = true; + hostName = "nextcloud.net.dn"; + https = true; + + extraApps = { + inherit (config.services.nextcloud.package.packages.apps) + news + contacts + calendar + tasks + ; + + memories = pkgs.fetchNextcloudApp { + sha256 = "sha256-BfxJDCGsiRJrZWkNJSQF3rSFm/G3zzQn7C6DCETSzw4="; + url = "https://github.com/pulsejet/memories/releases/download/v7.5.2/memories.tar.gz"; + license = "agpl3Plus"; + }; + + passwords = + (pkgs.fetchNextcloudApp { + sha256 = "sha256-Nu6WViFawQWby9CEEezAwoBNdp7O5O8a9IhDp/me/E0="; + url = "https://git.mdns.eu/api/v4/projects/45/packages/generic/passwords/2025.2.0/passwords.tar.gz"; + license = "agpl3Plus"; + }).overrideAttrs + (prev: { + unpackPhase = '' + cp $src passwords.tar.gz + tar -xf passwords.tar.gz + mv passwords/* ./ + rm passwords.tar.gz + rm -rpasswords + ''; + }); + }; + extraAppsEnable = true; + + database.createLocally = true; + config = { + adminpassFile = "/run/keys/nextcloud-admin-password.key"; + dbtype = "pgsql"; + }; + + settings = { + enabledPreviewProviders = [ + "OC\\Preview\\BMP" + "OC\\Preview\\GIF" + "OC\\Preview\\JPEG" + "OC\\Preview\\Krita" + "OC\\Preview\\MarkDown" + "OC\\Preview\\MP3" + "OC\\Preview\\OpenDocument" + "OC\\Preview\\PNG" + "OC\\Preview\\TXT" + "OC\\Preview\\XBitmap" + "OC\\Preview\\HEIC" + ]; + }; + }; + + environment.systemPackages = with pkgs; [ + exiftool + ]; +} diff --git a/system/dev/dn-server/nginx.nix b/system/dev/dn-server/nginx.nix new file mode 100644 index 0000000..edd0905 --- /dev/null +++ b/system/dev/dn-server/nginx.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + ... +}: +{ + services.nginx = { + enable = true; + virtualHosts = { + ${config.services.nextcloud.hostName} = { + listen = lib.mkForce [ + { + addr = "0.0.0.0"; + port = 443; + ssl = true; + } + ]; + forceSSL = true; + sslCertificate = "/var/lib/acme/net.dn.crt"; + sslCertificateKey = "/var/lib/acme/net.dn.key"; + sslTrustedCertificate = "/var/lib/acme/net.dn.crt"; + extraConfig = '' + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers on; + ''; + }; + }; + }; +} diff --git a/system/dev/dn-server/services.nix b/system/dev/dn-server/services.nix index cf3043d..c582569 100644 --- a/system/dev/dn-server/services.nix +++ b/system/dev/dn-server/services.nix @@ -1,14 +1,73 @@ -{ username, pkgs, ... }: +{ + settings, + pkgs, + lib, + ... +}: let + username = settings.personal.username; ethInterface = "enp0s31f6"; - wlInterface = "wlp0s20f3"; sshPorts = [ 30072 ]; sshPortsString = builtins.concatStringsSep ", " (builtins.map (p: builtins.toString p) sshPorts); + + getCleanAddress = + ip: + with builtins; + let + result = replaceStrings [ "/24" "/32" ] [ "" "" ] ip; + in + result; + + getReverseFilename = + ip: + with builtins; + with lib.lists; + with lib.strings; + let + octets = take 3 (splitString "." (getCleanAddress ip)); + reversedFilename = "db." + (concatStringsSep "." (reverseList octets)); + in + reversedFilename; + + getSubAddress = + ip: + with builtins; + with lib.lists; + with lib.strings; + let + octets = reverseList (splitString "." (getCleanAddress ip)); + sub = head octets; + in + sub; + + reverseIP = + ip: + with builtins; + with lib.lists; + with lib.strings; + let + octets = splitString "." (getCleanAddress ip); + reversedIP = (concatStringsSep "." (reverseList octets)) + ".in-addr.arpa"; + in + reversedIP; + + reverseZone = + ip: + with builtins; + with lib.lists; + with lib.strings; + let + octets = take 3 (splitString "." (getCleanAddress ip)); + reversedZone = (concatStringsSep "." (reverseList octets)) + ".in-addr.arpa"; + in + reversedZone; + personal = { ip = "10.0.0.1/24"; interface = "wg0"; port = 51820; + domain = "net.dn"; range = "10.0.0.0/24"; full = "10.0.0.1/25"; restrict = "10.0.0.128/25"; @@ -19,6 +78,9 @@ let range = "10.10.0.0/24"; interface = "wg1"; port = 51821; + masterIP = "10.10.0.1"; + masterHostname = "api-kube.net.dn"; + masterAPIServerPort = 6443; }; allowedSSHIPs = builtins.concatStringsSep ", " [ @@ -72,6 +134,12 @@ let publicKey = "Cm2AZU+zlv+ThMqah6WiLVxgPNvMHm9DEGd4PfywNWU="; allowedIPs = [ "10.0.0.135/32" ]; } + { + # justin03 + dns = "justin"; + publicKey = "WOze/PPilBPqQudk1D4Se34zWV3UghKXWTG6M/f7bEM="; + allowedIPs = [ "10.0.0.136/32" ]; + } { # ahhaha dns = "ahhaha"; @@ -96,14 +164,49 @@ let publicKey = "VVzGcHjSo6QkvN6raS9g/NYLIrZ1xzxdnEronQaTIHs="; allowedIPs = [ "10.0.0.141/32" ]; } + { + dns = "yc-mesh"; + publicKey = "dKcEjRq9eYA8rXVfispNoKEbrs9R3ZIVlQi5AXfFch8="; + allowedIPs = [ "10.0.0.142/32" ]; + } + { + dns = "jonly-mesh"; + publicKey = "EyRL+iyKZJaqz9DXVsH2Ne/wVInx5hg9oQARrXP3/k0="; + allowedIPs = [ "10.0.0.143/32" ]; + } + { + dns = "tommy-mesh"; + publicKey = "oCRNCyg0bw6W6W87XQ4pIUW+WFi/bx9MG4cIwE23GxI="; + allowedIPs = [ "10.0.0.144/32" ]; + } ]; dnsRecords = with builtins; concatStringsSep "\n" ( - map (r: '' - ${r.dns} IN A ${replaceStrings [ "/32" ] [ "" ] (elemAt r.allowedIPs 0)} - '') (fullRoute ++ meshRoute) + map ( + r: + let + ip = getCleanAddress (elemAt r.allowedIPs 0); + in + '' + ${r.dns} IN A ${ip} + '' + ) (fullRoute ++ meshRoute) + ); + + dnsReversedRecords = + with builtins; + concatStringsSep "\n" ( + map ( + r: + let + reversed = getSubAddress (getCleanAddress (elemAt r.allowedIPs 0)); + in + '' + ${reversed} IN PTR ${r.dns}.${personal.domain}. + '' + ) (fullRoute ++ meshRoute) ); in { @@ -124,10 +227,12 @@ in personal.port kube.port 25565 + kube.masterAPIServerPort ]; allowedTCPPorts = sshPorts ++ [ 53 25565 + kube.masterAPIServerPort ]; }; @@ -213,11 +318,12 @@ in }; }; }; + + extraHosts = "${kube.masterIP} ${kube.masterHostname}"; }; services = { dbus.enable = true; - blueman.enable = true; openssh = { @@ -232,6 +338,10 @@ in bind = { enable = true; + forwarders = [ + "8.8.8.8" + "8.8.4.4" + ]; cacheNetworks = [ "127.0.0.0/24" "::1/128" @@ -239,7 +349,7 @@ in kube.range ]; zones = { - "net.dn" = { + "${personal.domain}" = { master = true; allowQuery = [ "127.0.0.0/24" @@ -247,25 +357,67 @@ in personal.range kube.range ]; - file = pkgs.writeText "zone-net.dn" '' - $ORIGIN net.dn. - $TTL 1h - @ IN SOA server hostmaster ( - 1 ; Serial - 3h ; Refresh - 1h ; Retry - 1w ; Expire - 1h) ; Negative Cache TTL - IN NS server - IN NS phone - @ IN A 10.0.0.1 - IN AAAA fe80::3319:e2bb:fc15:c9df - IN MX 10 mail - IN TXT "v=spf1 mx" + file = + let + serverIP = getCleanAddress personal.ip; + kubeIP = getCleanAddress kube.ip; + origin = "${personal.domain}."; + in + pkgs.writeText "db.${personal.domain}" '' + $ORIGIN ${origin} + $TTL 1h + @ IN SOA dns.${origin} admin.dns.${origin} ( + 1 ; Serial + 3h ; Refresh + 1h ; Retry + 1w ; Expire + 1h) ; Negative Cache TTL + IN NS dns.${origin} + @ IN A ${serverIP} + IN AAAA fe80::3319:e2bb:fc15:c9df + IN MX 10 mail.${origin} + IN TXT "v=spf1 mx" + dns IN A ${serverIP} + nextcloud IN A ${serverIP} + ca IN A ${serverIP} + server IN A ${serverIP} + mail IN A ${serverIP} + api-kube IN A ${kubeIP} + ${dnsRecords} + ''; + }; + + "${reverseZone personal.ip}" = { + master = true; + allowQuery = [ + "127.0.0.0/24" + "::1/128" + personal.range + kube.range + ]; + file = + let + serverIP = getSubAddress personal.ip; + mailIP = getSubAddress personal.ip; + in + pkgs.writeText "${getReverseFilename personal.ip}" '' + $TTL 86400 + @ IN SOA dns.${personal.domain}. admin.dns.${personal.domain}. ( + 1 ; Serial + 3h ; Refresh + 1h ; Retry + 1w ; Expire + 1h) ; Negative Cache TTL + IN NS dns.${personal.domain}. + + ${serverIP} IN PTR dns.${personal.domain}. + ${serverIP} IN PTR server.${personal.domain}. + ${serverIP} IN PTR nextcloud.${personal.domain}. + ${serverIP} IN PTR ca.${personal.domain}. + ${mailIP} IN PTR mail.${personal.domain}. + ${dnsReversedRecords} + ''; - server IN A 10.0.0.1 - ${dnsRecords} - ''; }; }; }; @@ -278,7 +430,7 @@ in users.users = { root.openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBzLpMKn0Q24ACC6k/7lOX0FIdcFhq15NY6849yROeUK danny@dn-pre7780" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJSAOufpee7f8D8ONIIGU3qsN+8+DGO7BfZnEOTYqtQ5 danny@pre7780.dn" ]; "${username}".openssh.authorizedKeys.keys = [ diff --git a/system/dev/dn-server/step-ca.nix b/system/dev/dn-server/step-ca.nix new file mode 100644 index 0000000..e034207 --- /dev/null +++ b/system/dev/dn-server/step-ca.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ step-cli ]; + + users.users.step-ca = { + isSystemUser = true; + group = "step-ca"; + }; + + users.groups.step-ca = { }; + + services.step-ca = { + enable = true; + address = "0.0.0.0"; + settings = builtins.fromJSON (builtins.readFile /var/lib/step-ca/config/ca.json); + port = 8443; + openFirewall = true; + intermediatePasswordFile = "/run/keys/step-password"; + }; +} diff --git a/system/modules/ca.nix b/system/modules/ca.nix new file mode 100644 index 0000000..182059b --- /dev/null +++ b/system/modules/ca.nix @@ -0,0 +1,28 @@ +{ + ... + +}: +{ + security.pki.certificates = [ + '' + -----BEGIN CERTIFICATE----- + MIIC5TCCAc2gAwIBAgIUCxaWRHkKr2mQOW2cBzw+Ov9xJaQwDQYJKoZIhvcNAQEL + BQAwGzEZMBcGA1UEAwwQbmV4dGNsb3VkLm5ldC5kbjAeFw0yNTA0MjAxMDQ2MTVa + Fw0zNTA0MTgxMDQ2MTVaMBsxGTAXBgNVBAMMEG5leHRjbG91ZC5uZXQuZG4wggEi + MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY9TBCJoMJ0EREbiGdjLp2odJy + bpKqOyET1J8T/6nBwkgMDpTuAi2Pzp9gJ5lDdzmhhIN2B7f0XWnCNPHsUaHWKfZQ + gEX3LtDSOQrYt4ChMIuzioasJLhGqNyV+4XooIl6R/+2ycQ88I3FoamFDJ0sDkz9 + 2YtKM+UTKyEKSqThF3+W7SbFtHiohT79L5u6pRL2TE6zcqdcOOkqPTOnwbtuRP4+ + bDbFKowBhWTwFSZPpkf010ol6tr5RS8+MqdldmB7NTv9NmyRj2JTNDiQWv7Koq67 + UuDiL1ja+6TFNke47BwKEP1ykz6Ity59V364FljAol477urXNWgppRhOK/1tAgMB + AAGjITAfMB0GA1UdDgQWBBSJtl7lnYwXpMOz6PHjIx7QR9ra6DANBgkqhkiG9w0B + AQsFAAOCAQEAi6M16fhOWS3zi5SDV2KHxa9fJuZcqbgt7ITSr2ex7BpdbMQ17RDT + PyVOQsCVQGF6zY3KqP/+fRYoZzLxnXwPmO/4OXYZoR5UQmoc0VZ9vMTaALIYooYS + t5I/Q8xnH/CmVkt6cIRU4Ysjy4zp9+sobZM7u+Agl0yd2LExzMREjiNpK832hCyz + RZmCrkyekEG3MREuRAqk0vxO7yNTzHMNOG0SzKh49t8WCWWXHyUdxbTzaqXic+R+ + E7dWCFQY5m8ExiqPrKusIMxeerPbs7cXew1mJDEtFqJxpSSa7Jz1XBaMPS3KfcbK + Vhgysawxfe0gSPXwIuOcB+DF8vz6ZdhQYQ== + -----END CERTIFICATE----- + '' + ]; +} diff --git a/system/modules/networking.nix b/system/modules/networking.nix index ce42169..2ffdef4 100644 --- a/system/modules/networking.nix +++ b/system/modules/networking.nix @@ -1,9 +1,10 @@ +{ lib, ... }: { networking = { networkmanager.enable = true; - enableIPv6 = false; + enableIPv6 = lib.mkDefault false; firewall = { - enable = true; + enable = lib.mkDefault true; }; }; } diff --git a/system/modules/presets/basic.nix b/system/modules/presets/basic.nix index 0f166d2..5bc0d3c 100644 --- a/system/modules/presets/basic.nix +++ b/system/modules/presets/basic.nix @@ -25,5 +25,6 @@ ../time.nix ../tmux.nix ../users.nix + ../ca.nix ]; } diff --git a/system/modules/presets/minimal.nix b/system/modules/presets/minimal.nix index 20e70e9..e78d9d7 100644 --- a/system/modules/presets/minimal.nix +++ b/system/modules/presets/minimal.nix @@ -14,5 +14,7 @@ ../sound.nix ../time.nix ../users.nix + ../tmux.nix + ../ca.nix ]; } diff --git a/system/modules/services.nix b/system/modules/services.nix index 325a72c..a0efe8f 100644 --- a/system/modules/services.nix +++ b/system/modules/services.nix @@ -1,4 +1,4 @@ -{ settings, ... }: +{ settings, lib, ... }: { networking = { @@ -15,10 +15,10 @@ enable = true; ports = [ 22 ]; settings = { - PasswordAuthentication = false; - AllowUsers = [ settings.personal.username ]; - UseDns = true; - PermitRootLogin = "no"; + PasswordAuthentication = lib.mkDefault false; + AllowUsers = lib.mkDefault [ settings.personal.username ]; + UseDns = lib.mkDefault true; + PermitRootLogin = lib.mkDefault "no"; }; };