From 6de382ceb46c9c76098e4619cc8bc343c4fd4b03 Mon Sep 17 00:00:00 2001 From: James Eversole Date: Tue, 27 Jun 2023 19:41:33 -0500 Subject: [PATCH] Refactor nginx.nix using generative functions; Remove bind container service; Enable CoreDNS; Open 53UDP on system firewall; rename service files; containers listen on localhost only; added SDA-EXT data volume --- README | 43 ++++- application/containers.nix | 20 +-- application/nginx.nix | 183 ++++++++------------ flake.nix | 3 +- shell.nix | 2 +- system/{services.nix => build-services.nix} | 4 +- system/dns.nix | 17 ++ system/hardware.nix | 45 ++--- system/security.nix | 3 + system/system.nix | 2 +- 10 files changed, 159 insertions(+), 163 deletions(-) rename system/{services.nix => build-services.nix} (86%) create mode 100644 system/dns.nix diff --git a/README b/README index 8988209..a52d559 100644 --- a/README +++ b/README @@ -1,19 +1,49 @@ # eve-psr-nix0 -This repository holds the configuration for my primary home server. -This README exists to document solutions used or implemented with Nix. +This repository holds the configuration for my primary home server. --- +## details + +- Defines a single node host +- Follows the latest stable nixpkgs +- Utilizes the nixpkgs-fmt code formatter + -> /flake.nix + +- Provides a devShell with direnv/nix-direnv integration +- Common project scripts are packaged and then exposed via devShell/direnv + -> /shell.nix + +- Allows SSH Access +- Enables the Hydra build server +- Enables the nix-serve-ng binary cache server + -> /system/services.nix + +- HTTP entrypoint is an Nginx Reverse Proxy +- Automatic TLS provisioning via Let's Encrypt ACME +- Directly reference nix packages and configuration in Virtual Host definitions + -> /applcation/nginx.nix + +- Monitoring stack consisting of Prometheus, Grafana, Loki, and Promtail +- Complete monitoring stack and connections are defined declaratively via Nix + -> /monitoring/*.nix + +- podman & systemd container orchestration +- podman services are exposed only to localhost and are reverse proxied by Nginx + -> /application/containers.nix + +- agenix for secrets encryption and management + -> /system/age.nix ## cheatsheet -### Enter the developer shell without pulling down the repository: +### Enter the developer shell without cloning the repository: ``` $> nix develop git+https://git.eversole.co/eve-psr-nix0 $nix> # Success! ``` -The rest of the cheatsheet assumes you have already cloned the repository and entered the developer shell: +The rest of the cheatsheet assumes you have entered the developer shell or are using direnv: ``` $> git clone https://git.eversole.co/eve-psr-nix0 $> cd eve-psr-nix0 @@ -23,13 +53,14 @@ $nix> # Success! Now we have our development dependencies. ### Use the developer shell alias to remotely build and deploy the configuration to eve-psr-nix0: ``` -# This is it! Check the shellHook in outputs.devShell.x86_64-linux for more details. +# This is it! Check the package definitions in /shell.nix for more details. $nix> deploy ``` ### Format .nix source files: ``` -$nix> nix fmt *.nix +# This is it! Check the package definitions in /shell.nix for more details. +$nix> format ``` ### Create a new agenix secret: diff --git a/application/containers.nix b/application/containers.nix index 6c97870..a9238e2 100644 --- a/application/containers.nix +++ b/application/containers.nix @@ -2,17 +2,9 @@ virtualisation.oci-containers = { containers = { - bind = { - image = "sameersbn/bind:latest"; - ports = - [ "0.0.0.0:53:53/tcp" "0.0.0.0:53:53/udp" "0.0.0.0:5053:10000/tcp" ]; - volumes = [ "/home/sezycei/srv/containerdata/bind/bind:/data" ]; - environmentFiles = [ /home/sezycei/srv/containerdata/bind/.env ]; - }; - jellyfin = { image = "linuxserver/jellyfin"; - ports = [ "0.0.0.0:8096:8096" "0.0.0.0:8920:8920" ]; + ports = [ "127.0.0.1:8096:8096" "127.0.0.1:8920:8920" ]; volumes = [ "/home/sezycei/srv/containerdata/jellyfin/config:/config" "/home/torrent/data/completed:/data/unsorted" @@ -31,7 +23,7 @@ legit = { image = "docker.matri.cx/legit"; - ports = [ "0.0.0.0:5121:8080" ]; + ports = [ "127.0.0.1:5121:8080" ]; volumes = [ "/home/sezycei/srv/containerdata/legit/static:/static" "/home/sezycei/srv/containerdata/legit/templates:/templates" @@ -43,7 +35,7 @@ murmur = { image = "goofball222/murmur"; - ports = [ "0.0.0.0:64738:64738" "0.0.0.0:64738:64738/udp" ]; + ports = [ "127.0.0.1:64738:64738" "127.0.0.1:64738:64738/udp" ]; volumes = [ "/home/sezycei/srv/containerdata/registry/registry/data:/var/lib/registry" "/home/sezycei/srv/containerdata/registry/registry/certs:/certs" @@ -54,7 +46,7 @@ purr = { image = "docker.matri.cx/purr"; - ports = [ "0.0.0.0:5195:3000" ]; + ports = [ "127.0.0.1:5195:3000" ]; volumes = [ "/home/sezycei/dev/purr/data/Purr.sqlite:/app/data/Purr.sqlite" "/home/sezycei/dev/purr/config.dhall:/app/config.dhall" @@ -64,7 +56,7 @@ registry = { image = "registry:2"; - ports = [ "0.0.0.0:3001:5000" ]; + ports = [ "127.0.0.1:3001:5000" ]; volumes = [ "/home/sezycei/srv/containerdata/registry/registry/data:/var/lib/registry" "/home/sezycei/srv/containerdata/registry/registry/certs:/certs" @@ -75,7 +67,7 @@ transmission = { image = "haugene/transmission-openvpn"; - ports = [ "0.0.0.0:9091:9091" ]; + ports = [ "127.0.0.1:9091:9091" ]; volumes = [ "/home/sezycei/srv/scripts/transmission/settings.json:/etc/transmission-daemon/settings.json" "/etc/localtime:/etc/localtime:ro" diff --git a/application/nginx.nix b/application/nginx.nix index 7579a0d..90521f9 100644 --- a/application/nginx.nix +++ b/application/nginx.nix @@ -1,124 +1,77 @@ -{ config, ... }: { +{ pkgs, config, ... }: +let + containernix = import ./containers.nix; + containers = containernix.virtualisation.oci-containers.containers; +in +{ services.nginx = { enable = true; recommendedProxySettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; - virtualHosts."cache.matri.cx" = { - enableACME = true; - forceSSL = true; - root = "/var/www/cache.matri.cx"; - locations."/" = { - extraConfig = "allow 192.168.0.0\/24;\ndeny all;"; - proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; + virtualHosts = + let + base = locations: { + enableACME = true; + forceSSL = true; + inherit locations; + }; + + static = { dir }: base { + "/".root = dir; + }; + + proxied = { target, extra ? "" }: base { + "/" = { + proxyPass = target; + extraConfig = extra; + }; + }; + + proxiedAuth = { target, extra ? "", auth }: base { + "/" = { + proxyPass = target; + basicAuthFile = auth; + extraConfig = extra; + }; + }; + proxiedLAN = { target }: base { + "/" = { + proxyPass = target; + extraConfig = '' + allow 192.168.0.0/24; + deny all; + ''; + }; + }; + in + { + "cache.matri.cx" = proxiedLAN { + target = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; + }; + "caitlynncox.com" = static { dir = "/var/www/caitlynncox.com"; }; + "dallasmed65.com" = static { dir = "/var/www/dallasmed65.com"; }; + "docker.matri.cx" = proxiedAuth { + auth = config.age.secrets.htpasswd-dock.path; + target = "http://127.0.0.1:3001"; + }; + "eversole.co" = static { dir = "/var/www/jame.su"; }; + "git.eversole.co" = proxied { target = "http://127.0.0.1:5121"; }; + "graf.eversole.co" = { root = "/var/www/graf.eversole.co"; }; # refer to /monitoring/nginx.nix + "hydra.matri.cx" = proxied { + target = "http://127.0.0.1:3034"; + extra = '' + proxy_set_header X-Request-Base "https://hydra.matri.cx"; + ''; + }; + "jame.su" = static { dir = "/var/www/jame.su"; }; + "matri.cx" = static { dir = "/var/www/matri.cx"; }; + "media.matri.cx" = proxied { target = "http://127.0.0.1:8096"; }; + "sezycei.com" = static { dir = "/var/www/sezycei.com"; }; + "snakebelmont.com" = static { dir = "/var/www/snakebelmont.com"; }; + "transmission.matri.cx" = proxiedLAN { target = "http://127.0.0.1:9001"; }; + "purr.eversole.co" = proxied { target = "http://127.0.0.1:5195"; }; }; - }; - - virtualHosts."caitlynncox.com" = { - enableACME = true; - forceSSL = true; - root = "/var/www/caitlynncox.com"; - }; - - virtualHosts."dallasmed65.com" = { - enableACME = true; - forceSSL = true; - root = "/var/www/dallasmed65.com"; - }; - - virtualHosts."docker.matri.cx" = { - enableACME = true; - forceSSL = true; - root = "/var/www/docker.matri.cx"; - locations."/" = { - basicAuthFile = config.age.secrets.htpasswd-dock.path; - proxyPass = "http://192.168.0.130:3001"; - }; - }; - - virtualHosts."eversole.co" = { - enableACME = true; - forceSSL = true; - root = "/var/www/jame.su"; - locations = { - "/.well-known/openpgpkey/hu/".extraConfig = '' - default_type "application/octet-stream"; - add_header Access-Control-Allow-Origin * always; - ''; - "/ip".proxyPass = "http://192.168.0.130:5001"; - "/pw".proxyPass = "http://192.168.0.130:5002"; - }; - }; - - virtualHosts."git.eversole.co" = { - enableACME = true; - forceSSL = true; - root = "/var/www/git.eversole.co"; - locations = { - "/James".extraConfig = '' - if ($request_uri ~* "([^/]*$)" ) { - return 301 https://$server_name/$1; - } - ''; - "/".proxyPass = "http://192.168.0.130:5121"; - }; - }; - - # refer to /monitoring/nginx.nix - virtualHosts."graf.eversole.co" = { - root = "/var/www/graf.eversole.co"; - }; - - virtualHosts."hydra.matri.cx" = { - enableACME = true; - forceSSL = true; - root = "/var/www/hydra.matri.cx"; - locations."/" = { - proxyPass = "http://192.168.0.130:3034"; - extraConfig = '' - proxy_set_header X-Request-Base "https://hydra.matri.cx"; - ''; - }; - }; - - virtualHosts."jame.su" = { - enableACME = true; - forceSSL = true; - root = "/var/www/jame.su"; - }; - - virtualHosts."matri.cx" = { - enableACME = true; - forceSSL = true; - root = "/var/www/matri.cx"; - }; - - virtualHosts."media.matri.cx" = { - enableACME = true; - forceSSL = true; - root = "/var/www/media.matri.cx"; - locations."/".proxyPass = "http://192.168.0.130:8096"; - }; - - virtualHosts."sezycei.com" = { - enableACME = true; - forceSSL = true; - root = "/var/www/sezycei.com"; - }; - - virtualHosts."snakebelmont.com" = { - enableACME = true; - forceSSL = true; - root = "/var/www/snakebelmont.com"; - }; - - virtualHosts."purr.eversole.co" = { - enableACME = true; - forceSSL = true; - root = "/var/www/purr.eversole.co"; - locations."/".proxyPass = "http://192.168.0.130:5195"; - }; - }; } diff --git a/flake.nix b/flake.nix index 48924ad..9c1e908 100644 --- a/flake.nix +++ b/flake.nix @@ -47,10 +47,11 @@ ./monitoring/promtail.nix ./system/age.nix + ./system/dns.nix ./system/hardware.nix ./system/nix-conf.nix ./system/security.nix - ./system/services.nix + ./system/build-services.nix ./system/system.nix ./system/virtualisation.nix diff --git a/shell.nix b/shell.nix index 5f8b74d..7d71c73 100644 --- a/shell.nix +++ b/shell.nix @@ -14,7 +14,7 @@ packages = { x86_64-linux = { deploy = pkgs.writeShellScriptBin "deploy" '' - nixos-rebuild switch --target-host root@matri.cx --build-host root@matri.cx --flake .#eve-psr-nix0 ; + nixos-rebuild switch --target-host root@192.168.0.130 --build-host root@192.168.0.130 --flake .#eve-psr-nix0 ; ''; format = pkgs.writeShellScriptBin "format" '' nix fmt ./*.nix; diff --git a/system/services.nix b/system/build-services.nix similarity index 86% rename from system/services.nix rename to system/build-services.nix index 87c2ef0..577b0da 100644 --- a/system/services.nix +++ b/system/build-services.nix @@ -1,11 +1,9 @@ { config, ... }: { services = { - openssh = { enable = true; }; - hydra = { enable = true; hydraURL = "https://hydra.matri.cx"; - listenHost = "192.168.0.130"; + listenHost = "127.0.0.1"; port = 3034; extraConfig = '' diff --git a/system/dns.nix b/system/dns.nix new file mode 100644 index 0000000..9c5769b --- /dev/null +++ b/system/dns.nix @@ -0,0 +1,17 @@ +{ config, ... }: { + services = { + coredns.enable = true; + coredns.config = '' + . { + forward . 9.9.9.9 149.112.112.112 84.200.69.80 84.200.70.40 + cache + } + + matri.cx { + template IN A { + answer "{{ .Name }} 0 IN A 192.168.0.130" + } + } + ''; + }; +} diff --git a/system/hardware.nix b/system/hardware.nix index 74868ed..0fcdcbd 100644 --- a/system/hardware.nix +++ b/system/hardware.nix @@ -1,37 +1,38 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. { config, lib, pkgs, modulesPath, ... }: { imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; - boot.initrd.availableKernelModules = - [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ]; - boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ "kvm-intel" ]; - boot.extraModulePackages = [ ]; - - fileSystems."/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "ext4"; + boot = { + initrd = { + availableKernelModules = + [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ]; + kernelModules = [ ]; + }; + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; }; - fileSystems."/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; + fileSystems = { + "/" = { + device = "/dev/disk/by-label/NIXROOT"; + fsType = "ext4"; + }; + + "/mnt/data" = { + device = "/dev/disk/by-label/SDA-EXT"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-label/NIXBOOT"; + fsType = "vfat"; + }; }; swapDevices = [ ]; - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. networking.useDHCP = lib.mkDefault true; - # networking.interfaces.eno1.useDHCP = lib.mkDefault true; - # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; hardware.cpu.intel.updateMicrocode = diff --git a/system/security.nix b/system/security.nix index e36f627..5362de5 100644 --- a/system/security.nix +++ b/system/security.nix @@ -1,4 +1,7 @@ { ... }: { + services.openssh = { + enable = true; + }; security = { sudo.wheelNeedsPassword = false; acme = { diff --git a/system/system.nix b/system/system.nix index 98a9dee..c5af330 100644 --- a/system/system.nix +++ b/system/system.nix @@ -10,7 +10,7 @@ hostName = "eve-psr-nix0"; firewall = { allowedTCPPorts = [ 22 80 443 ]; - allowedUDPPorts = [ 22 80 443 ]; + allowedUDPPorts = [ 22 80 443 53 ]; }; };