From c7abbc56562f9745d9d1bb29f3c0d4874425e92c Mon Sep 17 00:00:00 2001 From: adikro Date: Sat, 23 May 2026 21:32:00 +0200 Subject: updates --- os/srv/authelia.nix | 55 ++++++++++++++ os/srv/default.nix | 4 +- os/srv/firewall.nix | 10 +-- os/srv/gaming.nix | 6 +- os/srv/lldap.nix | 24 +++++++ os/srv/nginx.nix | 25 ++++++- os/srv/nix-helper.nix | 6 +- os/srv/ntopng.nix | 20 ++++++ os/srv/ssh.nix | 111 +++++++++++++++++++---------- os/srv/syncthing.nix | 194 ++++++++++++++++++++++++++++---------------------- os/srv/vpn.nix | 49 ------------- os/srv/wireguard.nix | 146 ++++++++++++++++++++++++++++++++++++- 12 files changed, 456 insertions(+), 194 deletions(-) create mode 100644 os/srv/authelia.nix create mode 100644 os/srv/lldap.nix create mode 100644 os/srv/ntopng.nix delete mode 100644 os/srv/vpn.nix (limited to 'os/srv') diff --git a/os/srv/authelia.nix b/os/srv/authelia.nix new file mode 100644 index 0000000..a7a8c19 --- /dev/null +++ b/os/srv/authelia.nix @@ -0,0 +1,55 @@ +{ + config, + lib, + masterDomain, + ... +}: +let + cfg = config.os.srv.authelia; +in +{ + options.os.srv.authelia.enable = lib.mkEnableOption "enables authelia scanning"; + options.os.services.authelia.extraRules = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + default = [ ]; + description = "Additional access control rules to be appended to Authelia."; + }; + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = config.os.srv.sops.enable; + message = "Required for password secure password storing"; + } + ]; + services.authelia.instances.main = { + enable = true; + secrets = { + jwtSecretFile = config.sops.secrets."authelia/jwt_secret".path; + storageEncryptionKeyFile = config.sops.secrets."authelia/encryptionKey".path; + }; + settings = { + theme = "dark"; + authentication_backend = { + ldap = { + address = "ldap://127.0.0.1:3890"; + implementation = "lldap"; + base_dn = "dc=example,dc=com"; + user = "uid=authelia,ou=people,dc=example,dc=com"; + password_file = config.sops.secrets."lldap/bind_password".path; + }; + }; + access_control = { + default_policy = "deny"; + rules = [ + { + domain = "auth.${masterDomain}"; + policy = "bypass"; + } + ] + ++ config.os.services.authelia.extraRules; + }; + session.domain = masterDomain; + }; + }; + }; +} diff --git a/os/srv/default.nix b/os/srv/default.nix index d42fdb9..9bba42b 100644 --- a/os/srv/default.nix +++ b/os/srv/default.nix @@ -2,6 +2,7 @@ { imports = [ ./aide.nix + ./authelia.nix ./backup.nix ./bluetooth.nix ./clamav.nix @@ -13,10 +14,12 @@ ./gaming.nix ./i2p.nix ./kdeconnect.nix + ./lldap.nix ./monero.nix ./nfs.nix ./nginx.nix ./nix-helper.nix + ./ntopng.nix ./oci.nix ./omnisearch.nix ./opnsense.nix @@ -28,7 +31,6 @@ ./tailscale.nix ./tor.nix ./virtualization.nix - ./vpn.nix ./wireguard.nix ./yggdrasil.nix ./zfs.nix diff --git a/os/srv/firewall.nix b/os/srv/firewall.nix index 9242007..bc06ffe 100644 --- a/os/srv/firewall.nix +++ b/os/srv/firewall.nix @@ -4,19 +4,13 @@ let in { options.os.srv.firewall = { - enable = lib.mkEnableOption "enables the firewall"; + enable = lib.mkEnableOption "enables the nixos firewall and nftables"; }; config = lib.mkIf cfg.enable { networking = { + firewall.enable = true; nftables.enable = true; - - firewall = { - enable = true; - - allowedTCPPorts = [ ]; - allowedUDPPorts = [ ]; - }; }; }; } diff --git a/os/srv/gaming.nix b/os/srv/gaming.nix index 1e3e9cd..28e309a 100644 --- a/os/srv/gaming.nix +++ b/os/srv/gaming.nix @@ -107,9 +107,9 @@ in home.packages = [ inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.wrapped ]; xdg.desktopEntries = { - "SLSsteam" = { - name = "SLSsteam"; - comment = "Library modification for Steam"; + steam = { + name = "Steam"; + comment = "Library modified Steam client"; exec = "${ lib.getExe' inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.wrapped "SLSsteam" } %U"; diff --git a/os/srv/lldap.nix b/os/srv/lldap.nix new file mode 100644 index 0000000..1cf43e4 --- /dev/null +++ b/os/srv/lldap.nix @@ -0,0 +1,24 @@ +{ config, lib, ... }: +let + cfg = config.os.srv.lldap; +in +{ + options.os.srv.lldap.enable = lib.mkEnableOption "enables lldap scanning"; + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = config.os.srv.sops.enable; + message = "Required for password secure password storing"; + } + ]; + services.lldap = { + enable = true; + settings = { + ldap_base_dn = "dc=example,dc=com"; + ldap_port = 3890; + http_port = 17170; + }; + environmentFile = config.sops.secrets."lldap/env".path; + }; + }; +} diff --git a/os/srv/nginx.nix b/os/srv/nginx.nix index b0c01a7..f0207b3 100644 --- a/os/srv/nginx.nix +++ b/os/srv/nginx.nix @@ -1,4 +1,9 @@ -{ config, lib, ... }: +{ + config, + lib, + pkgs, + ... +}: let cfg = config.os.srv.nginx; @@ -17,14 +22,30 @@ in config = lib.mkIf cfg.enable { services.nginx = { enable = true; + package = pkgs.nginx.override { openssl = pkgs.libressl; }; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; + virtualHosts = { + default = { + serverName = "_"; + default = true; + rejectSSL = true; + locations."/".return = "444"; + }; + }; + }; + + security.acme = { + acceptTerms = true; + defaults.email = "adikro@disroot.org"; }; - networking.firewall.allowedTCPPorts = lib.mkOptional cfg.openFirewall [ + # users.users.nginx.extraGroups = [ "acme" ]; + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 80 443 ]; diff --git a/os/srv/nix-helper.nix b/os/srv/nix-helper.nix index 5e5e133..9734043 100644 --- a/os/srv/nix-helper.nix +++ b/os/srv/nix-helper.nix @@ -2,7 +2,6 @@ config, lib, pkgs, - username, ... }: let @@ -12,10 +11,7 @@ in options.os.srv.nix-helper.enable = lib.mkEnableOption "enables nix-helper"; config = lib.mkIf cfg.enable { nix.settings = { - trusted-users = [ - "root" - "${username}" - ]; + allowed-users = [ "@users" ]; experimental-features = [ "nix-command" "flakes" diff --git a/os/srv/ntopng.nix b/os/srv/ntopng.nix new file mode 100644 index 0000000..3c11534 --- /dev/null +++ b/os/srv/ntopng.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: +let + cfg = config.os.srv.ntopng; +in +{ + options.os.srv.ntopng.enable = lib.mkEnableOption "enables ntopng monitoring"; + config = lib.mkIf cfg.enable { + services.ntopng = { + enable = true; + httpPort = 3000; + extraConfig = "--packet-fanout"; + + # TODO fill interfaces + interfaces = [ + "" + "" + ]; + }; + }; +} diff --git a/os/srv/ssh.nix b/os/srv/ssh.nix index 089fb32..2c7a4ac 100644 --- a/os/srv/ssh.nix +++ b/os/srv/ssh.nix @@ -6,50 +6,85 @@ }: let cfg = config.os.srv.ssh; - keys = { - main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC610CJfgc3yII7MpLVqzEzQGa8Tsm+dih+CTXHXTnv4"; - oci = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgWmRbNTP/kcaZ8JNV1boVTZ/FQVV4qP/9eTKL9buzDvz9HJdgyWmbCiVZicNSert31IRdWOF/wm1sFjZ48nSkGDHbrnc//MPSdHULTx+kMES/NW9SZwwpaquFIJClrObysxrFYBAqweD+DJ3bp451WIymBs7lRBMNKPgoHBpJ5WN2CfIQjl60Jqnli7ML5seCsrquPEemcMPr1TFPmrFCbirzgDVkzCLL5kOowSD2uprtSA08fFm/pZ6nZh6KTQaEgPO4zR9tK+NQ46oCynWwBTI7JOPB4/LtIOiC5TjEUrkXZ/sJzpCBiNPYSRI8RWnAD0N/uVFJ4EYPUKLO2C/d"; - }; + keys.main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC610CJfgc3yII7MpLVqzEzQGa8Tsm+dih+CTXHXTnv4"; in { - options.os.srv.ssh.enable = lib.mkEnableOption "enables ssh server setup"; - - config = lib.mkIf cfg.enable { - services.openssh = { - enable = true; - settings = { - PasswordAuthentication = false; - KbdInteractiveAuthentication = false; - }; + options.os.srv.ssh = { + server = { + enable = lib.mkEnableOption "enables the ssh server module"; + enableWireguard = lib.mkEnableOption "only allows connections from wireguard"; }; + client = { + enable = lib.mkEnableOption "enables the ssh client module"; + createAliases = lib.mkEnableOption "enables system-wide SSH shortcuts"; + }; + enableSigning = lib.mkEnableOption "enables signing git commits with ssh keys"; + }; - programs.ssh.startAgent = true; - services.gnome.gcr-ssh-agent.enable = false; + config = lib.mkMerge [ + (lib.mkIf cfg.server.enable { + services.openssh = { + enable = true; - users.users.${username}.openssh.authorizedKeys.keys = [ "${keys.main} adikro@disroot.org" ]; + hostKeys = [ + { + path = "/etc/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + ]; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "no"; - environment.etc."ssh/allowed_signers".text = "adikro@disroot.org ${keys.main}"; - home-manager.users.${username} = { - programs.ssh = { - enable = true; - enableDefaultConfig = false; - - matchBlocks = { - "github.com codeberg.org" = { - identityFile = "~/.ssh/main_id_ed25519.pub"; - identitiesOnly = true; - user = "git"; - }; - "oci" = { - hostname = "130.162.223.123"; - user = "opc"; - }; + PubkeyAcceptedAlgorithms = "ssh-ed25519"; }; }; - home.file = { - ".ssh/main_id_ed25519.pub".text = keys.main; - ".ssh/oci.pub".text = keys.oci; - }; - }; - }; + + users.users.${username}.openssh.authorizedKeys.keys = [ + "${keys.main} adikro@disroot.org" + ]; + }) + (lib.mkIf (cfg.server.enable && cfg.server.enableWireguard) { + services.openssh.listenAddresses = [ + { + addr = "10.255.0.1"; + } + ]; + }) + + (lib.mkIf cfg.client.enable { + programs.ssh.startAgent = true; + services.gnome.gcr-ssh-agent.enable = false; + }) + + (lib.mkIf (cfg.client.enable && cfg.client.createAliases) { + programs.ssh.extraConfig = '' + Host github.com codeberg.org + IdentityFile /home/${username}/.ssh/main_id_ed25519.pub + IdentitiesOnly yes + User git + + Host oci + HostName 130.162.223.123 + User opc + + Host bibus + HostName bibus.top + User opc + + Host bibus-local + HostName 10.255.0.1 + user opc + ''; + systemd.tmpfiles.rules = [ + "d /home/${username}/.ssh 0700 ${username} users - -" + "f /home/${username}/.ssh/main_id_ed25519.pub 0644 ${username} users - ${keys.main}" + ]; + }) + + (lib.mkIf cfg.enableSigning { + environment.etc."ssh/allowed_signers".text = "adikro@disroot.org ${keys.main}"; + }) + ]; } diff --git a/os/srv/syncthing.nix b/os/srv/syncthing.nix index 28806f1..bcbf665 100644 --- a/os/srv/syncthing.nix +++ b/os/srv/syncthing.nix @@ -6,10 +6,116 @@ }: let cfg = config.os.srv.syncthing; - syncDirs = lib.mapAttrsToList (_: folder: folder.path) config.services.syncthing.settings.folders; + allFolders = { + "openmw-config" = { + path = "/home/${username}/.config/openmw"; + id = "openmw-config"; + devices = [ "oci" ]; + versioning = { + type = "simple"; + params.keep = "3"; + }; + ignorePatterns = [ + "settings.cfg" + "*.log" + ]; + }; + + "openmw-mods" = { + path = "/home/${username}/games/openmw"; + id = "openmw-mods"; + devices = [ "oci" ]; + versioning = { + type = "trashcan"; + params.cleanoutDays = "7"; + }; + }; + + "game-saves" = { + path = "/home/${username}/.saves"; + id = "game-saves"; + devices = [ "oci" ]; + versioning = { + type = "staggered"; + params = { + cleanInterval = "3600"; + maxAge = "2592000"; + }; + }; + }; + + "keepass" = { + path = "/home/${username}/.keepass"; + id = "keepass"; + devices = [ + { + name = "oci"; + encryptionPasswordFile = config.sops.secrets."syncthing/encryption/keepass".path; + } + ]; + versioning = { + type = "staggered"; + params = { + cleanInterval = "3600"; + maxAge = "31536000"; + }; + }; + }; + + "sync" = { + path = "/home/${username}/sync"; + id = "sync"; + devices = [ + { + name = "oci"; + encryptionPasswordFile = config.sops.secrets."syncthing/encryption/sync".path; + } + ]; + versioning = { + type = "staggered"; + params = { + cleanInterval = "3600"; + maxAge = "15552000"; + }; + }; + }; + + "music" = { + path = "/storage/music"; + id = "music"; + devices = [ "oci" ]; + versioning = { + type = "trashcan"; + params.cleanoutDays = "14"; + }; + }; + }; + activeFoldersSet = lib.filterAttrs (name: _: builtins.elem name cfg.activeFolders) allFolders; + + syncDirs = lib.mapAttrsToList (_: folder: folder.path) activeFoldersSet; in { - options.os.srv.syncthing.enable = lib.mkEnableOption "enables syncthing syncing"; + options.os.srv.syncthing = { + enable = lib.mkEnableOption "enables syncthing syncing"; + + activeFolders = lib.mkOption { + type = lib.types.listOf ( + lib.types.enum [ + "openmw-config" + "openmw-mods" + "game-saves" + "keepass" + "sync" + "music" + ] + ); + default = [ + "keepass" + "sync" + ]; + description = "List of Syncthing folders to enable and sync on this specific machine."; + }; + }; config = lib.mkIf cfg.enable { systemd.tmpfiles.rules = map (path: "d ${path} 0755 ${username} users -") syncDirs; @@ -23,89 +129,7 @@ in settings = { devices."oci".id = "DQXGVDC-KGPM6RK-5NDEBJJ-R7PEWYZ-N6Z3WFZ-TSVJG5X-235SHG4-4BEJNQJ"; - folders = { - "openmw-config" = { - path = "/home/${username}/.config/openmw"; - id = "openmw-config"; - devices = [ - { - name = "oci"; - encryptionPasswordFile = config.sops.secrets."syncthing/encryption/openmw-config".path; - } - ]; - versioning = { - type = "simple"; - params.keep = "3"; - }; - ignorePatterns = [ - "settings.cfg" - "*.log" - ]; - }; - - "openmw-mods" = { - path = "/home/${username}/games/openmw"; - id = "openmw-mods"; - devices = [ - { - name = "oci"; - encryptionPasswordFile = config.sops.secrets."syncthing/encryption/openmw-mods".path; - } - ]; - versioning = { - type = "trashcan"; - params.cleanoutDays = "7"; - }; - }; - - "game-saves" = { - path = "/home/${username}/.saves"; - id = "game-saves"; - devices = [ - { - name = "oci"; - encryptionPasswordFile = config.sops.secrets."syncthing/encryption/game-saves".path; - } - ]; - versioning = { - type = "staggered"; - params = { - cleanInterval = "3600"; - maxAge = "2592000"; - }; - }; - }; - - "keepass" = { - path = "/home/${username}/.keepass"; - id = "keepass"; - devices = [ - { - name = "oci"; - encryptionPasswordFile = config.sops.secrets."syncthing/encryption/keepass".path; - } - ]; - versioning = { - type = "simple"; - params.keep = "10"; - }; - }; - - "sync" = { - path = "/home/${username}/sync"; - id = "sync"; - devices = [ - { - name = "oci"; - encryptionPasswordFile = config.sops.secrets."syncthing/encryption/sync".path; - } - ]; - versioning = { - type = "simple"; - params.keep = "3"; - }; - }; - }; + folders = activeFoldersSet; }; }; }; diff --git a/os/srv/vpn.nix b/os/srv/vpn.nix deleted file mode 100644 index 28c7a9e..0000000 --- a/os/srv/vpn.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - cfg = config.os.srv.vpn; - netCfg = config.os.core.network; -in -{ - options.os.srv.vpn.enable = lib.mkEnableOption "enables vpn stuff"; - - config = lib.mkIf (cfg.enable && netCfg.enable) { - networking.networkmanager.ensureProfiles = { - environmentFiles = [ config.sops.secrets."vpn/warp_private_key".path ]; - profiles.cloudflare-warp = { - connection = { - id = "cloudflare-warp"; - type = "wireguard"; - interface-name = "wg0"; - autoconnect = false; - }; - wireguard = { - mtu = 1200; - private-key = "$WG_KEY"; - }; - "wireguard-peer.bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=" = { - endpoint = "engage.cloudflareclient.com:2408"; - allowed-ips = "0.0.0.0/0;::/0;"; - }; - ipv4 = { - method = "manual"; - address1 = "172.16.0.2/32"; - dns = "1.1.1.1;1.0.0.1;"; - }; - ipv6 = { - method = "manual"; - address1 = "2606:4700:110:84c7:36c4:e444:5efb:b108/128"; - dns = "2606:4700:4700::1111;2606:4700:4700::1001;"; - }; - }; - }; - environment.systemPackages = with pkgs; [ - wgcf - wireguard-tools - ]; - }; -} diff --git a/os/srv/wireguard.nix b/os/srv/wireguard.nix index 4b9dbc4..15675a4 100644 --- a/os/srv/wireguard.nix +++ b/os/srv/wireguard.nix @@ -1,9 +1,149 @@ -{ config, lib, ... }: +{ + config, + lib, + hostname, + masterDomain, + ... +}: let cfg = config.os.srv.wireguard; in { - options.os.srv.wireguard.enable = lib.mkEnableOption "enables wireguard vpn"; - config = lib.mkIf cfg.enable { + options.os.srv.wireguard = { + enable = lib.mkEnableOption "enables wireguard vpn"; + + role = lib.mkOption { + type = lib.types.enum [ + "server" + "client" + ]; + default = "client"; + description = "where the machine is accepting connections or connecting"; + }; + + server = { + externalInterface = lib.mkOption { + type = lib.types.str; + default = "eth0"; + description = "The public WAN interface of the server"; + }; + + peers = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + name = lib.mkOption { type = lib.types.str; }; + publicKey = lib.mkOption { type = lib.types.str; }; + }; + } + ); + default = [ ]; + description = "List of client peers authorized to connect to this server"; + }; + }; + + client = { + index = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = null; + description = "The assigned host index number for the client IP address"; + }; + + routeAllTraffic = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Routes 100% of your internet traffic through the server when active"; + }; + }; }; + + config = lib.mkIf cfg.enable ( + lib.mkMerge [ + { + assertions = [ + { + assertion = config.os.srv.sops.enable; + message = "required for wg private key"; + } + ]; + + sops.secrets."wg_private_key/${hostname}" = { + owner = "root"; + group = "root"; + mode = "0600"; + }; + } + + (lib.mkIf (cfg.role == "server") { + assertions = [ + { + assertion = config.os.srv.firewall.enable; + message = "required for opening ports and passthrough"; + } + ]; + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + networking.firewall.allowedUDPPorts = [ 51280 ]; + + networking.nftables = { + tables.wg-nat = { + family = "inet"; + content = '' + chain forward { + type filter hook forward priority 0; policy accept; + iifname "wg0" accept + oifname "wg0" accept + } + + chain postrouting { + type nat hook postrouting priority 100; policy accept; + iifname "wg0" oifname "${cfg.server.externalInterface}" masquerade + } + ''; + }; + }; + + networking.wireguard.interfaces.wg0 = { + ips = [ "10.255.1.1/16" ]; + listenPort = 51280; + privateKeyFile = config.sops.secrets."wg_private_key/${hostname}".path; + + peers = lib.imap1 (i: peer: { + publicKey = peer.publicKey; + allowedIPs = [ "10.255.0.${toString i}/32" ]; + persistentKeepalive = 25; + }) cfg.server.peers; + }; + }) + + (lib.mkIf (cfg.role == "client") { + assertions = [ + { + assertion = cfg.client.index != null; + message = "WireGuard client role requires a valid 'client.index' integer designation."; + } + ]; + + networking.nameservers = [ + "10.255.1.1" + "9.9.9.9" + ]; + + networking.wireguard.interfaces.wg0 = { + ips = [ "10.255.0.${toString cfg.client.index}/16" ]; + privateKeyFile = config.sops.secrets."wg_private_key/${hostname}".path; + + peers = [ + { + # TODO get the server public key + publicKey = ""; + endpoint = "${masterDomain}:51280"; + persistentKeepalive = 25; + + allowedIPs = if cfg.client.routeAllTraffic then [ "0.0.0.0/0" ] else [ "10.255.0.0/16" ]; + } + ]; + }; + }) + ] + ); } -- cgit v1.3