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

This commit is contained in:
James Eversole 2023-06-27 19:41:33 -05:00
parent 13e06ad3af
commit 6de382ceb4
10 changed files with 159 additions and 163 deletions

43
README
View File

@ -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:

View File

@ -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"

View File

@ -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";
};
};
}

View File

@ -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

View File

@ -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;

View File

@ -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 = ''

17
system/dns.nix Normal file
View File

@ -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"
}
}
'';
};
}

View File

@ -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.<interface>.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 =

View File

@ -1,4 +1,7 @@
{ ... }: {
services.openssh = {
enable = true;
};
security = {
sudo.wheelNeedsPassword = false;
acme = {

View File

@ -10,7 +10,7 @@
hostName = "eve-psr-nix0";
firewall = {
allowedTCPPorts = [ 22 80 443 ];
allowedUDPPorts = [ 22 80 443 ];
allowedUDPPorts = [ 22 80 443 53 ];
};
};