{ pkgs, lib, name, my-projects-versions, networkingConfig, nixpkgs-path, ... }: let pretense = import (pkgs.fetchFromGitHub my-projects-versions.pretense.fetchFromGitHub); quotdd = import (pkgs.fetchFromGitHub my-projects-versions.quotdd.fetchFromGitHub); in { deployment.targetHost = "${name}.infra.noratrieb.dev"; # TODO: ensure that the rust programs have frame pointers networking.hosts = { "${networkingConfig.vps3.wg.privateIP}" = [ "loki.internal" "pyroscope.internal" "prometheus.internal" ]; }; imports = [ "${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/9edb1787864c4f59ae5074ad498b6272b3ec308d.tar.gz"}/modules/age.nix" # main 2025-08-07 ]; nix = { nixPath = [ "nixpkgs=${nixpkgs-path}" ]; }; environment.systemPackages = with pkgs; [ vim wget curl traceroute dnsutils nftables ]; networking.hostName = name; time.timeZone = "Europe/Zurich"; users.users.root.openssh.authorizedKeys.keys = [ ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG0n1ikUG9rYqobh7WpAyXrqZqxQoQ2zNJrFPj12gTpP nilsh@PC-Nils'' ]; boot.tmp.cleanOnBoot = true; zramSwap.enable = true; services.openssh = { enable = true; openFirewall = true; banner = "meoooooow!! 😼 :3\n"; hostKeys = [ { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; } { # P256 path = "/etc/ssh/ssh_host_ecdsa_key"; type = "ecdsa"; } { bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; } ]; settings = { PasswordAuthentication = false; AllowUsers = [ "root" ]; }; }; services.fail2ban = { enable = true; }; system.nixos.distroName = "NixOS (gay 🏳️‍⚧️)"; systemd.services.pretense = { description = "pretense connection logger"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { DynamicUser = true; ExecStart = "${lib.getExe (pretense {inherit pkgs;})}"; AmbientCapabilities = "CAP_NET_BIND_SERVICE"; Environment = [ "PRETENSE_PORTS=23,3306,5432,1521" # telnet,mysql,postgres,oracle "PRETENSE_METRICS_PORT=9150" ]; PrivateDevices = true; ProtectHome = true; ProtectClock = true; ProtectKernelLogs = true; ProtectHostname = true; ProtectKernelTunables = true; CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; ProtectProc = "ptraceable"; RestrictNamespaces = true; MemoryDenyWriteExecute = true; ProtectControlGroups = true; ProtectKernelModules = true; SystemCallArchitectures = ""; SystemCallFilter = "@system-service"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; ProtectSystem = "strict"; }; }; systemd.services.quotdd = { description = "quotdd Quote of The Day Daemon"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { DynamicUser = true; ExecStart = "${lib.getExe (quotdd {inherit pkgs;})}"; AmbientCapabilities = "CAP_NET_BIND_SERVICE"; Environment = [ ]; PrivateDevices = true; ProtectHome = true; ProtectClock = true; ProtectKernelLogs = true; ProtectHostname = true; ProtectKernelTunables = true; CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; ProtectProc = "ptraceable"; RestrictNamespaces = true; MemoryDenyWriteExecute = true; ProtectControlGroups = true; ProtectKernelModules = true; SystemCallArchitectures = ""; SystemCallFilter = "@system-service"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; ProtectSystem = "strict"; }; }; networking.firewall.allowedTCPPorts = [ 23 # telnet, pretense 3306 # mysql, pretense 5432 # postgres, pretense 1521 # oracle, pretense 17 # quote of the day, quotdd ]; # monitoring networking.firewall.interfaces.wg0.allowedTCPPorts = [ 8080 # cadvisor exporter 9100 # node exporter 9150 # pretense exporter 9558 # systemd exporter ]; services.prometheus.exporters = { node = { enable = true; }; systemd = { enable = true; }; }; services.cadvisor = { enable = true; listenAddress = "0.0.0.0"; extraOptions = [ # significantly decreases CPU usage (https://github.com/google/cadvisor/issues/2523) "--housekeeping_interval=30s" ]; }; services.promtail = { enable = true; configuration = { server = { disable = true; }; clients = [ { url = "http://loki.internal:3100/loki/api/v1/push"; } ]; scrape_configs = [ { job_name = "journal"; journal = { max_age = "24h"; labels = { job = "systemd-journal"; node = name; }; }; pipeline_stages = [{ match = { selector = "{unit = \"sshd.service\"} |= \"Invalid user\""; stages = [ { regex = { expression = "Invalid user.*from (?P.*) port.*"; }; } { geoip = { db = pkgs.fetchurl { # Note: You cannot use this for your own usage, this is only for me. url = "https://github.com/noratrieb-mirrors/maxmind-geoip/releases/download/20240922/GeoLite2-City.mmdb"; sha256 = "sha256-xRGf2JEaEHpxEkIq3jJnZv49lTisFbygbjxiIZHIThg="; }; source = "ip"; db_type = "city"; }; } ]; }; }]; relabel_configs = [ { source_labels = [ "__journal__systemd_unit" ]; target_label = "unit"; } { source_labels = [ "__journal__hostname" ]; target_label = "host"; } { source_labels = [ "__journal_priority_keyword" ]; target_label = "severity"; regex = "(.+)"; } ]; } ]; }; }; services.alloy = { enable = true; }; systemd.services.alloy.serviceConfig = { DynamicUser = lib.mkForce false; PrivateDevices = true; ProtectClock = true; ProtectKernelLogs = true; PrivateMounts = true; ProtectControlGroups = true; ProtectHostname = true; LockPersonality = true; ProtectKernelTunables = true; ProtectSystem = true; ProtectHome = true; PrivateTmp = true; NoNewPrivileges = true; RestrictNamespaces = ""; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; # TODO: find what's required for /proc/kallsyms (it should be CAP_SYSLOG!) # CapabilityBoundingSet = "CAP_SYS_PTRACE CAP_BPF CAP_SYSLOG"; }; environment.etc."alloy/config.alloy".text = '' discovery.process "all" { discover_config { cgroup_path = true container_id = true } } discovery.relabel "alloy" { targets = discovery.process.all.targets // Filter needed processes rule { source_labels = ["__meta_process_cgroup_path"] regex = "0::/system.slice/.*.service" action = "keep" } rule { source_labels = ["__meta_process_cgroup_path"] regex = "0::/system.slice/(.*.service)" target_label = "service_name" action = "replace" } } pyroscope.ebpf "instance" { forward_to = [pyroscope.write.endpoint.receiver] targets = discovery.relabel.alloy.output } pyroscope.write "endpoint" { endpoint { url = "http://pyroscope.internal:4040" } external_labels = { "instance" = env("HOSTNAME"), } } ''; deployment.tags = networkingConfig."${name}".tags; }