diff --git a/modules/hosts/nixos/nixnuc/containers/nginx-proxy.nix b/modules/hosts/nixos/nixnuc/containers/nginx-proxy.nix new file mode 100644 index 0000000..13e93d1 --- /dev/null +++ b/modules/hosts/nixos/nixnuc/containers/nginx-proxy.nix @@ -0,0 +1,178 @@ +{ config, ... }: let + http_port = 80; + https_port = 443; + gandi_api = "${config.sops.secrets.gandi_api.path}"; + #gandi_dns_pat = "${config.sops.secrets.gandi_dns_pat.path}"; + home_domain = "home.technicalissues.us"; + backend_ip = "192.168.20.190"; + mini_watcher = "192.168.23.20"; +in { + sops.secrets.gandi_api = { + sopsFile = ../../../../system/common/secrets.yaml; + restartUnits = [ + "container@nginx-proxy.service" + ]; + }; + #sops.secrets.gandi_dns_pat = { + # sopsFile = ../../../../system/common/secrets.yaml; + # restartUnits = [ + # "container@nginx-proxy.service" + # ]; + #}; + + ## + ## Gandi (gandi.net) + ## + ## Single host update + # protocol=gandi + # zone=example.com + # password=my-gandi-access-token + # use-personal-access-token=yes + # ttl=10800 # optional + # myhost.example.com + services.ddclient = { + enable = true; + protocol = "gandi"; + zone = "technicalissues.us"; + domains = [ home_domain ]; + username = "unused"; + extraConfig = '' + usev4=webv4 + #usev6=webv6 + #use-personal-access-token=yes + ttl=300 + ''; + passwordFile = gandi_api; }; + + containers.nginx-proxy = { + bindMounts."${gandi_api}".isReadOnly = true; + #bindMounts."${gandi_dns_pat}".isReadOnly = true; + autoStart = true; + timeoutStartSec = "5min"; + privateNetwork = true; + hostBridge = "br1-23"; + localAddress = "192.168.23.21/24"; + config = { config, pkgs, lib, ... }: { + system.stateVersion = "23.11"; + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + appendHttpConfig = '' + # Add HSTS header with preloading to HTTPS requests. + # Adding this header to HTTP requests is discouraged + map $scheme $hsts_header { + https "max-age=31536000 always;"; + } + add_header Strict-Transport-Security $hsts_header; + ''; + + virtualHosts = { + "${home_domain}" = { + serverAliases = [ "nix-tester.${home_domain}" ]; + default = true; + listen = [ + { port = http_port; addr = "0.0.0.0"; } + { port = https_port; addr = "0.0.0.0"; ssl = true; } + ]; + enableACME = true; + acmeRoot = null; + addSSL = true; + forceSSL = false; + locations."/" = { + return = "200 '

Hello world ;)

'"; + extraConfig = '' + add_header Content-Type text/html; + ''; + }; + }; + "ab.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + locations."/".proxyWebsockets = true; + locations."/".proxyPass = "http://${mini_watcher}:13378"; + }; + "atuin.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + locations."/".proxyPass = "http://${mini_watcher}:9999"; + }; + "nc.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + extraConfig = '' + client_max_body_size 0; + underscores_in_headers on; + ''; + locations."/".proxyWebsockets = true; + locations."/".proxyPass = "http://${mini_watcher}:8081"; + locations."/".extraConfig = '' + # these are added per https://www.nicemicro.com/tutorials/debian-snap-nextcloud.html + add_header Front-End-Https on; + proxy_headers_hash_max_size 512; + proxy_headers_hash_bucket_size 64; + proxy_buffering off; + proxy_max_temp_file_size 0; + ''; + }; + "onlyoffice.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + locations."/".proxyWebsockets = true; + locations."/".proxyPass = "http://${mini_watcher}:8888"; + }; + "readit.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + locations."/".proxyPass = "http://${mini_watcher}:8090"; + }; + "tandoor.${home_domain}" = { + listen = [{ port = https_port; addr = "0.0.0.0"; ssl = true; }]; + enableACME = true; + acmeRoot = null; + forceSSL = true; + locations."/".proxyPass = "http://${mini_watcher}:8080"; + }; + }; + }; + + security.acme = { + acceptTerms = true; + defaults = { + email = "lets-encrypt@technicalissues.us"; + credentialFiles = { "GANDIV5_API_KEY_FILE" = gandi_api; }; + #credentialFiles = { "GANDIV5_PERSONAL_ACCESS_TOKEN_FILE" = gandi_dns_pat; }; + dnsProvider = "gandiv5"; + dnsResolver = "ns1.gandi.net"; + # uncomment below for testing + #server = "https://acme-staging-v02.api.letsencrypt.org/directory"; + }; + }; + + networking = { + firewall = { + enable = true; + allowedTCPPorts = [ http_port https_port ]; + }; + defaultGateway = "192.168.23.1"; + # Use systemd-resolved inside the container + # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686 + useHostResolvConf = lib.mkForce false; + }; + + services.resolved.enable = true; + }; + }; +} diff --git a/modules/hosts/nixos/nixnuc/default.nix b/modules/hosts/nixos/nixnuc/default.nix index 5b90a09..82e73ba 100644 --- a/modules/hosts/nixos/nixnuc/default.nix +++ b/modules/hosts/nixos/nixnuc/default.nix @@ -1,7 +1,8 @@ -{ inputs, config, hostname, pkgs, sops-nix, username, ... }: { +{ config, pkgs, username, ... }: { imports = [ ./hardware-configuration.nix ./audiobookshelf.nix + ./containers/nginx-proxy.nix ]; system.stateVersion = "23.11"; @@ -49,7 +50,18 @@ hostId = "c5826b45"; # head -c4 /dev/urandom | od -A none -t x4 + useDHCP = false; networkmanager.enable = true; + vlans = { + vlan23 = { id = 23; interface = "eno1"; }; + }; + bridges = { + br1-23 = { interfaces = [ "vlan23" ]; }; + }; + interfaces = { + eno1.useDHCP = true; + br1-23.useDHCP = false; + }; }; # Hardware Transcoding for Jellyfin @@ -83,6 +95,7 @@ enable = true; openFirewall = true; }; + lldpd.enable = true; nginx = { enable = true; virtualHosts."jellyfin" = { diff --git a/modules/system/common/all-nixos.nix b/modules/system/common/all-nixos.nix index c1df1e3..3aff185 100644 --- a/modules/system/common/all-nixos.nix +++ b/modules/system/common/all-nixos.nix @@ -41,10 +41,14 @@ "flakes" "nix-command" ]; - extra-trusted-public-keys = [ + trusted-public-keys = [ + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "flox-cache-public-1:7F4OyH7ZCnFhcze3fJdfyXYLQw/aV7GEed86nQ7IsOs=" ]; - extra-trusted-substituters = [ + substituters = [ + "https://cache.nixos.org" + ]; + trusted-substituters = [ "https://cache.flox.dev" ]; trusted-users = [ "${username}" ]; diff --git a/modules/system/common/secrets.yaml b/modules/system/common/secrets.yaml new file mode 100644 index 0000000..8064289 --- /dev/null +++ b/modules/system/common/secrets.yaml @@ -0,0 +1,76 @@ +gandi_dns_pat: ENC[AES256_GCM,data:81tlAE6e655+RgKZVJgwYg6V59VtMmuVk5spkGZq1U6AgxYXO3wvsA==,iv:Dp5csrqHIAYloi5XkrBgDMqeIX/W+JFJ1avKbTnEU/Y=,tag:QjhdX4gv9OmWtQp7r06+RA==,type:str] +gandi_api: ENC[AES256_GCM,data:YsdDMk75miIKO4LkCZjfwJw6gxfrmsTL,iv:BOPRxB661sPJnUH1AUKEALIJfBeyAHZpkWJEDbY+7i8=,tag:TvtW7qhPbOqi9kKDcIe28w==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1a652ev7gekx4aj589s8fd27ul9j5ugpdwg7pxhmqcwdjwwq9gf2qv38um9 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseHFTeDZoMElxVUZpWFVa + dmxvWEFkS0p6aTFraUNyNmtITTQ4bFdLNFVZCnlsTlE3TUVvMWdXS0psb0FOQVdP + UGtTVVQ3ZExQVUdvekFEa0lYZmRxdEkKLS0tIEEyMXdkZ0JyV0orSnVwL3hMWVpy + TTAvb09FUE1JaXpNSm80Mmx3Z292eVUKjJ8Q9y2PhU9NpgCjKYne7zY+I+fXvIhs + BB/lskZG/AVuGdBDHRf0yIVFd/j6inTWbP1u3wJ+Mf+dBnPAlS9rXg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1g24zhwvgenpc4wqejt63thvgd4rn5x9n7nnwwme7dm83nfqpp93se2vmq4 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYWWVCd0ZjMzkxZVdIR1JC + Q1plamZveGg1Z1FaK2VPb29CUVVia0Q4aFZ3CkNKUjl0S090SUMwU1dJenRONEpJ + WnZ6aEFwV2lrelBZV0p0UUQvaWdmS0kKLS0tIGh2OE5iTTRObFEraUpxN0YyTVpx + Mk5Sb0VCN1VjMnNNdzBBZWY3Q2FsUFkK7d9MAUNRL7GSF6diz/5X21BmMsyE5Cu3 + 18ycNiMLtUwGHsfxh+aLliFDBO32LwMI64/tKHDtx4sHQSBGoppsfQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age15xlw5vnnjdx2ypz6rq0mqcywuaj3yx8y6lrgf95satafqf7y4qus6rv6ck + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4UEc1M2UwTkduWnEyMG8x + TGVYaUpsSlNVcnBxdHZRWU8ydUJvMnZXTTNZCmtIenlWeDdvM0xQemI3Y1dXNlox + SUhNcG5iZE44WGhWL0NwUTZjSzhPNFkKLS0tIHIyaU1DOUxSV0VWVTRaQmhBbXVP + dGVWRnhIek1mV2FJemF1dzVwMjZqWUUKNvkzOwi6OR369S5e5y6TSfGA4/EH09WK + MWlH3fzABkCN+IeRmOmtU/L3MdHIiWanDWp6KdWCJJ3OnBO8cjMEig== + -----END AGE ENCRYPTED FILE----- + - recipient: age1awdf9h0avajf57cudx0rjfmxu2wlxw8wf3sa7yvfk8rp4j6taecsu74x77 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLOE5pYXFDdXQzblI1N01i + eFROYzVvK3cxN1pJMHlScW0rZjBScG9SMzBnCko4VDllS0pQMU5NdU5NbndWQWpq + NmhWK1RJSHpITktFWTZIN2JHRklqS2cKLS0tIFFjRE9Ia3Z0TzIyd2MrS2RRWU9k + d3FIL3dqTHRtQVJiS255aVVWZ1p3UjQKb+65IgxbWXtkidmlb5w5Cu11izXh5QgR + I1YAckCX6RlR3Mlcs/5cTyLakpc3ibm/g4+N9+EhlIQz4wIxmxAtHQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1rt72txg22w8y3cdvq9w7zff0cas6xtkplpj36kxnevfnrtn82f6ss7yw7d + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNb2hxZElESWd4eTFycFI1 + YWpKS1ZpWmtYcy9JK2ZPQ1QzSXFjWXM5VzFjCk1CcmJmdE5yL0J1Q2RBN3Npa2hn + WWxZTHkwTnhZaXBYanpZTkRTRUdTcWcKLS0tIFA3SkVuVFFVT2NsbVBlNUdFRlUx + UE9sMXVVOW1ib3JBYUR5LzVFRFp3ZWcK2hwlxaEUexjqHcg86dSpJU37b8bkWO6r + mSygDEjU71u20G6sdMeoSyxepPtWJsVhnAMukFsnKZf6LyfiiCseAQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1zz34qx3n3dj63sva24kaymetv3apn58lafjq4dl6zw7xxachuyts00mhck + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoZndiK3FMOUptbDRGOVQ0 + QnNSSEtlVHZtaUlRQlRySzJNUmdqbzRQRFZFCnNyOHRtNFhsWGEvTFRkNTRUbit6 + OWh6cVRRTXhlQmxpY3JpNVFRdStuWkkKLS0tIElYZGRVVWVSTlBhRHhVYWRFSFhC + NERwYVhzTjRZUDBmbTM2QzEyay9vT2MK9QIINuuaagTz2wyF9NiNzE0aiwoAHquH + GK203V5jVnLXftOV09NIg3027m8KCRc7yEWOtcbH5UkGZxZCqESv9Q== + -----END AGE ENCRYPTED FILE----- + - recipient: age1rpy8edlpgxuf6w75cvlqexuq2xe4c49h9t2ge6jhc3fzczp8vfasnjelwq + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNY2xrM1BFRDdtckRGZkIz + Mkc5VzNHQzV5aC9xTzU4US80czFMcHNpbXpzCnlqUWliUjlra1U0Y0dJTDByMGFQ + MlRTd2FaT1QzMXFWZ3piVjZsZ1ZDemsKLS0tIENRdlVvNE5VT3VOc2hqM2ZnVUVY + ZlBVMUJmWml3dkQ3OTN1ZmF1N0hXNHcKnLOSViooQmhU5yE754VHIBYNRVikgptc + 3bXDiOlkjBbxGru3bnn+vUUJ3n+QdZoAnCgdL7D2/Me3HVrAW5M5LA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-04-05T03:17:40Z" + mac: ENC[AES256_GCM,data:4u2rpoc20qDv3W6s3lgtYU+35cfaK1tOmMySuji07s7IxqXqmkAn/giynH7y+PQRLACV6XvKnysLwuTPanekmXqQx/cOPOIPPrXOwz4oDLncFILI+7H/ShFuRN3KKUq9+OZElO4lLO0PDL+6flo3Mq6oSbzzeqxqVXUvt5gG8So=,iv:WEoiZzIWxAsxr3+nUY7b/jewYn6YRraU+zIPBhin8JI=,tag:BN5zLe8jdrvvCFU0BbfiaQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1