diff --git a/configuration/default.nix b/configuration/default.nix index dc05cd3..6c6f29a 100644 --- a/configuration/default.nix +++ b/configuration/default.nix @@ -16,9 +16,10 @@ ./services/backups.nix ./services/conduit.nix + ./services/fail2ban.nix ./services/foundryvtt.nix ./services/gitea.nix - ./services/metrics.nix + ./services/metrics ./services/nextcloud.nix ./services/webserver.nix ./services/wireguard.nix @@ -146,27 +147,6 @@ acceptTerms = true; }; - services.fail2ban = { - enable = true; - extraPackages = [pkgs.ipset]; - banaction = "iptables-ipset-proto6-allports"; - bantime-increment.enable = true; - - jails = { - nginx-botsearch = '' - enabled = true - logpath = /var/log/nginx/access.log - ''; - }; - - ignoreIP = [ - "127.0.0.0/8" - "10.0.0.0/8" - "172.16.0.0/12" - "192.168.0.0/16" - ]; - }; - # Remove some unneeded packages environment.defaultPackages = []; diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix new file mode 100644 index 0000000..032addb --- /dev/null +++ b/configuration/services/fail2ban.nix @@ -0,0 +1,46 @@ +{pkgs, ...}: { + services.fail2ban = { + enable = true; + extraPackages = [pkgs.ipset]; + banaction = "iptables-ipset-proto6-allports"; + bantime-increment.enable = true; + + jails = { + nginx-botsearch = '' + enabled = true + logpath = /var/log/nginx/access.log + ''; + }; + + ignoreIP = [ + "127.0.0.0/8" + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + ]; + }; + + # Allow metrics services to connect to the socket as well + users.groups.fail2ban = {}; + systemd.services.fail2ban.serviceConfig = { + RestrictAddressFamilies = [ + "AF_UNIX" # AF_INET and AF_INET6 are added by the generic config + ]; + + ExecStartPost = + "+" + + (pkgs.writeShellScript "fail2ban-post-start" '' + while ! [ -S /var/run/fail2ban/fail2ban.sock ]; do + sleep 1 + done + + while ! ${pkgs.netcat}/bin/nc -zU /var/run/fail2ban/fail2ban.sock; do + sleep 1 + done + + ${pkgs.coreutils}/bin/chown root:fail2ban /var/run/fail2ban /var/run/fail2ban/fail2ban.sock + ${pkgs.coreutils}/bin/chmod 660 /var/run/fail2ban/fail2ban.sock + ${pkgs.coreutils}/bin/chmod 710 /var/run/fail2ban + ''); + }; +} diff --git a/configuration/services/metrics.nix b/configuration/services/metrics/default.nix similarity index 76% rename from configuration/services/metrics.nix rename to configuration/services/metrics/default.nix index 51a654d..b563b14 100644 --- a/configuration/services/metrics.nix +++ b/configuration/services/metrics/default.nix @@ -7,6 +7,10 @@ domain = "metrics.${config.services.nginx.domain}"; yaml = pkgs.formats.yaml {}; in { + imports = [ + ./exporters.nix + ]; + services.victoriametrics.enable = true; services.grafana = { @@ -62,6 +66,26 @@ in { }; }; + services.prometheus.local-exporters = { + prometheus-fail2ban-exporter = rec { + enable = true; + after = ["fail2ban.service"]; + + port = 9191; + listenAddress = "127.0.0.1"; + + serviceConfig = { + Group = "fail2ban"; + + ExecStart = lib.concatStringsSep " " [ + "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter" + "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock" + "--web.listen-address='${listenAddress}:${toString port}'" + ]; + }; + }; + }; + systemd.services.export-to-victoriametrics = let promscrape = yaml.generate "prometheus.yml" { scrape_configs = [ @@ -72,7 +96,7 @@ in { targets = lib.mapAttrsToList (name: exporter: "${exporter.listenAddress}:${toString exporter.port}") (lib.filterAttrs (name: exporter: (builtins.isAttrs exporter) && exporter.enable) - config.services.prometheus.exporters); + (config.services.prometheus.exporters // config.services.prometheus.local-exporters)); } ]; } diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix new file mode 100644 index 0000000..7f5dd20 --- /dev/null +++ b/configuration/services/metrics/exporters.nix @@ -0,0 +1,45 @@ +{ + config, + lib, + ... +}: { + options.services.prometheus.local-exporters = lib.mkOption { + type = lib.types.anything; + }; + + config.systemd.services = lib.mapAttrs (_: exporter: + lib.mkMerge [ + { + wantedBy = ["multi-user.target"]; + after = ["network.target"]; + + serviceConfig = { + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = "/tmp"; + DynamicUser = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NonNewPrivileges = true; + PrivateDevices = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + }; + } + (removeAttrs exporter ["port" "listenAddress"]) + ]) + config.services.prometheus.local-exporters; +} diff --git a/flake.nix b/flake.nix index b6db610..d8ff1a8 100644 --- a/flake.nix +++ b/flake.nix @@ -78,7 +78,7 @@ # Utility scripts # ################### packages.${system} = let - inherit (nixpkgs.legacyPackages.${system}) writeShellScript; + inherit (nixpkgs.legacyPackages.${system}) writeShellScript writeShellScriptBin; vm = nixpkgs.lib.nixosSystem { inherit system; specialArgs.flake-inputs = inputs; @@ -106,6 +106,14 @@ "${vm.config.system.build.vm}/bin/run-tlaternet-vm" ''; + update-pkgs = let + nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher"; + in + writeShellScriptBin "update-pkgs" '' + cd "$(git rev-parse --show-toplevel)/pkgs" + ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml + ''; + update-nextcloud-apps = let nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher"; in diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json new file mode 100644 index 0000000..b3faf9a --- /dev/null +++ b/pkgs/_sources_pkgs/generated.json @@ -0,0 +1,21 @@ +{ + "prometheus-fail2ban-exporter": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "prometheus-fail2ban-exporter", + "passthru": null, + "pinned": false, + "src": { + "deepClone": false, + "fetchSubmodules": false, + "leaveDotGit": false, + "name": null, + "rev": "v0.10.0", + "sha256": "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4=", + "type": "git", + "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter" + }, + "version": "v0.10.0" + } +} \ No newline at end of file diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix new file mode 100644 index 0000000..bb015b4 --- /dev/null +++ b/pkgs/_sources_pkgs/generated.nix @@ -0,0 +1,16 @@ +# This file was generated by nvfetcher, please do not modify it manually. +{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }: +{ + prometheus-fail2ban-exporter = { + pname = "prometheus-fail2ban-exporter"; + version = "v0.10.0"; + src = fetchgit { + url = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"; + rev = "v0.10.0"; + fetchSubmodules = false; + deepClone = false; + leaveDotGit = false; + sha256 = "sha256-8nIW1XaHCBqQCoLkV1ZYE3NTbVZ6c+UOqYD08XQiv+4="; + }; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix index 3818a26..3130ae0 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -7,6 +7,9 @@ in { starbound = callPackage ./starbound {}; + prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix { + sources = pkgs.callPackage ./_sources_pkgs/generated.nix {}; + }; } // ( # Add nextcloud apps diff --git a/pkgs/nvfetcher.toml b/pkgs/nvfetcher.toml new file mode 100644 index 0000000..8c53200 --- /dev/null +++ b/pkgs/nvfetcher.toml @@ -0,0 +1,3 @@ +[prometheus-fail2ban-exporter] +src.manual = "v0.10.0" # No gitlab support in nvfetcher +fetch.git = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter" diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix new file mode 100644 index 0000000..50b4973 --- /dev/null +++ b/pkgs/prometheus/fail2ban-exporter.nix @@ -0,0 +1,8 @@ +{ + buildGoModule, + sources, +}: +buildGoModule { + inherit (sources.prometheus-fail2ban-exporter) pname src version; + vendorHash = "sha256-qU6opwhhvzbQOhfGVyiVgKhfCSB0Z4eSRAJnv6ht2I0="; +}