diff --git a/modules/server/acme.nix b/modules/server/acme.nix new file mode 100644 index 0000000..8caea58 --- /dev/null +++ b/modules/server/acme.nix @@ -0,0 +1,28 @@ +{ + config, + pkgs, + ... +}: +{ + security = { + acme = { + acceptTerms = true; + defaults = { + email = "oqyude@zeroq.su"; + server = "https://localhost:9000/acme/acme/directory"; + dnsProvider = null; + }; + # certs = { + # # "home.arpa" = { + # # domain = "*.home.arpa"; + # # server = "https://localhost:9000/acme/acme/directory"; + # # listenHTTP = ":80"; + # # }; + # "turn.home.arpa" = { + # listenHTTP = "127.0.0.1:80"; + # group = "turnserver"; + # }; + # }; + }; + }; +} diff --git a/modules/server/coredns.nix b/modules/server/coredns.nix index 8f505a0..33969d4 100644 --- a/modules/server/coredns.nix +++ b/modules/server/coredns.nix @@ -19,6 +19,8 @@ 192.168.1.20 nextcloud.zeroq.su 192.168.1.20 office.zeroq.su 192.168.1.20 pdf.zeroq.su + 192.168.1.20 talk.zeroq.su + 192.168.1.20 turn.zeroq.su fallthrough } cache 300 diff --git a/modules/server/coturn.nix b/modules/server/coturn.nix new file mode 100644 index 0000000..f2392d0 --- /dev/null +++ b/modules/server/coturn.nix @@ -0,0 +1,53 @@ +{ + config, + inputs, + lib, + pkgs, + xlib, + ... +}: +# let +# acme-path = "/var/lib/acme"; +# in +{ + services.coturn = { + enable = false; + realm = "turn.home.arpa"; + # cert = "${acme-path}/turn.home.arpa/fullchain.pem"; + # pkey = "${acme-path}/turn.home.arpa/key.pem"; + use-auth-secret = true; + static-auth-secret-file = config.sops.secrets.turn-secret.path; + no-cli = true; + listening-port = 3478; # TURN + # tls-listening-port = 5349; # TURNS + extraConfig = '' + min-port=49160 + max-port=49200 + ''; + }; + networking.firewall = { + allowedTCPPorts = [ + 3478 + # 5349 + ]; + allowedUDPPorts = [ + 3478 + ]; + allowedUDPPortRanges = [ + { + from = 49160; + to = 49200; + } + ]; + }; + sops.secrets = { + turn-secret = { + format = "yaml"; + key = "turn-secret"; + sopsFile = ./secrets/coturn.yaml; + # group = "nextcloud-spreed-signaling"; + # owner = "turnserver"; + mode = "0440"; + }; + }; +} diff --git a/modules/server/default.nix b/modules/server/default.nix index e6f45d7..a003011 100644 --- a/modules/server/default.nix +++ b/modules/server/default.nix @@ -5,10 +5,12 @@ { imports = [ ../software/beets + ./acme.nix ./bentopdf.nix ./calibre-web.nix ./chrony.nix ./coredns.nix + ./coturn.nix ./gitea.nix ./glances.nix ./immich.nix diff --git a/modules/server/nextcloud.nix b/modules/server/nextcloud.nix index f43d556..1599a60 100644 --- a/modules/server/nextcloud.nix +++ b/modules/server/nextcloud.nix @@ -22,6 +22,38 @@ in }; secrets = [ config.sops.secrets.nextcloud-whiteboard-jwt.path ]; }; + nextcloud-spreed-signaling = { + enable = false; + hostName = "talk.private"; + backends.nextcloud = { + urls = [ + "https://nextcloud.home.arpa" + "https://nextcloud.zeroq.su" + ]; + secretFile = config.sops.secrets.nextcloud-talk-secret.path; + }; + settings = { + http.listen = "127.0.0.1:8080"; + clients.internalsecretFile = config.sops.secrets.internal-secret.path; + sessions = { + hashkeyFile = config.sops.secrets.hashkey.path; + blockkeyFile = config.sops.secrets.blockkey.path; + }; + mcu = { + type = "janus"; + url = "ws://127.0.0.1:8188"; + }; + turn = { + secretFile = config.sops.secrets.turn-secret.path; + apikeyFile = config.sops.secrets.turn-api-key.path; + servers = [ + "turn:turn.home.arpa:3478?transport=udp" + "turn:turn.home.arpa:3478?transport=tcp" + # "turns:turn.home.arpa:5349?transport=tcp" + ]; + }; + }; + }; nextcloud = { enable = true; package = pkgs.nextcloud33; @@ -223,5 +255,51 @@ in group = "onlyoffice"; mode = "0650"; }; + nextcloud-talk-secret = { + format = "yaml"; + key = "nextcloud-talk-secret"; + sopsFile = ./secrets/nextcloud.yaml; + # owner = "nextcloud-spreed-signaling"; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; + internal-secret = { + format = "yaml"; + key = "internal-secret"; + sopsFile = ./secrets/nextcloud.yaml; + # owner = "nextcloud-spreed-signaling"; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; + hashkey = { + format = "yaml"; + key = "hashkey"; + sopsFile = ./secrets/nextcloud.yaml; + # owner = "nextcloud-spreed-signaling"; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; + blockkey = { + format = "yaml"; + key = "blockkey"; + sopsFile = ./secrets/nextcloud.yaml; + # owner = "nextcloud-spreed-signaling"; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; + turn-secret = { + format = "yaml"; + key = "turn-secret"; + sopsFile = ./secrets/coturn.yaml; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; + turn-api-key = { + format = "yaml"; + key = "turn-api-key"; + sopsFile = ./secrets/coturn.yaml; + # group = "nextcloud-spreed-signaling"; + mode = "0440"; + }; }; } diff --git a/modules/server/nginx.nix b/modules/server/nginx.nix index f0bc550..c3657cf 100644 --- a/modules/server/nginx.nix +++ b/modules/server/nginx.nix @@ -94,6 +94,32 @@ in client_max_body_size 5G; ''; }; + # "talk.home.arpa" = { + # forceSSL = true; + # enableACME = true; + # # locations = { + # # "/" = { + # # proxyPass = "http://127.0.0.1:7880"; + # # proxyWebsockets = true; + # # }; + # # }; + # extraConfig = '' + # client_max_body_size 5G; + # ''; + # }; + # "turn.home.arpa" = { + # forceSSL = true; + # enableACME = true; + # locations = { + # "/" = { + # proxyPass = "http://127.0.0.1:5349"; + # proxyWebsockets = true; + # }; + # }; + # extraConfig = '' + # client_max_body_size 5G; + # ''; + # }; "ca.home.arpa" = { forceSSL = true; enableACME = true; @@ -215,14 +241,4 @@ in }; }; }; - security = { - acme = { - acceptTerms = true; - defaults = { - email = "oqyude@zeroq.su"; - server = "https://localhost:9000/acme/acme/directory"; - dnsProvider = null; - }; - }; - }; } diff --git a/modules/server/samba.nix b/modules/server/samba.nix index 7117e67..67b9b5a 100644 --- a/modules/server/samba.nix +++ b/modules/server/samba.nix @@ -1,55 +1,65 @@ { config, + pkgs, xlib, ... }: { - services.samba = { - enable = true; - nmbd = { + services = { + samba-wsdd = { enable = true; + openFirewall = true; + hostname = "sapphira.home.arpa"; + discovery = true; }; - settings = { - global = { - "invalid users" = [ ]; - "passwd program" = "/run/wrappers/bin/passwd %u"; - security = "user"; + samba = { + enable = true; + package = pkgs.samba4Full; + nmbd = { + enable = true; }; - nixos = { - "path" = "/etc/nixos"; - "browseable" = "yes"; - "read only" = "no"; - "valid users" = "${xlib.device.username}"; - "guest ok" = "no"; - "writable" = "yes"; - "create mask" = 755; - "directory mask" = 755; - "force user" = "${xlib.device.username}"; - "force group" = "users"; - }; - root = { - "path" = "/"; - "browseable" = "yes"; - "read only" = "no"; - "valid users" = "${xlib.device.username}"; - "guest ok" = "no"; - "writable" = "yes"; - #"create mask" = 0644; - #"directory mask" = 0644; - "force user" = "root"; - "force group" = "root"; - }; - "${xlib.device.username}" = { - "path" = "${xlib.dirs.server-home}"; - "browseable" = "yes"; - "read only" = "no"; - "valid users" = "${xlib.device.username}"; - "guest ok" = "no"; - "writable" = "yes"; - "create mask" = 700; - "directory mask" = 700; - "force user" = "${xlib.device.username}"; - "force group" = "users"; + settings = { + global = { + "invalid users" = [ ]; + "passwd program" = "/run/wrappers/bin/passwd %u"; + security = "user"; + }; + nixos = { + "path" = "/etc/nixos"; + "browseable" = "yes"; + "read only" = "no"; + "valid users" = "${xlib.device.username}"; + "guest ok" = "no"; + "writable" = "yes"; + "create mask" = 755; + "directory mask" = 755; + "force user" = "${xlib.device.username}"; + "force group" = "users"; + }; + root = { + "path" = "/"; + "browseable" = "yes"; + "read only" = "no"; + "valid users" = "${xlib.device.username}"; + "guest ok" = "no"; + "writable" = "yes"; + #"create mask" = 0644; + #"directory mask" = 0644; + "force user" = "root"; + "force group" = "root"; + }; + "${xlib.device.username}" = { + "path" = "${xlib.dirs.server-home}"; + "browseable" = "yes"; + "read only" = "no"; + "valid users" = "${xlib.device.username}"; + "guest ok" = "no"; + "writable" = "yes"; + "create mask" = 700; + "directory mask" = 700; + "force user" = "${xlib.device.username}"; + "force group" = "users"; + }; }; }; }; diff --git a/modules/server/secrets/coturn.yaml b/modules/server/secrets/coturn.yaml new file mode 100644 index 0000000..8f9e378 --- /dev/null +++ b/modules/server/secrets/coturn.yaml @@ -0,0 +1,17 @@ +turn-secret: ENC[AES256_GCM,data:M8dIzxKmv/x07/KNFTB+0JusGNA61J9r8VaR1Yy/j8Lo5x+NI2S1+rytvUutGxnTnYVqXynozs3ABfIDu/yzyA==,iv:X70EiZNkjbSL2R0S79D2Ey6tMiU35Gr4ROcxbX6df70=,tag:dJjSBSyK2RtIdXP5npWOQA==,type:str] +turn-api-key: ENC[AES256_GCM,data:xFV8ZCDSPrtybCSIas4JEamsYX6fqd0IZIdNqv7cfk0R5+rKsvJYzAFc2RcREOafiGrA6nR85NvldhoAB06HIQ==,iv:DeqlY9jBByn42ygx2TiRQscPYqKwxvGZyhLEo1nmAgw=,tag:RCW0LJqFANWycASBsBuKYA==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOdVI1aUJDZ2gxWUhpSllL + dVRZS0cvYjVBeWlhNytpK09nMVBFQU1aOUVrCnpOdit6bGxxYmhJNTYwMkdKOWdI + QTQzZUhDc3ZCeTlFVWZER2U5dUxDNG8KLS0tIDRYUW02ZjV4OFNyTkhRa0ZDMU1Q + NzNnQXloNE9LODA3SXpUTzExU0RuUFUKOSmHSr4oKj+MdSLv1bXzGWdj+xBS4cXq + 93hxORbXILr96DUfQucNHkAHT4BcW0TIE1F5EyOL1HVEnI3/WEuR4w== + -----END AGE ENCRYPTED FILE----- + recipient: age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm + lastmodified: "2026-06-30T08:02:46Z" + mac: ENC[AES256_GCM,data:NG0b9LrWQ1E6rQOxDvhAqu190a3EDmGwQV49ezuCVZmjr4okajomjCe3Q37KdG+d576RXldtciPq2ZNhEPzuC51kEvNk1x1oMn64lNDrYWXwev4tI+NcdpLm8W2hPeU6jsnY4NZAQf9YUvjJIwXyO2fhuR8AovRsUPj9A8fEjJU=,iv:H7C/GBsh8Zal3p+FXY7BjBCTVTEkC9ma4molPODsZDU=,tag:+V+mI88apssiXr3cJPQeiw==,type:str] + unencrypted_suffix: _unencrypted + version: 3.13.1 diff --git a/modules/server/secrets/nextcloud.yaml b/modules/server/secrets/nextcloud.yaml index 6f27ba7..c47f049 100644 --- a/modules/server/secrets/nextcloud.yaml +++ b/modules/server/secrets/nextcloud.yaml @@ -1,9 +1,12 @@ adminpass: ENC[AES256_GCM,data:Fm+Q6YWXxouP5cX2WHU05Jr49FU=,iv:Exf/li6bL6xpR9HQ8XDDSprjx4ltHkJFl99Ga+gXwmQ=,tag:iB9d5O4982tr7lPu1nWccQ==,type:str] whiteboard-jwt: ENC[AES256_GCM,data:5i+x8VODrBIhGEWS5Ua6lrk7tsfk6xTa/1qm1rXe4A==,iv:2gFEeudip7BxJh553QtZ1CZo9T8jro3Q/Afdo8ouHtw=,tag:HgBM9ta41rhXJlsQJ+asFg==,type:str] +nextcloud-talk-secret: ENC[AES256_GCM,data:rdPoTwP00N3VdYKVMG1JgBL4GdXbJAGYIyBHGrVoH1kP0+vU9ImHFfhPNOGTJasTcsVH9Ub+ewLw8cnhBpjFGw==,iv:dOY3kuYZt+Uw1RqNLMV1AJirQXl6UZrD4TCSibnM+nI=,tag:gzkJCN7ipqKV3UdrSF6aGQ==,type:str] +internal-secret: ENC[AES256_GCM,data:5dUblSAYYKaBXJj4nzHHggQp3+76Ubc0SE6VGbT6wzO+Zavdy/vo8JtVPkq3WZddyqJX9sgc2mn4fIXRRU+Zkg==,iv:A240Os4SEN+O9GT0HwX6WrGJx9TAYnJDSyW609vmES0=,tag:8p05AcrovwTaxxt+vFri9A==,type:str] +hashkey: ENC[AES256_GCM,data:49w+JLFgN1pcV8QqcW+URURIypnZMi5RC6E7U60HgrY=,iv:u0r2QgVehL/Y0xSiDTvBc2yOw1fWL/PQgT+n6ZSGf4M=,tag:NF9h6FWwjX2RUxy5YN6ODA==,type:str] +blockkey: ENC[AES256_GCM,data:t/w0aENV7X0/tiAoJWi74BKFsaGZblfCnsYPg271aBQ=,iv:hWiFMDEtq6g/11dAvtUun3wgZw2J4jbIMOz3ly4o34Q=,tag:z2DYXT+rylpgOp/0CY7qDQ==,type:str] sops: age: - - recipient: age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm - enc: | + - enc: | -----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxNWFiUlZXMEEvNll0aFFk UldxNitqaDgyenBFeWRhLzUxSVVhQk55Q1FBCkdLU3p4S0NTOVhERkRoaWVwbWVB @@ -11,7 +14,8 @@ sops: WGVQYjZtaHhaeC9pMzYxYmxTcVNtYk0KKxXXNA9h0fs+mA6U/Vsyg+q1CPl5hFrI Ozjqh+dzwajQeqkCPUdCsoeIWsvBY2Cyabvs+f0zj8S00faXb8rVQQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-30T12:49:45Z" - mac: ENC[AES256_GCM,data:1EkbMGa6nK53GqGWYvXZP+sqy91AldGKy/32CVPshZwvTzJtk/VeK3W9A3fIGwvo7gl+QVWJmSiqrOTql4v+U4Yi3jVLEXsHXA5Bh28aJ7Ng9nkZmI10K7oaYF1xWNxzwss4gcDNIuomK+wG1WNLaiLbxwCBkN6xHugWQ4F+DLs=,iv:UmI6nC7dIHGeas54taf5kTIINvyd8YXyOVdIYghwHmE=,tag:VxdJLXRYin8D07r6CCA00A==,type:str] + recipient: age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm + lastmodified: "2026-06-30T07:33:27Z" + mac: ENC[AES256_GCM,data:fZlKozBczGDWfhXKyJXmW/I/7GdKKoPG/NVNt2ncoK2a+pjHglJ0Ur9Zg02v05Fb37MmFznmHH2nn4W4av1TX118dX4jkni2aue06NEF3L8iali+sHFPUSI+uT8SvG0DW7ZvllPNwyPNgzeZPLIKqRRGZ7CgOqKe6IWOha4jAhg=,iv:7gfdmYmktzRXq7ANwXOdOKVgZEe0kfFIPKEvEnhfKrc=,tag:3tkVXh+89Q/uW8TCHZtWWQ==,type:str] unencrypted_suffix: _unencrypted - version: 3.12.2 + version: 3.13.1 diff --git a/modules/server/step-ca.nix b/modules/server/step-ca.nix index 3d5db3f..914d0b1 100644 --- a/modules/server/step-ca.nix +++ b/modules/server/step-ca.nix @@ -39,6 +39,16 @@ in { type = "ACME"; name = "acme"; + claims = { + enableSSHCA = false; + allowSANs = [ + "*.home.arpa" + "*.zeroq.su" + "home.arpa" + "localhost" + ]; + maxTLSCertDuration = "2160h"; + }; } { type = "JWK";