diff --git a/flake.lock b/flake.lock index 1b24a83..2c06c32 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,22 @@ "type": "github" } }, + "actor-typeahead-src": { + "flake": false, + "locked": { + "lastModified": 1762835797, + "narHash": "sha256-heizoWUKDdar6ymfZTnj3ytcEv/L4d4fzSmtr0HlXsQ=", + "ref": "refs/heads/main", + "rev": "677fe7f743050a4e7f09d4a6f87bbf1325a06f6b", + "revCount": 6, + "type": "git", + "url": "https://tangled.org/@jakelazaroff.com/actor-typeahead" + }, + "original": { + "type": "git", + "url": "https://tangled.org/@jakelazaroff.com/actor-typeahead" + } + }, "catppuccin": { "inputs": { "nixpkgs": "nixpkgs_4" @@ -61,6 +77,49 @@ "type": "github" } }, + "fenix": { + "inputs": { + "nixpkgs": [ + "tangled", + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1780397302, + "narHash": "sha256-SQmrkj17xBdvc8lVMbsY7pIJCjKftgNh42R1keP3dLQ=", + "owner": "nix-community", + "repo": "fenix", + "rev": "f6670530f53e69cc284f7aef818eb0f08fe81905", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "fetch-tangled": { + "inputs": { + "nixpkgs": [ + "tangled", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779479671, + "narHash": "sha256-8PR9nZnK0Fn4gDOikz+3sLdsEJYnKC3gaunBs4N+V9Q=", + "ref": "refs/heads/main", + "rev": "2e3744d31b990248f277d16a11ef81753b366f0f", + "revCount": 22, + "type": "git", + "url": "https://tangled.org/isabelroses.com/fetch-tangled" + }, + "original": { + "type": "git", + "url": "https://tangled.org/isabelroses.com/fetch-tangled" + } + }, "flake-compat": { "flake": false, "locked": { @@ -107,6 +166,20 @@ "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" } }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1751685974, + "narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=", + "rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1", + "type": "tarball", + "url": "https://git.lix.systems/api/v1/repos/lix-project/flake-compat/archive/549f2762aebeff29a2e5ece7a7dc0f955281a1d1.tar.gz?rev=549f2762aebeff29a2e5ece7a7dc0f955281a1d1" + }, + "original": { + "type": "tarball", + "url": "https://git.lix.systems/lix-project/flake-compat/archive/main.tar.gz" + } + }, "flake-utils": { "inputs": { "systems": [ @@ -129,6 +202,46 @@ "type": "github" } }, + "flake-utils_2": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gomod2nix": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "tangled", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763982521, + "narHash": "sha256-ur4QIAHwgFc0vXiaxn5No/FuZicxBr2p0gmT54xZkUQ=", + "owner": "nix-community", + "repo": "gomod2nix", + "rev": "02e63a239d6eabd595db56852535992c898eba72", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "gomod2nix", + "type": "github" + } + }, "helix": { "inputs": { "nixpkgs": "nixpkgs_5", @@ -148,6 +261,18 @@ "type": "github" } }, + "hls-src": { + "flake": false, + "locked": { + "narHash": "sha256-mmxgaQRXXWzRG6/OlOn5efV+NmzhvmXTQaFbODqh0b8=", + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/hls.js@1.5.13/dist/hls.min.js" + }, + "original": { + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/hls.js@1.5.13/dist/hls.min.js" + } + }, "home-manager": { "inputs": { "nixpkgs": "nixpkgs_6" @@ -167,6 +292,131 @@ "type": "github" } }, + "htmx-src": { + "flake": false, + "locked": { + "narHash": "sha256-2D8I0L0u6qb57QpeVn88RrT0xatDwQwG/lWOTjuEFPc=", + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/htmx.org@2.0.10/dist/htmx.min.js" + }, + "original": { + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/htmx.org@2.0.10/dist/htmx.min.js" + } + }, + "htmx-ws-src": { + "flake": false, + "locked": { + "narHash": "sha256-woiluaeAoxH/CyDkpk6LYNWCzxH8PHgwgnrlBFGJxgk=", + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/htmx-ext-ws@2.0.4" + }, + "original": { + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/htmx-ext-ws@2.0.4" + } + }, + "ibm-plex-mono-src": { + "flake": false, + "locked": { + "lastModified": 1731402384, + "narHash": "sha256-OwUmrPfEehLDz0fl2ChYLK8FQM2p0G1+EMrGsYEq+6g=", + "type": "tarball", + "url": "https://github.com/IBM/plex/releases/download/@ibm%2Fplex-mono@1.1.0/ibm-plex-mono.zip" + }, + "original": { + "type": "tarball", + "url": "https://github.com/IBM/plex/releases/download/@ibm%2Fplex-mono@1.1.0/ibm-plex-mono.zip" + } + }, + "indigo": { + "flake": false, + "locked": { + "lastModified": 1753693716, + "narHash": "sha256-DMIKnCJRODQXEHUxA+7mLzRALmnZhkkbHlFT2rCQYrE=", + "owner": "oppiliappan", + "repo": "indigo", + "rev": "5f170569da9360f57add450a278d73538092d8ca", + "type": "github" + }, + "original": { + "owner": "oppiliappan", + "repo": "indigo", + "type": "github" + } + }, + "inter-fonts-src": { + "flake": false, + "locked": { + "lastModified": 1731687360, + "narHash": "sha256-5vdKKvHAeZi6igrfpbOdhZlDX2/5+UvzlnCQV6DdqoQ=", + "type": "tarball", + "url": "https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip" + }, + "original": { + "type": "tarball", + "url": "https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip" + } + }, + "lucide-src": { + "flake": false, + "locked": { + "lastModified": 1754044466, + "narHash": "sha256-+exBR2OToB1iv7ZQI2S4B0lXA/QRvC9n6U99UxGpJGs=", + "type": "tarball", + "url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip" + }, + "original": { + "type": "tarball", + "url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip" + } + }, + "mathjax-src": { + "flake": false, + "locked": { + "narHash": "sha256-eqg25bKfiDzynRMR2RfeWNfo0EefHF/eRRFafl9RnNI=", + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/mathjax@4.1.2/tex-svg.js" + }, + "original": { + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/mathjax@4.1.2/tex-svg.js" + } + }, + "mermaid-src": { + "flake": false, + "locked": { + "narHash": "sha256-/YOdECG2V5c3kJ1QfGvhziTT6K/Dx/4mOk2mr3Fs/do=", + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/mermaid@11.12.3/dist/mermaid.min.js" + }, + "original": { + "type": "file", + "url": "https://cdn.jsdelivr.net/npm/mermaid@11.12.3/dist/mermaid.min.js" + } + }, + "microvm": { + "inputs": { + "nixpkgs": [ + "tangled", + "nixpkgs" + ], + "spectrum": "spectrum" + }, + "locked": { + "lastModified": 1779970379, + "narHash": "sha256-ZHsxoYXXnfJtMVh1/yY+1Eh9hHcPBhE28Qvinauh+BQ=", + "owner": "microvm-nix", + "repo": "microvm.nix", + "rev": "0d49083ba2d7419b22908ac392777c16df9a032e", + "type": "github" + }, + "original": { + "owner": "microvm-nix", + "repo": "microvm.nix", + "type": "github" + } + }, "moppkgs": { "inputs": { "nixpkgs": "nixpkgs" @@ -256,11 +506,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1786072111, - "narHash": "sha256-m6NWUbZC08A/bHjR0sy7Ee1/xjnqGxQzLcHHLzVMPYY=", + "lastModified": 1786328466, + "narHash": "sha256-LrBZgQA3j50IGWGTH1GXvkv/kNuZA3k0vlBMvvzJvj4=", "owner": "Infinidoge", "repo": "nix-minecraft", - "rev": "02f9da181da65a0f2f869b8a1ea8cd263fbd1d31", + "rev": "71e57519f7acdeadc062fa101dd704841a8072b4", "type": "github" }, "original": { @@ -349,11 +599,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1785989512, - "narHash": "sha256-HFQhkQcl5D1hUNoen3SGHCSFCt2Bg6uP+HgbrnA3InQ=", + "lastModified": 1786313170, + "narHash": "sha256-9BG7OgUWdu0ONDO5X2q6+K4bsuBITkX/3W4nNJu1Ito=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "445d861c6d31b4af0c79d8d4be2331f762a361d7", + "rev": "fcb8fcd6bf2d0adecae5bd491afaaaf8311b758d", "type": "github" }, "original": { @@ -538,9 +788,27 @@ "nixpkgs": "nixpkgs_2", "sidonia": "sidonia", "steamcmd-flake": "steamcmd-flake", + "tangled": "tangled", "unstable": "unstable" } }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1780337665, + "narHash": "sha256-RS3F+/6dtBIwd5+47GVen3jAk62/KumFZ4q3RVYafDk=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "55af1774e9e840d3b28d12fcfaa72d2e2caa8ac9", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, "rust-overlay": { "inputs": { "nixpkgs": [ @@ -692,6 +960,35 @@ "type": "github" } }, + "spectrum": { + "flake": false, + "locked": { + "lastModified": 1778940603, + "narHash": "sha256-voSM8dZNlaOWN3kbYFky+FNY6fFQOEw0xF+ZMpZKkCQ=", + "ref": "refs/heads/main", + "rev": "367dd227f539267eae2b62770b4c17b88ac8c1f1", + "revCount": 1265, + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + }, + "original": { + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + } + }, + "sqlite-lib-src": { + "flake": false, + "locked": { + "lastModified": 1706631843, + "narHash": "sha256-bJoMjirsBjm2Qk9KPiy3yV3+8b/POlYe76/FQbciHro=", + "type": "tarball", + "url": "https://sqlite.org/2024/sqlite-amalgamation-3450100.zip" + }, + "original": { + "type": "tarball", + "url": "https://sqlite.org/2024/sqlite-amalgamation-3450100.zip" + } + }, "steamcmd-flake": { "inputs": { "nixpkgs": [ @@ -774,6 +1071,71 @@ "type": "github" } }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tailwindcss-animated-src": { + "flake": false, + "locked": { + "lastModified": 499162500, + "narHash": "sha256-l3esIcsAwj0PHOhnHBLWiLzzRiOo1yOk9VYEGpn6fyQ=", + "type": "tarball", + "url": "https://registry.npmjs.org/tailwindcss-animated/-/tailwindcss-animated-1.1.2.tgz" + }, + "original": { + "type": "tarball", + "url": "https://registry.npmjs.org/tailwindcss-animated/-/tailwindcss-animated-1.1.2.tgz" + } + }, + "tangled": { + "inputs": { + "actor-typeahead-src": "actor-typeahead-src", + "fenix": "fenix", + "fetch-tangled": "fetch-tangled", + "flake-compat": "flake-compat_4", + "gomod2nix": "gomod2nix", + "hls-src": "hls-src", + "htmx-src": "htmx-src", + "htmx-ws-src": "htmx-ws-src", + "ibm-plex-mono-src": "ibm-plex-mono-src", + "indigo": "indigo", + "inter-fonts-src": "inter-fonts-src", + "lucide-src": "lucide-src", + "mathjax-src": "mathjax-src", + "mermaid-src": "mermaid-src", + "microvm": "microvm", + "nixpkgs": [ + "nixpkgs" + ], + "sqlite-lib-src": "sqlite-lib-src", + "tailwindcss-animated-src": "tailwindcss-animated-src" + }, + "locked": { + "lastModified": 1786351941, + "narHash": "sha256-w5MICNYX5eRbU1R+gYts2jDHMoFHGu7cATaCoGirzgw=", + "ref": "refs/heads/master", + "rev": "1b2a86c0465a2db029fb3d1bcfccf78f2e1bf3a6", + "revCount": 3098, + "type": "git", + "url": "https://tangled.org/@tangled.org/core" + }, + "original": { + "type": "git", + "url": "https://tangled.org/@tangled.org/core" + } + }, "treefmt-nix": { "inputs": { "nixpkgs": [ @@ -798,11 +1160,11 @@ }, "unstable": { "locked": { - "lastModified": 1785967620, - "narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=", + "lastModified": 1786106723, + "narHash": "sha256-zDSUbpoeo/9ZmD2+wXnzxoo1+uhL8vxc0b8yuYMKYq0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436", + "rev": "f13ff45afd1bb73e640eaa08a7066dbed07e3238", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index ac08ff2..def82a1 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,11 @@ url = "github:flashgnash/steamcmd-flake"; inputs.nixpkgs.follows = "nixpkgs"; }; + + tangled = { + url = "git+https://tangled.org/@tangled.org/core"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = inputs: { diff --git a/hosts/lala/crowdsec.nix b/hosts/lala/crowdsec.nix new file mode 100644 index 0000000..4beb4a6 --- /dev/null +++ b/hosts/lala/crowdsec.nix @@ -0,0 +1,64 @@ +{ + inputs, + pkgs, + config, + lib, + ... +}: +let + crowdsecPort = 32487; + crowdsecURI = "localhost:${toString crowdsecPort}"; +in +{ + sops.secrets = { + "lala/netbird/crowdsecLAPI" = { }; + "lala/netbird/crowdsecCAPI".owner = config.users.users.crowdsec.name; + }; + + sops.templates."crowdsec_lapi.yaml" = { + owner = config.users.users.crowdsec.name; + content = '' + url: http://${crowdsecURI} + ${config.sops.placeholder."lala/netbird/crowdsecLAPI"} + ''; + }; + services.crowdsec = { + enable = true; + autoUpdateService = true; + openFirewall = false; # using local api + settings = { + general = { + prometheus.enabled = false; + api.server = { + enable = true; + listen_uri = crowdsecURI; + trusted_ips = [ + "127.0.0.1" + "::1" + ]; + }; + }; + lapi.credentialsFile = config.sops.templates."crowdsec_lapi.yaml".path; + capi.credentialsFile = config.sops.secrets."lala/netbird/crowdsecCAPI".path; + console.configuration = { + share_context = true; + share_custom = true; + share_manual_decisions = true; + share_tainted = true; + }; + }; + hub.collections = [ "crowdsecurity/linux" ]; + localConfig.acquisitions = [ + # Need at least one data source for the service to start + { + journalctl_filter = [ + "_SYSTEMD_UNIT=sshd.service" + ]; + labels = { + type = "syslog"; + }; + source = "journalctl"; + } + ]; + }; +} diff --git a/hosts/lala/default.nix b/hosts/lala/default.nix index fb8957c..bff5094 100644 --- a/hosts/lala/default.nix +++ b/hosts/lala/default.nix @@ -8,9 +8,12 @@ { imports = [ ../../common/os/services/openssh.nix + ./crowdsec.nix ./hardware-configuration.nix ./netbird.nix ./proxies.nix + ./tangled.nix + ./traefik.nix ]; catppuccin = { enable = true; diff --git a/hosts/lala/netbird.nix b/hosts/lala/netbird.nix index bd5cf2c..1c1f3de 100644 --- a/hosts/lala/netbird.nix +++ b/hosts/lala/netbird.nix @@ -11,11 +11,8 @@ let netbirdDomain = "netbird.${domain}"; netbirdUrl = "https://${netbirdDomain}"; stateDir = "/var/lib/netbird-mgmt"; - dashboardPort = 1234; relayPort = 33080; proxyPort = 8443; - crowdsecPort = 32487; - crowdsecURI = "localhost:${toString crowdsecPort}"; coturnPass = config.sops.secrets."lala/netbird/coturnPass".path; relaySecretEnv = config.sops.secrets."lala/netbird/relaySecretEnv".path; hardening = { @@ -52,15 +49,10 @@ in networking.firewall = { allowedTCPPorts = [ - 80 - 443 - 3478 10000 relayPort ]; allowedUDPPorts = [ - 3478 - 5349 relayPort ]; allowedUDPPortRanges = [ @@ -71,97 +63,10 @@ in ]; }; - security.acme.acceptTerms = true; - services.traefik = { - enable = true; - staticConfigOptions = { - entryPoints = { - web.address = ":80"; - websecure.address = ":443"; - }; - certificatesResolvers.letsencrypt.acme = { - email = "moppu@pm.me"; - storage = "acme.json"; - httpChallenge.entryPoint = "web"; - }; - log.level = "INFO"; - }; - dynamicConfigOptions = { - tcp = { - routers = { - proxy-passthrough = { - rule = "HostSNI(`*`)"; - entryPoints = "websecure"; - tls.passthrough = true; - service = "proxy-tls"; - priority = 1; - }; - }; - services.proxy-tls.loadBalancer.servers = [ { address = "localhost:${toString proxyPort}"; } ]; - }; - http = { - routers = { - netbird-dashboard = { - rule = "Host(`${netbirdDomain}`)"; - entryPoints = "websecure"; - tls.certResolver = "letsencrypt"; - service = "netbird-dash"; - priority = 10; - }; - netbird-signal = { - rule = "Host(`${netbirdDomain}`) && PathPrefix(`/ws-proxy/signal`)"; - entryPoints = "websecure"; - tls.certResolver = "letsencrypt"; - service = "netbird-signal"; - priority = 100; - }; - netbird-signal-grpc = { - rule = "Host(`${netbirdDomain}`) && PathPrefix(`/signalexchange.SignalExchange/`)"; - entryPoints = "websecure"; - tls.certResolver = "letsencrypt"; - service = "netbird-signal-grpc"; - priority = 100; - }; - netbird-backend = { - rule = "Host(`${netbirdDomain}`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/management`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))"; - entryPoints = "websecure"; - tls.certResolver = "letsencrypt"; - service = "netbird-server"; - priority = 100; - }; - netbird-backend-grpc = { - rule = "Host(`${netbirdDomain}`) && (PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`))"; - entryPoints = "websecure"; - tls.certResolver = "letsencrypt"; - service = "netbird-server-grpc"; - priority = 100; - }; - }; - services = { - netbird-dash.loadBalancer.servers = [ - { url = "http://localhost:${toString dashboardPort}"; } - ]; - netbird-server.loadBalancer.servers = [ - { url = "http://localhost:${toString config.services.netbird.server.management.port}"; } - ]; - netbird-server-grpc.loadBalancer.servers = [ - { url = "h2c://localhost:${toString config.services.netbird.server.management.port}"; } - ]; - netbird-signal.loadBalancer.servers = [ - { url = "http://localhost:${toString config.services.netbird.server.signal.port}"; } - ]; - netbird-signal-grpc.loadBalancer.servers = [ - { url = "h2c://localhost:${toString config.services.netbird.server.signal.port}"; } - ]; - }; - }; - }; - }; - # Keep nginx config for the dashboard but listen on an internal port instead of port 80 - services.nginx.virtualHosts.${config.services.netbird.server.dashboard.domain}.listen = [ + services.nginx.virtualHosts.${netbirdDomain}.listen = [ { - port = dashboardPort; + port = 1234; addr = "localhost"; } ]; @@ -214,13 +119,13 @@ in { Password._secret = coturnPass; proto = "udp"; - URI = "turn:${netbirdDomain}:3478"; + URI = "turn:${netbirdDomain}:${toString config.services.coturn.listening-port}"; Username = "netbird"; } ]; }; Relay = { - Addresses = [ "rels://${netbirdDomain}:33080" ]; + Addresses = [ "rels://${netbirdDomain}:${toString relayPort}" ]; CredentialsTTL = "24h"; Secret._secret = config.sops.secrets."lala/netbird/relaySecret".path; }; @@ -255,7 +160,7 @@ in NB_PROXY_ACME_CHALLENGE_TYPE = "tls-alpn-01"; NB_PROXY_CERTIFICATE_DIRECTORY = "/var/lib/proxy-certs"; NB_PROXY_LOG_LEVEL = "info"; - NB_PROXY_CROWDSEC_API_URL = "http://${crowdsecURI}"; + NB_PROXY_CROWDSEC_API_URL = "http://${config.services.crowdsec.settings.general.api.server.listen_uri}"; }; serviceConfig = hardening // { EnvironmentFile = config.sops.secrets."lala/netbird/proxySecretEnv".path; @@ -300,106 +205,55 @@ in }; in { - netbird-relay = - let - id = 1; - in - lib.mkMerge [ - commonConfig - (addrMap id) - { - autoStart = true; - bindMounts."/var/lib/acme/${netbirdDomain}".isReadOnly = true; - bindMounts."${relaySecretEnv}".isReadOnly = true; - forwardPorts = [ - { - containerPort = relayPort; - hostPort = relayPort; - protocol = "tcp"; - } - { - containerPort = relayPort; - hostPort = relayPort; - protocol = "udp"; - } - ]; - config = { - networking.firewall = { - allowedTCPPorts = [ relayPort ]; - allowedUDPPorts = [ relayPort ]; + netbird-relay = lib.mkMerge [ + commonConfig + (addrMap 1) + { + autoStart = true; + bindMounts."/var/lib/acme/${netbirdDomain}".isReadOnly = true; + bindMounts."${relaySecretEnv}".isReadOnly = true; + forwardPorts = [ + { + containerPort = relayPort; + hostPort = relayPort; + protocol = "tcp"; + } + { + containerPort = relayPort; + hostPort = relayPort; + protocol = "udp"; + } + ]; + config = { + networking.firewall = { + allowedTCPPorts = [ relayPort ]; + allowedUDPPorts = [ relayPort ]; + }; + systemd.services.netbird-relay = { + enable = true; + description = "The relay service for Netbird, a wireguard VPN"; + documentation = [ "https://netbird.io/docs/" ]; + after = [ + "network.target" + "netbird-management.service" + ]; + wantedBy = [ "multi-user.target" ]; + environment = { + NB_LOG_LEVEL = "info"; + NB_LISTEN_ADDRESS = ":${toString relayPort}"; + NB_EXPOSED_ADDRESS = "rels://${netbirdDomain}:${toString relayPort}"; + NB_TLS_CERT_FILE = "/var/lib/acme/${netbirdDomain}/fullchain.pem"; + NB_TLS_KEY_FILE = "/var/lib/acme/${netbirdDomain}/key.pem"; }; - systemd.services.netbird-relay = { - enable = true; - description = "The relay service for Netbird, a wireguard VPN"; - documentation = [ "https://netbird.io/docs/" ]; - after = [ - "network.target" - "netbird-management.service" - ]; - wantedBy = [ "multi-user.target" ]; - environment = { - NB_LOG_LEVEL = "info"; - NB_LISTEN_ADDRESS = ":${toString relayPort}"; - NB_EXPOSED_ADDRESS = "rels://${netbirdDomain}:${toString relayPort}"; - NB_TLS_CERT_FILE = "/var/lib/acme/${netbirdDomain}/fullchain.pem"; - NB_TLS_KEY_FILE = "/var/lib/acme/${netbirdDomain}/key.pem"; - }; - serviceConfig = hardening // { - EnvironmentFile = relaySecretEnv; - ExecStart = lib.getExe unstable.netbird-relay; - Restart = "always"; - }; - stopIfChanged = false; + serviceConfig = hardening // { + EnvironmentFile = relaySecretEnv; + ExecStart = lib.getExe unstable.netbird-relay; + Restart = "always"; }; + stopIfChanged = false; }; - } - ]; - }; - - sops.templates."crowdsec_lapi.yaml" = { - owner = config.users.users.crowdsec.name; - content = '' - url: http://${crowdsecURI} - ${config.sops.placeholder."lala/netbird/crowdsecLAPI"} - ''; - }; - services.crowdsec = { - enable = true; - autoUpdateService = true; - openFirewall = false; # using local api - settings = { - general = { - prometheus.enabled = false; - api.server = { - enable = true; - listen_uri = crowdsecURI; - trusted_ips = [ - "127.0.0.1" - "::1" - ]; - }; - }; - lapi.credentialsFile = config.sops.templates."crowdsec_lapi.yaml".path; - capi.credentialsFile = config.sops.secrets."lala/netbird/crowdsecCAPI".path; - console.configuration = { - share_context = true; - share_custom = true; - share_manual_decisions = true; - share_tainted = true; - }; + }; + } + ]; }; - hub.collections = [ "crowdsecurity/linux" ]; - localConfig.acquisitions = [ - # Need at least one data source for the service to start - { - journalctl_filter = [ - "_SYSTEMD_UNIT=sshd.service" - ]; - labels = { - type = "syslog"; - }; - source = "journalctl"; - } - ]; - }; } diff --git a/hosts/lala/tangled.nix b/hosts/lala/tangled.nix new file mode 100644 index 0000000..b05a28b --- /dev/null +++ b/hosts/lala/tangled.nix @@ -0,0 +1,38 @@ +{ + inputs, + pkgs, + config, + lib, + ... +}: +let + knotPort = 5555; + knotInternalPort = 5444; +in +{ + imports = [ inputs.tangled.nixosModules.knot ]; + services.traefik.dynamicConfigOptions = { + http = { + routers.tangled-knot = { + rule = "Host(`${config.services.tangled.knot.server.hostname}`)"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "tangled-knot"; + priority = 10; + }; + services.tangled-knot.loadBalancer.servers = [ + { url = "http://${config.services.tangled.knot.server.listenAddr}"; } + ]; + }; + }; + services.tangled.knot = { + enable = true; + server = { + listenAddr = "localhost:${toString knotPort}"; + internalListenAddr = "localhost:${toString knotInternalPort}"; + owner = "did:plc:cs4o74lhxfkkmarqtvhpinj7"; + hostname = "knot.moppu.dev"; + secureMode = true; + }; + }; +} diff --git a/hosts/lala/traefik.nix b/hosts/lala/traefik.nix new file mode 100644 index 0000000..194a047 --- /dev/null +++ b/hosts/lala/traefik.nix @@ -0,0 +1,108 @@ +{ + inputs, + pkgs, + config, + lib, + ... +}: +let + netbirdDomain = config.services.netbird.server.domain; + dashboardPort = (builtins.head config.services.nginx.virtualHosts.${netbirdDomain}.listen).port; +in +{ + networking.firewall = { + allowedTCPPorts = [ + 80 + 443 + ]; + }; + + security.acme.acceptTerms = true; + services.traefik = { + enable = true; + staticConfigOptions = { + entryPoints = { + web.address = ":80"; + websecure.address = ":443"; + }; + certificatesResolvers.letsencrypt.acme = { + email = "moppu@pm.me"; + storage = "acme.json"; + httpChallenge.entryPoint = "web"; + }; + log.level = "INFO"; + }; + dynamicConfigOptions = { + tcp = { + routers = { + proxy-passthrough = { + rule = "HostSNI(`*`)"; + entryPoints = "websecure"; + tls.passthrough = true; + service = "proxy-tls"; + priority = 1; + }; + }; + services.proxy-tls.loadBalancer.servers = [ + { address = "localhost${config.systemd.services.netbird-proxy.environment.NB_PROXY_ADDRESS}"; } + ]; + }; + http = { + routers = { + netbird-dashboard = { + rule = "Host(`${netbirdDomain}`)"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "netbird-dash"; + priority = 10; + }; + netbird-signal = { + rule = "Host(`${netbirdDomain}`) && PathPrefix(`/ws-proxy/signal`)"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "netbird-signal"; + priority = 100; + }; + netbird-signal-grpc = { + rule = "Host(`${netbirdDomain}`) && PathPrefix(`/signalexchange.SignalExchange/`)"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "netbird-signal-grpc"; + priority = 100; + }; + netbird-backend = { + rule = "Host(`${netbirdDomain}`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/management`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "netbird-server"; + priority = 100; + }; + netbird-backend-grpc = { + rule = "Host(`${netbirdDomain}`) && (PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`))"; + entryPoints = "websecure"; + tls.certResolver = "letsencrypt"; + service = "netbird-server-grpc"; + priority = 100; + }; + }; + services = { + netbird-dash.loadBalancer.servers = [ + { url = "http://localhost:${toString dashboardPort}"; } + ]; + netbird-server.loadBalancer.servers = [ + { url = "http://localhost:${toString config.services.netbird.server.management.port}"; } + ]; + netbird-server-grpc.loadBalancer.servers = [ + { url = "h2c://localhost:${toString config.services.netbird.server.management.port}"; } + ]; + netbird-signal.loadBalancer.servers = [ + { url = "http://localhost:${toString config.services.netbird.server.signal.port}"; } + ]; + netbird-signal-grpc.loadBalancer.servers = [ + { url = "h2c://localhost:${toString config.services.netbird.server.signal.port}"; } + ]; + }; + }; + }; + }; +}