diff --git a/hosts/desktop/default.nix b/hosts/desktop/default.nix index 0d839f2..a06baa7 100644 --- a/hosts/desktop/default.nix +++ b/hosts/desktop/default.nix @@ -26,7 +26,6 @@ services = { gc.enable = true; sound.enable = true; - tailscale.enable = true; nebula.node = { enable = true; address = "10.254.250.1"; diff --git a/hosts/desktop/secrets.json b/hosts/desktop/secrets.json index 31957b1..e2fc9db 100644 --- a/hosts/desktop/secrets.json +++ b/hosts/desktop/secrets.json @@ -1,8 +1,5 @@ { "seb-password": "ENC[AES256_GCM,data:dFdYolLTXrxAT8ybVAq3+8eKxO5x2qB810o9FSpUAtfjgYr9DFFVvi06Ut+14ukGcfulXLOixyf0pM/3n9/jeNghnsD14hoGxw==,iv:vORmRgBgZvdafRa8vFF4LL3fw44yZV3yNq3L8eOcQRI=,tag:kr7ZUJpJUhzPJwCCezWCRA==,type:str]", - "tailscale": { - "auth-key": "ENC[AES256_GCM,data:nbc5TURKW/d81lJ5LjJmEykGe6Cz7hnl42BgJdma4S0O92t9EtHCapjujlSSivqO9vjUWUtkJ9JMn5SQOw==,iv:SeVyuQpObjTG/FvBaUn5yv6ktVIXCXWoHv1eLlymnrI=,tag:gKOSviNCzCoRx6zsJ/MzqA==,type:str]" - }, "syncthing": { "cert": "ENC[AES256_GCM,data:Rf6Pgni4jkcFC0pYC+CBJnCRfsNqSBR2yStaFngefb2/rQd3za2h7o7fp2IPVLs9fYmUG5r8/mP9K0m46xA/2wVLp+ddyNA2wndSwk7ZqNEs2BA/GAdelX8gtcPV74CkB/NJa4E42qH7aTVcgrBZVIM27RxO6e/8r8JSXb/HOczYpLAVdW2DHXjGrzi43cjEcn8UK+dNeNsp0AlEZqN9eRRbqh3JQr7+WOYKkk0R0VP3SLH4O9ROLzSJ4Pw4BoLArR3lvp7pOLOrmXvazToKkMInnLZsH0oV7Zvpu1kTz2KrvhIZdNoUZOV2L/laoS7nc/MFixEwpMy4gqszhiADXlNEbslZyZPcq9KxLgIH0W3xKuQDwrC/RWfjMAwnpucByKy9dR4+9C7maVYp5rvBdRbhNM/Yp6U465d8qJVG5YmURG5NBudAsXkfkp8/AqGSK8RQk/F2b28SfqVCfd/Kga1SINcbdEY7P9nNxx3sbVhncQ3pZXY2tZhYJiSuZ/hGMuPa3yMJPgDPJV8tPIUASCNxbeLOKp7HVghb9IIHSDhhiZmFTFB9xT8X9w05w0afLgQQCybG81YGXvXTiA/xLriA2AzQqg4KzdjUgs+lv7rPL9fsP5V7LAoBZamTirsOCoApMrP7L+QP0OTFyHBakf+GBEREwn5dygos+/vBXne4RtDmji/+zh9U1CqwwCIbx/rdVODzYusYV0lvDjYPyVnTWjEGQN5uGCgEBozQWUkaR1KlmamzcXS9ihPsIa1VNu/aLRrb66hS99wuALFdHJPg5XgHNKEA+Re/lXqUwups/A1RQ9bymqXUj8lIK1hDWsC3DCqDsL54x2BIodyvBBB8hyHFnBC3xg+W8yC0SQLivkFLdNMTRdAgyREFEZp3Nvi19B9+njnciFjcbRj+sG1L9X2OSvDZ2e7273DYtXAVsI9977VBtQYHmjXeyDVBnK53sri/8P2ofniPmBM/ZQ9X1UtMI+vrKIj/o4jcTaEcAmqA9bI2YbG5p84rIH6mBA4SvPCHGz6s48XhaYLzCJbOIR+eqwjbvBA=,iv:72+0+hlBxKtuhjhrLD1EMlx8LcJtskxO+MCpYj7rpes=,tag:qnQlahuimpMoVY1hbTGI6g==,type:str]", "key": "ENC[AES256_GCM,data:A/Am53gADkKNOn1kAgNoJmirRhIDtysyX8+ubtpyKTQKhTzEJfEKFrVw5BjJ8rYRS31DgMYV20FQs7HOfoRsR3MFdSGDFUgePnbIcNGpHD6EY8GJ9TblT+NyPsYsKG4WgFZElOjQYT3X9Rr0IWoNnDJoOaaI5sCpOumfLKWrekWvYfTUT+SiFfkCebeEQs7ZF7G6ZQJF73upaeKdbd8/uBdcfVc/c6PdjGvY1xnCOAqW39S9K2fK0RibqHs8BiuzPBTCYjBg6euYXi+XGrZjmHLFnj/ZflroiPJr/qFhMDVnmiaW7M3sWYDQYYPd6rk6Adam+ylEAU8BXwIjmdHNkR48WbdIDYWCHHdv4iZ8MLTj6MaX/ksIZvev2M19Eiyi,iv:lkGS4uR0Xd7FnahXLjVc8g0PiRPxyUS6YQY3EM3B5G0=,tag:NZYybe/MgP+LNlJ09AiV6g==,type:str]" @@ -21,8 +18,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2Qmh4TnU2U0toYXZlaUpU\nZWdBVFMwRVpxelBTb3FvMHVDQkFMMkVlOEVjCjNaTEJDaGlkcUJtem43aDZ6Yk9j\nZGhmWFFvbm1HN0N1VkUyN1lQLzM2c0UKLS0tIHhEeFNyaXI0UDB0ZDBydW80djRX\nSmpyNDlLSFMvaXRsZGdWcS9nVTRzbk0KNryo5P1+bu9vntBafSgAAHxSsYXG2ELj\nQQM6kP+eaSoEFXfWxp7dhxHcjoTjQ9DmCgzVaDUD8nLzFsiJsgbjIg==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2025-12-21T01:21:48Z", - "mac": "ENC[AES256_GCM,data:tn8lgEn8Sp2YYFUVRUa+yOND7oISGld22+otWBB9U1she28JZ+g+vvdpCPRPevkqWHA+BawKUKkaD8Iaoe732HQukpbIBrVgK+g6YpaSnakhSZPGV2oE3z7KdSDeYdBF/La0ml1OKs67hldFfN9D2Sl5RdTROwBWaVaJesNTFS4=,iv:BCbSXBAUqb/LoDfLXLi6UB+CRuJOKEXuHFjITAdaH+E=,tag:f570BuZv30rL45m4y1IwJg==,type:str]", + "lastmodified": "2026-01-10T23:13:24Z", + "mac": "ENC[AES256_GCM,data:5JwqpNoFY0lW59TKMu9v//HQPfsrf37CRZAPZpJarHAAcxvAQhm25i8wwlrjZesEWmiqv3lzEi/82XX86h0kqSaB/7dbX+LVISNLeHJhYvOK4/MW87AjBAI9X9FjEhF1UMlE6ku6m7iJr3Jw11ePK6nxy3X+CPodd0q6DvuQKB0=,iv:UT32qwh51s0qaqDk47ytuCj9m2EehzkQpgeCKdTxtc0=,tag:6uxCkvCJGc8kPvGyX4TkFQ==,type:str]", "unencrypted_suffix": "_unencrypted", "version": "3.11.0" } diff --git a/hosts/laptop/default.nix b/hosts/laptop/default.nix index 7321a50..0f13386 100644 --- a/hosts/laptop/default.nix +++ b/hosts/laptop/default.nix @@ -29,7 +29,6 @@ wlan.enable = true; bluetooth.enable = true; sound.enable = true; - tailscale.enable = true; nebula.node = { enable = true; address = "10.254.250.3"; diff --git a/hosts/laptop/secrets.json b/hosts/laptop/secrets.json index 359a568..b9ca1d1 100644 --- a/hosts/laptop/secrets.json +++ b/hosts/laptop/secrets.json @@ -1,8 +1,5 @@ { "seb-password": "ENC[AES256_GCM,data:RoDF5G7xX1SEabK9/mzbM1nu7KWN9tZJh5GZuiwAOBcQPXLcFkPh+U/I/PlwpSqDT7aWULW+FFG5DzQkdWIKLojWatZrkIrYvw==,iv:oWQj47oxjxR3DBHhFwUD/Emj5ziZHwcbXzD69ChRmHU=,tag:EiPidd+ISk7e2ZMxgeLHNQ==,type:str]", - "tailscale": { - "auth-key": "ENC[AES256_GCM,data:bQtlPQiNwM1xP+6a1jRGeJFdsxxL87RK0jazIj0uoe/U7wwUSZsxpFHyi9AJzfZSLYiST3LkUBtd5EPVnpw=,iv:qzcRpnOqEQF7iWWA8FSXHSlbNIcNk88xgMOk55nY33c=,tag:ZLXi7FZAlrH+z7Q9EvAxdg==,type:str]" - }, "iwd": { "EW90N.psk": "ENC[AES256_GCM,data:n2sY4SrmLG+nfIRQC2KXXHlS/1pRyWYsObg5K8MhX83jJp8MYZfa4BEwBm77ae62,iv:RIh/45UhkyEtjh5Q0FOS63p1RRgLlrRF+QTiFozm4eU=,tag:rVnKVlp8qu3eUSdyZW0hmA==,type:str]", "Fairphone4.psk": "ENC[AES256_GCM,data:GGxrhfXB0vb+R87G4GgsAxqjh89g0gVJu3gTPXsBDDlUUz5xv9iS5UlHPaJD,iv:p80LlUGQkBdeEK63dBDWgWe0n6GtEC2rcn8fToOvD5I=,tag:XSh+FAxBzKs/LQyYM2mUUQ==,type:str]", @@ -28,8 +25,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPM1k5U2pCM0JkKytwSE16\nek1zdVVuQjdKS1MyZ29xSUZkK1FId2JVZ0dFCng5bjV3SGlGRHdvaHkvWnNQcWpk\ndGlMbWl6STdERmtHeXVMYTJ6NjQzSU0KLS0tIFBza3d4eVlsVHB3YS9ySUNFMjUx\neUkwQlExdGNwWU1hbHlzS0RkS3NLbFkKLiP/N/5jOnsQhRCOkZ/BieX3OLJOq82e\ngp57skqFeG0k22sPpbgOS0Uz7jckv7/C3kFpuwXQGpEHdzp3QZ+Owg==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2025-12-23T23:35:27Z", - "mac": "ENC[AES256_GCM,data:+4U7yeb/0mDHuVz/DcGzg3whECVm3HJChE/T1NNJKCkbc1lkdIfLvI7p68IBe5QtkTsGtm2pGqJn8ztbOCAJJ1feoZyHMdcDqGbJG+IpDSrPRdmwqvey5CGtrGgIdgW0vZUMCCywmbASzEmsVoFvOzBp5GAxeJsJZRuPU8ditRc=,iv:dkqg3210wXfVAjXPmXYkerLJX14muxeKPMKU65PrKMc=,tag:TPbzWHamgoVBbAyshiRahg==,type:str]", + "lastmodified": "2026-01-10T23:13:41Z", + "mac": "ENC[AES256_GCM,data:HOucc0/UhQ46sbupGkOoID7vuiA99ObG9ZKZ2AD7dcb7wMN35d/Y//xCJFo3XPRw4nGT/tb87RIh6rOwmN37rYgP0eU/43Eyj66/bCAGfFyY/U3kATwII+GhfLCbHR7Fm4jcYS9UmfhCTydqLlunxsqhqqoZHGLpPm9B4KsVdoU=,iv:ns/HFeeF9TsmcINEOMUSW92lDLe3QCp+lwFYEJRZIdE=,tag:DQA790sM42Jbm0uXs9GQ3w==,type:str]", "unencrypted_suffix": "_unencrypted", "version": "3.11.0" } diff --git a/hosts/vps-monitor/default.nix b/hosts/vps-monitor/default.nix index 0d751cd..554782f 100644 --- a/hosts/vps-monitor/default.nix +++ b/hosts/vps-monitor/default.nix @@ -26,8 +26,6 @@ onlyCleanRoots = true; }; - tailscale.enable = true; - nebula.node = { enable = true; address = "10.254.250.5"; @@ -40,12 +38,12 @@ web-services = let - tailscaleDomain = config.custom.services.tailscale.domain; + privateDomain = config.custom.services.nebula.network.domain; in { gatus = { enable = true; - domain = "status.${tailscaleDomain}"; + domain = "status.${privateDomain}"; generateDefaultEndpoints = true; endpoints."alerts" = { path = "/v1/health"; @@ -55,12 +53,12 @@ ntfy = { enable = true; - domain = "alerts.${tailscaleDomain}"; + domain = "alerts.${privateDomain}"; }; grafana = { enable = true; - domain = "grafana.${tailscaleDomain}"; + domain = "grafana.${privateDomain}"; datasources = { prometheus.enable = true; victoriametrics.enable = true; @@ -76,17 +74,17 @@ victoriametrics = { enable = true; - domain = "metrics.${tailscaleDomain}"; + domain = "metrics.${privateDomain}"; }; victorialogs = { enable = true; - domain = "logs.${tailscaleDomain}"; + domain = "logs.${privateDomain}"; }; alloy = { enable = true; - domain = "alloy-${config.networking.hostName}.${tailscaleDomain}"; + domain = "alloy.${config.networking.hostName}.${privateDomain}"; }; }; }; diff --git a/hosts/vps-monitor/secrets.json b/hosts/vps-monitor/secrets.json index 1d0ce79..fa99e10 100644 --- a/hosts/vps-monitor/secrets.json +++ b/hosts/vps-monitor/secrets.json @@ -1,9 +1,5 @@ { "seb-password": "ENC[AES256_GCM,data:BsVFQMY7q+RhByY3RTWwrwbdC4Pgb2kNVG8HXn+kmI2evAo8XmGbDHbr7mXnI2LA6E+iXm5bewfwwTnJWZjaup06/kr1bd8JDg==,iv:GpBQNm1jspU8PCN+SzfAUKSps3YySg6JJVYOLOFetOI=,tag:ydQaXcLVYllSZYWNCtH7+A==,type:str]", - "tailscale": { - "auth-key": "ENC[AES256_GCM,data:b+m+4KGLeS7hYLSqYXxX5VhiA946b4SEp+OAQUkK6e6ShYe0RnC0VfnypHjqwrdOiGYAIxB4ggIjZ9F5lfw=,iv:o36k4vtsnSThDQNIMIPBQHJ92WodbIyVC42L1t8Fvzg=,tag:/9oYSFO3asAGmWiedNo+Bw==,type:str]", - "service-auth-key": "ENC[AES256_GCM,data:Z/u3GJr1J7rhn1k+Ul0SyHhWKIxpIKqqinGphdZ/BNFvBGCsU8xKKHz7c4B6O94Oe3tuUNGp+X285lSnpZg=,iv:ch6Mg8ki82pxlWFGlOGoJB7Mhn3tYPEcL6Z8/6bXzCQ=,tag:9sHLrQ8F/DzYvdtvUM7dYg==,type:str]" - }, "healthchecks": { "ping-key": "ENC[AES256_GCM,data:Zq71AU3oym7fC364YZNyRtx4N2G35Q==,iv:ibMBpcrSocLBhtumsSV00+KVN6Pi4SzE7soCkZcU4fY=,tag:Wv/Wr0wRZGXucMHZHgoNtg==,type:str]" }, @@ -13,6 +9,10 @@ "nebula": { "host-key": "ENC[AES256_GCM,data:usSLqYOvDAAs7z1xo+gccDqgUE78upK+k522ldKcPoFKKBH87Us7gi6+XAOMDQ79U6i8j4l1lAE8kRdqDuvasodESHVSW9gSnnv5E73MVr0d1Snh7tAewVzneac+2R2R8tUzKzwzWM5SyyvJSoKGBg8WmGzdGT8UqC623utlYQ==,iv:NoZ2u8IK4g1Kwb6uZZ1jXJH4eFO9Jj5Phi5hPM4K72o=,tag:9mOv6oSESH+8r2ZC4yUE+w==,type:str]" }, + "porkbun": { + "api-key": "ENC[AES256_GCM,data:oqnAPVfLU8CG64+TsRijZ/2Wzy11bt3PvoEqbpWZbcXIE2aM0oZtUUtCxt0DiWp8Uyta6AO40V8+EGkzeqL4O6VLxU4=,iv:KaEwSmoG5zYxsWjUxwqbfe77Iiv03IAnFaIjQ5YoYkc=,tag:ilzXSYElARjnWkOcBKZBdA==,type:str]", + "secret-api-key": "ENC[AES256_GCM,data:dGOAsu3kPJmDwhddZGgrY8KrDJeS7PiEPjEVh/h8BgSygRKLInow/7PIaHcy8gIlsGFvU2CYORY7Vmf3QCxYbRTkdIQ=,iv:otDnIv0B1h1H6usJqSNVqv9UUcmx9r5Cn18Q6DFwBME=,tag:O2O3V33TmalVuL6y4V9ufw==,type:str]" + }, "sops": { "age": [ { @@ -24,8 +24,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTVmV4dkZEaWVDNHMxUFdr\nYnhuVWpReXBNSEhhZkltQTE4bEpzSlBzL0VJCk15UFlwa0haWTZNaE1DVzVZVFBI\nd0QzcUptYmQ3dmhhdjhFV0xDSWdmMGMKLS0tIFhWamx6SXJleFFSVUFkRmw2VFZy\nOVVhNm9NSE0yRGFMQjNrM1B6cDVxSXMKrhAkDcWqutgSmQI5O+5i8fcwuTh2/XKr\nljK/Vn8EvGr8qEUeHzOBI1b5VtgngJkVJyfM9G/Q0lZvQF7ZZ5YCgQ==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-01-03T15:47:25Z", - "mac": "ENC[AES256_GCM,data:fEtJdI0I7Tiv21n30ZcxMdOsf4emevkouRmMW+100GEY19rL/VtAIXkvaaygdz/sGXXzLeANReLjo5Ryp93x8854eravT4nQ8IXpNlCgdBXmq7QgUD/nc5kaOj0//3neAxE+ht5MPWm+AbfO4kYDKTmF9GFoLRZMfyvrWXTVv4M=,iv:h4RUkWkr6PABpj0yp+YRhgJ/0X6kwpMyB30qVMbO2to=,tag:8a+w96TwPXk15GZdryWneQ==,type:str]", + "lastmodified": "2026-01-10T23:14:34Z", + "mac": "ENC[AES256_GCM,data:RpG1S1iuaHmBc9wT9Tau6dZHcFX9DwQA0kHcAuTZxbjopLfYJnVosvU9S9N+4tAZqwGLpKqVxX3UiUWLEIFwrcB3xM3/SdpKWD4CE/cyMbvwWCIN4RcHveFJ6py7ItXtipzLC0lZeRWDXP+IyREuKggAID50zXuSIPr6BDlnkYA=,iv:gWykL+vhNB3tLHtHlhbNd5iUPKjB5vDpx0nAf5j+F8Y=,tag:MAI8aaSR+g33IIYM4opqCw==,type:str]", "unencrypted_suffix": "_unencrypted", "version": "3.11.0" } diff --git a/hosts/vps-private/default.nix b/hosts/vps-private/default.nix index c0065f2..0850461 100644 --- a/hosts/vps-private/default.nix +++ b/hosts/vps-private/default.nix @@ -15,7 +15,7 @@ custom = let - tailscaleDomain = config.custom.services.tailscale.domain; + privateDomain = config.custom.services.nebula.network.domain; in { persistence.enable = true; @@ -30,11 +30,6 @@ onlyCleanRoots = true; }; - tailscale = { - enable = true; - exitNode.enable = true; - }; - nebula.node = { enable = true; address = "10.254.250.2"; @@ -49,44 +44,44 @@ isServer = true; doBackups = true; deviceId = "5R2MH7T-Q2ZZS2P-ZMSQ2UJ-B6VBHES-XYLNMZ6-7FYC27L-4P7MGJ2-FY4ITQD"; - gui.domain = "syncthing.${tailscaleDomain}"; + gui.domain = "syncthing.${privateDomain}"; }; }; web-services = { filebrowser = { enable = true; - domain = "files.${tailscaleDomain}"; + domain = "files.${privateDomain}"; doBackups = true; }; radicale = { enable = true; - domain = "calendar.${tailscaleDomain}"; + domain = "calendar.${privateDomain}"; doBackups = true; }; memos = { enable = true; - domain = "memos.${tailscaleDomain}"; + domain = "memos.${privateDomain}"; doBackups = true; }; actualbudget = { enable = true; - domain = "budget.${tailscaleDomain}"; + domain = "budget.${privateDomain}"; doBackups = true; }; freshrss = { enable = true; - domain = "rss.${tailscaleDomain}"; + domain = "rss.${privateDomain}"; doBackups = true; }; alloy = { enable = true; - domain = "alloy-${config.networking.hostName}.${tailscaleDomain}"; + domain = "alloy.${config.networking.hostName}.${privateDomain}"; }; }; }; diff --git a/hosts/vps-private/secrets.json b/hosts/vps-private/secrets.json index 46b3167..3b8f722 100644 --- a/hosts/vps-private/secrets.json +++ b/hosts/vps-private/secrets.json @@ -1,9 +1,5 @@ { "seb-password": "ENC[AES256_GCM,data:Q+yRIOJCUzHmCZ5n0OAGyCkePVh0VJfeFYmgG2fh8Wwy6IKyG9c3/3qcMEIRSvG6Qm9KFGahuIR2md5bz7//pTRfPcu1GdIsMA==,iv:GpBQNm1jspU8PCN+SzfAUKSps3YySg6JJVYOLOFetOI=,tag:pOLRjWZKL2+GkMgV435FMw==,type:str]", - "tailscale": { - "auth-key": "ENC[AES256_GCM,data:qqJnjWR309LAuW49/7t2uZqWlAgPUvz8niLZuM2g8kJxaQmF0TEAWcBDpYridy9NLHnJ+xgA9g088t9dSg==,iv:imh6BrNPf2jVQ6eVaB9Mt+gX9zGq6mHX1+9yhY/KzrI=,tag:HPjhNE+vecDWwCAMC+nGfw==,type:str]", - "service-auth-key": "ENC[AES256_GCM,data:x69Z9Ac533qpKb9y/CQXJYvkw3G6OGyvoih9wABwlYO969+PvQssuNvciFGq8ZmqUXaGRcFsL45edegiKs0=,iv:0yO9RGbrBVfnQ7GR+3rdLBCk+UY9DQJk7NVGlUEBdNs=,tag:ISv0GFT9yinM2BAvvI3mvw==,type:str]" - }, "restic": { "password": "ENC[AES256_GCM,data:AERasH4M/uP3aUELnggUmH6NzAx6v4Uqjg+ymF5X,iv:q5qJkB3+feZyEm778hKI8ikNz9/9dj+Z1hda6M4eHfQ=,tag:adI4AwzXp63SRSA8uAjRZw==,type:str]" }, @@ -24,6 +20,10 @@ "nebula": { "host-key": "ENC[AES256_GCM,data:dS3tXWUK+POzTZ98wLETaWz4ief/yFULCfI5Y3EbK26KQpwxzw6cpLXUNOSZeUwz9brN/4JcwUgewJR08Uq3HZhKZKoMPZfPRtZMDe51I4RYg4hZd1mMWXQn82KmSytZCiDIL/9qCwYvObVRiNCpAOKRj6JBpgpoQ1u5hgn1EA==,iv:G25EpAnvoLfYXAdPyJVqS3ocUPg5LQlUoi7fA+XFOZ8=,tag:/BNhuxJCunM85H9DnPF5Kg==,type:str]" }, + "porkbun": { + "api-key": "ENC[AES256_GCM,data:RV/+aEQRcfQ9LMjZjxGNvCeiso51VqvqrOBRRrR/dXhmBvyoGuh2LaAjyoDoWEjWy5kIStStR+jXZEFWZ8KXvnmEnoU=,iv:j3sYW85Vf88EfeOfezlspDxEms6YqZYnzy5JAiES3+U=,tag:0M9vDvsirc6ze3Ut+yMSoA==,type:str]", + "secret-api-key": "ENC[AES256_GCM,data:SUngZ65fBmC9WlPkmJMjyBb6sHREKhqyRj9fsBGkj5IyjtGDfQ1b7Iv0VNeSY//bWv0VZruwT48a320BUlg1xiNCKU8=,iv:glUaArlHJsxCP5z3y7JnWvmtsdRzszXhYydpd1YaX5U=,tag:185iAkQ/J9CfKkTsgPP6lA==,type:str]" + }, "sops": { "age": [ { @@ -35,8 +35,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqU01heng3NHdrYnZFZmZn\nZlJtUUIyd1ExTmhzeU5iZFZadFcwR25GOEVZCmxHOXNWQVh1ZlJSRHJtaDVHNVUv\nbTY0TlNmZ2hESDkzS2M3WHdlamxwclkKLS0tIEEvOFd3TDFkQmQwbjBodHhpb1BD\nZ2NvTnNqQmtrLy9aVDdGRGxZbVgrZG8KdnnjJWcjZFu3R8fVKToj6THHHRCFou9k\njQoedCZAML2A2FZIhHugH9wnDUPQQjG86WbcCBuFWcOTGiTF2gN+Qg==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2025-12-21T22:05:56Z", - "mac": "ENC[AES256_GCM,data:i6N/BeTtqkiYz5igk7mHxa69Z8MEe2cRF9541P93utNBddrTGev4VQ5VoqEQEkcOpKWvH5DbQcfsa8k60/zaGXJZ9tWbmbBiBTrbjdslpPJTbVkIwMXWYVhbS87WhfAsyQbRzXu73/jArGKVfDPzcdl2FuRmzXZKQkVjRc7x+Rc=,iv:HxjT6ppxY6jkrSPrcP9m84dd2gy2rGCGKV8MdjGy7FA=,tag:KPWQ2nhsGFuhX8ddFhEZow==,type:str]", + "lastmodified": "2026-01-10T23:14:08Z", + "mac": "ENC[AES256_GCM,data:ppj3M84MdH8awN6/r8b0DubMaQbqHpKpMfBJEb3TlbUJczE6kPmhuuX3Cx3FOsD+TJr0m8WRjCqb0Z844Z2oylaz7hmijYHLbByb+BY+dsSPU21zkvCli+KpzHkDY4+NcjhTN4MsopYSwVDegZoCb+qZ0nAqDKqLezUlNIKCUuI=,iv:xA1LzdkoEkiq2i5klIvojMIqvpIsuZeJTiKKOEBbR7k=,tag:o6eOKWKu216X+DnXRy6ARw==,type:str]", "unencrypted_suffix": "_unencrypted", "version": "3.11.0" } diff --git a/hosts/vps-public/default.nix b/hosts/vps-public/default.nix index a59538f..7d897d5 100644 --- a/hosts/vps-public/default.nix +++ b/hosts/vps-public/default.nix @@ -26,8 +26,6 @@ onlyCleanRoots = true; }; - tailscale.enable = true; - nebula.node = { enable = true; address = "10.254.250.4"; @@ -78,7 +76,7 @@ alloy = { enable = true; - domain = "alloy-${config.networking.hostName}.${config.custom.services.tailscale.domain}"; + domain = "alloy.${config.networking.hostName}.${config.custom.services.nebula.network.domain}"; }; }; }; diff --git a/hosts/vps-public/secrets.json b/hosts/vps-public/secrets.json index b5ceba2..c3019ae 100644 --- a/hosts/vps-public/secrets.json +++ b/hosts/vps-public/secrets.json @@ -1,9 +1,5 @@ { "seb-password": "ENC[AES256_GCM,data:znyHz9AhZipp2VNkXifU27IvEbPoKqLf4ibSkqfvkGGoX/jHnoJRYruWmwLnAaqTk6moHtew6HZq3xjvNgUf+qVgaleWQntrLg==,iv:GpBQNm1jspU8PCN+SzfAUKSps3YySg6JJVYOLOFetOI=,tag:CKgqMm/mVae1i9He/ioMAg==,type:str]", - "tailscale": { - "auth-key": "ENC[AES256_GCM,data:tnmR93k4iPsojBZgwVmnSPJkNDOYiJt9lJ/IpoDR/TWCIbpBmbFq7xKSnyoCXBRKiEZ6hK0z3jezuQc9IgQ=,iv:/b3+yxEOuPaRrrmD3LSUeSiNv/1u4bMxrg4B+1SKb0o=,tag:9f6ZSgFjP4HAExWiaStr2g==,type:str]", - "service-auth-key": "ENC[AES256_GCM,data:xlXV01WcdLVm/vRw8Elb3iCId8LstKP0UWSXDXeOG10goKLoIMV4JmJ8a8OalE3s3pO3FSLYQFxjQNxQmhk=,iv:ikHW6XVow1NJZB0hUhKl5JsC9gEZtvXc4F9SlUycQlI=,tag:GgqQPIxOXkYhhqPcv2/k0A==,type:str]" - }, "restic": { "password": "ENC[AES256_GCM,data:IGV07og9eSoleJnZ2+/FFLph7TLNd80q+u6WNn+V,iv:E2hBYbvpCMDul81lgUBNVr5Fm7x0u1f9cEkma9jKwYE=,tag:eA7CAtfQtodTCyOuEn4+ug==,type:str]" }, @@ -23,6 +19,10 @@ "nebula": { "host-key": "ENC[AES256_GCM,data:oi5uWtflxt+LB9ft6DuH+h3owTF8bj9lNKVAVyyZH4Ww5F4tN+GhQDNXHSt4SK4M/9K/M7/VfRjcL0uDJq0SJmI1oy0g/pTF+JcBAV/Z6PAhPWBXxMBkIdL+xYLR5lXmBKnTTkHoIqvBZH7wDHq2kOKrBFU96yFfrMLK1TVv5Q==,iv:eau9vYEVwUjGTgESR2d2QNiBlTZIq5Do97/xZqmrz2c=,tag:aTdQ2vRxI/BByG02VvpPMw==,type:str]" }, + "porkbun": { + "api-key": "ENC[AES256_GCM,data:KT1vUUnm0d2T9H1YI5SE6xgTVVdmbLFJeL/+otlw0mheH+9svnC19YP9szB/kBLAPLes+2qunpqM02B9tJxGgD30SNc=,iv:wVIkhrCQ7t7lkR0q0OO/XWZbgZYuja53XgUjfy1fTNA=,tag:MJ5tjbIofqcKXDuzD0b1aQ==,type:str]", + "secret-api-key": "ENC[AES256_GCM,data:lmU41AkCVb15sFuMqTZ7qZ978D5BLEYYidsb0yPPjiPPUmnfqBNM5lMVo4k4gt/PcMLcRVv5I6DDqE44zOK7YPf6Fck=,iv:sS7PfE2/CjUekIXGlvEA/N6R5JE7BvgfeXJO5dzv6/8=,tag:rp8FY3hEOyoafmwTdROJ7Q==,type:str]" + }, "sops": { "age": [ { @@ -34,8 +34,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvVnphWlNaTUU0QytIdnEv\nQnNzelN4MUMreXZrME5KZStFMDg2V1VFd21rCkk2Uy9ITEF3SjlRVEdMMXlPdHhG\nam1PNnp3emtnMnczeFFSSStJaHF6TkkKLS0tIEJKbFRzbmNqMjk5NXVHZnhlWWZ3\nYng5L1F5YUJGOTg3TTJCK281SG9Id3MKsmH2yj19ig2g+KzBGLD9dWkdvr6TLdSd\nuuDC+frhj7wWrEomOOjIoYtWHXkUtTSAnCEZhrhfyupYhEvlFfWRlw==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-01-03T15:48:23Z", - "mac": "ENC[AES256_GCM,data:p+WJViYWL4HFi7Us7RXJHVDFk8Q0HQ7I+dtV8XrIgBHELp19QTu6BmJ/7G/36Fe1H6h78SmwU3gOdSThDa77CmPlKlGG8aS6edLChJnCWeM0FBl61bvrCgZQwjVq/LZNMwJJIHiktDIPiIgNOwVvTzRCErrH6/UYjH0aGeyRI4g=,iv:6JE/7GAfIrLhRXUMVvFu4roON5zNgmQZY4vJJdgwcS8=,tag:xlDMg/vtqO5VFkbdbSBKxQ==,type:str]", + "lastmodified": "2026-01-10T23:14:22Z", + "mac": "ENC[AES256_GCM,data:oQ8weypJMM2sm5XzRzn80IE6VQ7zKiJdkujLTfZbiUHXhPSpmNJqsXnAMREtKGAxxm6p9aTeZMbkX1xN1FGf38909/W0Bk/I0trpo1Q6bxLwlo/8eLvA5CAqrgQIgJz3jpIEDpXGsvTDVDxNQeFPH4HZHInwmF4Z6snVBuv8UZI=,iv:D3qt1rhAdMRRnBzlaKf8hGU+f7isjIKPyGM1MCnhoBs=,tag:6ihR9KXKsr8SVPceVlB1Cg==,type:str]", "unencrypted_suffix": "_unencrypted", "version": "3.11.0" } diff --git a/lib/default.nix b/lib/default.nix index ef9e36e..49dc71f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -3,7 +3,7 @@ self, }: { - isTailscaleDomain = domain: domain |> lib.hasSuffix ".ts.net"; + isPrivateDomain = domain: domain |> lib.hasSuffix ".splitleaf.de"; subdomainOf = domain: domain |> lib.splitString "." |> lib.head; diff --git a/modules/home/services/tailscale.nix b/modules/home/services/tailscale.nix deleted file mode 100644 index 121c2ca..0000000 --- a/modules/home/services/tailscale.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ config, lib, ... }@moduleArgs: -{ - options.custom.services.tailscale.enable = lib.mkEnableOption "" // { - default = moduleArgs.osConfig.custom.services.tailscale.enable or false; - }; - - config = lib.mkIf config.custom.services.tailscale.enable { - programs.ssh = { - enable = true; - matchBlocks.installer.extraOptions = { - UserKnownHostsFile = "/dev/null"; - StrictHostKeyChecking = "no"; - }; - }; - }; -} diff --git a/modules/system/services/caddy.nix b/modules/system/services/caddy.nix index 3bdcde1..90d242d 100644 --- a/modules/system/services/caddy.nix +++ b/modules/system/services/caddy.nix @@ -1,18 +1,16 @@ { config, - pkgs, lib, lib', ... }: let cfg = config.custom.services.caddy; - inherit (config.services.caddy) user; virtualHosts = cfg.virtualHosts |> lib.attrValues |> lib.filter (value: value.enable); - publicHostsExist = virtualHosts |> lib.any (value: !lib'.isTailscaleDomain value.domain); - tailscaleHostsExist = virtualHosts |> lib.any (value: lib'.isTailscaleDomain value.domain); + publicHostsExist = virtualHosts |> lib.any (value: (!lib'.isPrivateDomain value.domain)); + privateHostsExist = virtualHosts |> lib.any (value: lib'.isPrivateDomain value.domain); webPorts = [ 80 @@ -29,7 +27,15 @@ let lib.nameValuePair domain { logFormat = "output file ${config.services.caddy.logDir}/${domain}.log { mode 640 }"; extraConfig = lib.concatLines [ - (lib.optionalString (lib'.isTailscaleDomain domain) "bind tailscale/${lib'.subdomainOf domain}") + (lib.optionalString (lib'.isPrivateDomain domain) ( + let + certDir = config.security.acme.certs.${domain}.directory; + in + '' + tls ${certDir}/fullchain.pem ${certDir}/key.pem + bind ${config.custom.services.nebula.node.address} + '' + )) (lib.optionalString (port != null) "reverse_proxy localhost:${toString port}") (lib.optionalString (files != null) '' root * ${files} @@ -103,23 +109,49 @@ in networking.firewall.allowedTCPPorts = webPorts; }) - (lib.mkIf tailscaleHostsExist { - sops.secrets."tailscale/service-auth-key" = { - owner = user; - restartUnits = [ "caddy.service" ]; + (lib.mkIf privateHostsExist { + sops.secrets = { + "porkbun/api-key".owner = config.users.users.acme.name; + "porkbun/secret-api-key".owner = config.users.users.acme.name; }; - services.caddy = { - package = pkgs.caddy.withPlugins { - plugins = [ "github.com/tailscale/caddy-tailscale@v0.0.0-20251117033914-662ef34c64b1" ]; - hash = "sha256-3lc2oSLFIco5Pgz1QNH2hT5tDTPZ4wcbc+NKH9wLEfY="; + security.acme = { + acceptTerms = true; + defaults = { + email = "acme@sstork.dev"; + dnsProvider = "porkbun"; + dnsResolver = "1.1.1.1:53"; + group = config.users.users.caddy.name; + credentialFiles = { + PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path; + PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path; + }; + reloadServices = [ "caddy.service" ]; }; - globalConfig = '' - tailscale { - auth_key {file.${config.sops.secrets."tailscale/service-auth-key".path}} - ephemeral true - } - ''; + + certs = + virtualHosts + |> lib.filter (host: lib'.isPrivateDomain host.domain) + |> lib.map (host: lib.nameValuePair host.domain { }) + |> lib.listToAttrs; + }; + + services.nebula.networks.mesh.firewall.inbound = [ + { + port = "80"; + proto = "tcp"; + host = "any"; + } + { + port = "443"; + proto = "tcp"; + host = "any"; + } + ]; + + systemd.services.caddy = { + requires = [ "nebula@mesh.service" ]; + after = [ "nebula@mesh.service" ]; }; }) ] diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix index 20d4017..e6cb193 100644 --- a/modules/system/services/nebula/default.nix +++ b/modules/system/services/nebula/default.nix @@ -135,7 +135,6 @@ in settings = { pki.disconnect_invalid = true; cipher = "aes"; - lighthouse.local_allow_list.interfaces.${config.services.tailscale.interfaceName} = false; }; }; diff --git a/modules/system/services/nebula/dns.nix b/modules/system/services/nebula/dns.nix index 51b04fa..b2c77e6 100644 --- a/modules/system/services/nebula/dns.nix +++ b/modules/system/services/nebula/dns.nix @@ -1,4 +1,10 @@ -{ config, lib, ... }: +{ + config, + self, + lib, + lib', + ... +}: let nebulaCfg = config.custom.services.nebula; cfg = nebulaCfg.node; @@ -25,22 +31,30 @@ in local-zone = "\"${nebulaCfg.network.domain}.\" static"; local-data = - nebulaCfg.nodes - |> lib.map (node: "\"${node.name}.${nebulaCfg.network.domain}. A ${node.address}\""); + let + nodeRecords = + nebulaCfg.nodes + |> lib.map (node: "\"${node.name}.${nebulaCfg.network.domain}. A ${node.address}\""); + serviceRecords = + self.nixosConfigurations + |> lib.attrValues + |> lib.concatMap ( + host: + host.config.meta.domains.local + |> lib.filter (domain: lib'.isPrivateDomain domain) + |> lib.map (domain: "\"${domain}. A ${host.config.custom.services.nebula.node.address}\"") + ); + in + nodeRecords ++ serviceRecords; }; - forward-zone = - (lib.singleton { - name = "."; - forward-addr = [ - "1.1.1.1" - "8.8.8.8" - ]; - }) - ++ lib.optional config.custom.services.tailscale.enable { - name = "${config.custom.services.tailscale.domain}"; - forward-addr = [ "100.100.100.100" ]; - }; + forward-zone = lib.singleton { + name = "."; + forward-addr = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; }; }; diff --git a/modules/system/services/syncthing.nix b/modules/system/services/syncthing.nix index b4e9605..abfd81b 100644 --- a/modules/system/services/syncthing.nix +++ b/modules/system/services/syncthing.nix @@ -59,7 +59,7 @@ in message = "Running syncthing on a server requires `gui.domain` to be set"; } { - assertion = (cfg.gui.domain != null) -> (lib'.isTailscaleDomain cfg.gui.domain); + assertion = (cfg.gui.domain != null) -> (lib'.isPrivateDomain cfg.gui.domain); message = lib'.mkUnprotectedMessage "Syncthing-GUI"; } ]; diff --git a/modules/system/services/tailscale.nix b/modules/system/services/tailscale.nix deleted file mode 100644 index 28fc6e1..0000000 --- a/modules/system/services/tailscale.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.custom.services.tailscale; -in -{ - options.custom.services.tailscale = { - enable = lib.mkEnableOption ""; - domain = lib.mkOption { - type = lib.types.nonEmptyStr; - default = "stork-atlas.ts.net"; - }; - ssh.enable = lib.mkEnableOption ""; - exitNode.enable = lib.mkEnableOption ""; - }; - - config = lib.mkIf cfg.enable { - meta.ports.udp = lib.mkIf config.services.tailscale.openFirewall [ - config.services.tailscale.port - ]; - - sops.secrets."tailscale/auth-key".restartUnits = [ "tailscaled-autoconnect.service" ]; - - services.tailscale = { - enable = true; - authKeyFile = config.sops.secrets."tailscale/auth-key".path; - openFirewall = true; - useRoutingFeatures = if cfg.exitNode.enable then "server" else "client"; - extraUpFlags = [ "--reset=true" ]; - extraSetFlags = [ - "--ssh=${lib.boolToString cfg.ssh.enable}" - "--advertise-exit-node=${lib.boolToString cfg.exitNode.enable}" - ]; - }; - - systemd.services.tailscaled-set.after = [ "tailscaled-autoconnect.service" ]; - - custom.persistence.directories = [ "/var/lib/tailscale" ]; - }; -} diff --git a/modules/system/web-services/alloy.nix b/modules/system/web-services/alloy.nix index 854077a..e0bc827 100644 --- a/modules/system/web-services/alloy.nix +++ b/modules/system/web-services/alloy.nix @@ -15,11 +15,11 @@ in }; metricsEndpoint = lib.mkOption { type = lib.types.nonEmptyStr; - default = "https://metrics.${config.custom.services.tailscale.domain}/prometheus/api/v1/write"; + default = "https://metrics.${config.custom.services.nebula.network.domain}/prometheus/api/v1/write"; }; logsEndpoint = lib.mkOption { type = lib.types.nonEmptyStr; - default = "https://logs.${config.custom.services.tailscale.domain}/insert/loki/api/v1/push"; + default = "https://logs.${config.custom.services.nebula.network.domain}/insert/loki/api/v1/push"; }; collect = { metrics = { diff --git a/modules/system/web-services/filebrowser.nix b/modules/system/web-services/filebrowser.nix index 09423ce..eabd86a 100644 --- a/modules/system/web-services/filebrowser.nix +++ b/modules/system/web-services/filebrowser.nix @@ -27,7 +27,7 @@ in config = lib.mkIf cfg.enable { assertions = lib.singleton { - assertion = lib'.isTailscaleDomain cfg.domain; + assertion = lib'.isPrivateDomain cfg.domain; message = lib'.mkUnprotectedMessage "Filebrowser"; }; diff --git a/modules/system/web-services/freshrss.nix b/modules/system/web-services/freshrss.nix index d47f1be..a9736d4 100644 --- a/modules/system/web-services/freshrss.nix +++ b/modules/system/web-services/freshrss.nix @@ -25,7 +25,7 @@ in config = lib.mkIf cfg.enable { assertions = lib.singleton { - assertion = lib'.isTailscaleDomain cfg.domain; + assertion = lib'.isPrivateDomain cfg.domain; message = lib'.mkUnprotectedMessage "FreshRSS"; }; diff --git a/modules/system/web-services/gatus.nix b/modules/system/web-services/gatus.nix index 6dff1f0..0cda068 100644 --- a/modules/system/web-services/gatus.nix +++ b/modules/system/web-services/gatus.nix @@ -113,7 +113,7 @@ in connectivity.checker.target = "1.1.1.1:53"; # Cloudflare DNS alerting.ntfy = { topic = "uptime"; - url = "https://alerts.${config.custom.services.tailscale.domain}"; + url = "https://alerts.${config.custom.services.nebula.network.domain}"; click = "https://${cfg.domain}"; default-alert = { enable = true; diff --git a/modules/system/web-services/grafana.nix b/modules/system/web-services/grafana.nix index 88134ea..155674c 100644 --- a/modules/system/web-services/grafana.nix +++ b/modules/system/web-services/grafana.nix @@ -23,21 +23,21 @@ in enable = lib.mkEnableOption ""; url = lib.mkOption { type = lib.types.nonEmptyStr; - default = "https://metrics.${config.custom.services.tailscale.domain}"; + default = "https://metrics.${config.custom.services.nebula.network.domain}"; }; }; victoriametrics = { enable = lib.mkEnableOption ""; url = lib.mkOption { type = lib.types.nonEmptyStr; - default = "https://metrics.${config.custom.services.tailscale.domain}"; + default = "https://metrics.${config.custom.services.nebula.network.domain}"; }; }; victorialogs = { enable = lib.mkEnableOption ""; url = lib.mkOption { type = lib.types.nonEmptyStr; - default = "https://logs.${config.custom.services.tailscale.domain}"; + default = "https://logs.${config.custom.services.nebula.network.domain}"; }; }; };