From ab1c3bdfb089183fa962b03e130b97ef7631949f Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Mon, 25 Aug 2025 18:10:04 +0200 Subject: [PATCH] mimas: block alibaba and tencent These networks keep scraping hydra.nixos.org with a high request rate across a wide range of IP addresses with bogus user-agents. They did it, they made me develop a tool to lookup prefixes for an AS and block them from accessing tcp/443 using an nftable set match. --- build/mimas/default.nix | 1 + build/mimas/firewall.nix | 81 ++++++++++++++++++++++++++++++++++++++++ flake.lock | 21 +++++++++++ flake.nix | 5 +++ 4 files changed, 108 insertions(+) create mode 100644 build/mimas/firewall.nix diff --git a/build/mimas/default.nix b/build/mimas/default.nix index 33faf6c3..4694e7f5 100644 --- a/build/mimas/default.nix +++ b/build/mimas/default.nix @@ -4,6 +4,7 @@ ../hydra.nix ../hydra-proxy.nix ./boot.nix + ./firewall.nix ./network.nix ]; diff --git a/build/mimas/firewall.nix b/build/mimas/firewall.nix new file mode 100644 index 00000000..5a6f12ed --- /dev/null +++ b/build/mimas/firewall.nix @@ -0,0 +1,81 @@ +{ + pkgs, + lib, + inputs, + ... +}: + +let + blockedAutNums = [ + 45102 # ALIBABA-CN-NET + 132203 # TENCENT-NET-AP-CN + ]; +in + +{ + networking.nftables = { + tables."abuse" = { + family = "inet"; + content = '' + set ipv4blocks { + type ipv4_addr; + flags interval; + auto-merge; + } + set ipv6blocks { + type ipv6_addr; + auto-merge; + flags interval; + } + chain input-abuse { + type filter hook input priority filter - 5; + + ip saddr @ipv4blocks tcp dport 443 counter drop; + ip6 saddr @ipv6blocks tcp dport 443 counter drop; + } + ''; + }; + }; + + systemd.services.nft-prefix-import = { + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ nftables ]; + environment.USER_AGENT = "NixOS.org Infrastructure - infra@nixos.org"; + serviceConfig = { + Type = "oneshot"; + AmbientCapabilities = [ "CAP_NET_ADMIN" ]; + DynamicUser = true; + User = "nft-asblock"; + Group = "nft-asblock"; + ExecStart = toString ( + [ + (lib.getExe inputs.nft-prefix-import.packages.${pkgs.hostPlatform.system}.default) + "--table" + "abuse" + "--ipv4set" + "ipv4blocks" + "--ipv6set" + "ipv6blocks" + ] + ++ blockedAutNums + ); + RestrictAddressFamilies = [ + "AF_NETLINK" + "AF_INET" + "AF_INET6" + ]; + StateDirectory = "nft-prefix-import"; + WorkingDirectory = "/var/lib/nft-prefix-import"; + }; + }; + + systemd.timers.nft-prefix-import = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "0/6:00"; + RandomizedDelaySec = 3600; + }; + }; +} diff --git a/flake.lock b/flake.lock index db25bcfe..ce168dc5 100644 --- a/flake.lock +++ b/flake.lock @@ -314,6 +314,26 @@ "type": "github" } }, + "nft-prefix-import": { + "inputs": { + "nixpkgs": [ + "nixpkgs-unstable" + ] + }, + "locked": { + "lastModified": 1757887817, + "narHash": "sha256-LAwCjMvMwKTIdOaqsNhHm/2URd1cBds013lDRc8CarM=", + "owner": "mweinelt", + "repo": "nft-prefix-import", + "rev": "8dafafa3eb9834e414b60490eb08ed905715b3a0", + "type": "github" + }, + "original": { + "owner": "mweinelt", + "repo": "nft-prefix-import", + "type": "github" + } + }, "nix": { "flake": false, "locked": { @@ -470,6 +490,7 @@ "flake-utils": "flake-utils", "freescout": "freescout", "hydra": "hydra", + "nft-prefix-import": "nft-prefix-import", "nixos-channel-scripts": "nixos-channel-scripts", "nixpkgs": "nixpkgs", "nixpkgs-swh": "nixpkgs-swh", diff --git a/flake.nix b/flake.nix index 187766d9..6a9384d7 100644 --- a/flake.nix +++ b/flake.nix @@ -70,6 +70,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + nft-prefix-import = { + url = "github:mweinelt/nft-prefix-import"; + inputs.nixpkgs.follows = "nixpkgs-unstable"; + }; + srvos = { url = "github:numtide/srvos"; inputs.nixpkgs.follows = "nixpkgs";