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.
Martin Weinelt committed
Aug 25, 2025 at 18:10 UTC
ab1c3bdfb089183fa962b03e130b97ef7631949f
4 files changed
+108
build/mimas/default.nix
+1
@@ -4,6 +4,7 @@
4
../hydra.nix
5
../hydra-proxy.nix
6
./boot.nix
7
+ ./firewall.nix
8
./network.nix
9
];
10
build/mimas/firewall.nix
new
+81
@@ -0,0 +1,81 @@
1
+{
2
+ pkgs,
3
+ lib,
4
+ inputs,
5
+ ...
6
+}:
7
+
8
+let
9
+ blockedAutNums = [
10
+ 45102 # ALIBABA-CN-NET
11
+ 132203 # TENCENT-NET-AP-CN
12
+ ];
13
+in
14
+
15
+{
16
+ networking.nftables = {
17
+ tables."abuse" = {
18
+ family = "inet";
19
+ content = ''
20
+ set ipv4blocks {
21
+ type ipv4_addr;
22
+ flags interval;
23
+ auto-merge;
24
+ }
25
+ set ipv6blocks {
26
+ type ipv6_addr;
27
+ auto-merge;
28
+ flags interval;
29
+ }
30
+ chain input-abuse {
31
+ type filter hook input priority filter - 5;
32
+
33
+ ip saddr @ipv4blocks tcp dport 443 counter drop;
34
+ ip6 saddr @ipv6blocks tcp dport 443 counter drop;
35
+ }
36
+ '';
37
+ };
38
+ };
39
+
40
+ systemd.services.nft-prefix-import = {
41
+ wants = [ "network-online.target" ];
42
+ after = [ "network-online.target" ];
43
+ wantedBy = [ "multi-user.target" ];
44
+ path = with pkgs; [ nftables ];
45
+ environment.USER_AGENT = "NixOS.org Infrastructure - infra@nixos.org";
46
+ serviceConfig = {
47
+ Type = "oneshot";
48
+ AmbientCapabilities = [ "CAP_NET_ADMIN" ];
49
+ DynamicUser = true;
50
+ User = "nft-asblock";
51
+ Group = "nft-asblock";
52
+ ExecStart = toString (
53
+ [
54
+ (lib.getExe inputs.nft-prefix-import.packages.${pkgs.hostPlatform.system}.default)
55
+ "--table"
56
+ "abuse"
57
+ "--ipv4set"
58
+ "ipv4blocks"
59
+ "--ipv6set"
60
+ "ipv6blocks"
61
+ ]
62
+ ++ blockedAutNums
63
+ );
64
+ RestrictAddressFamilies = [
65
+ "AF_NETLINK"
66
+ "AF_INET"
67
+ "AF_INET6"
68
+ ];
69
+ StateDirectory = "nft-prefix-import";
70
+ WorkingDirectory = "/var/lib/nft-prefix-import";
71
+ };
72
+ };
73
+
74
+ systemd.timers.nft-prefix-import = {
75
+ wantedBy = [ "timers.target" ];
76
+ timerConfig = {
77
+ OnCalendar = "0/6:00";
78
+ RandomizedDelaySec = 3600;
79
+ };
80
+ };
81
+}
flake.lock
+21
@@ -314,6 +314,26 @@
314
"type": "github"
315
}
316
},
317
+ "nft-prefix-import": {
318
+ "inputs": {
319
+ "nixpkgs": [
320
+ "nixpkgs-unstable"
321
+ ]
322
+ },
323
+ "locked": {
324
+ "lastModified": 1757887817,
325
+ "narHash": "sha256-LAwCjMvMwKTIdOaqsNhHm/2URd1cBds013lDRc8CarM=",
326
+ "owner": "mweinelt",
327
+ "repo": "nft-prefix-import",
328
+ "rev": "8dafafa3eb9834e414b60490eb08ed905715b3a0",
329
+ "type": "github"
330
+ },
331
+ "original": {
332
+ "owner": "mweinelt",
333
+ "repo": "nft-prefix-import",
334
+ "type": "github"
335
+ }
336
+ },
337
"nix": {
338
"flake": false,
339
"locked": {
@@ -470,6 +490,7 @@
490
"flake-utils": "flake-utils",
491
"freescout": "freescout",
492
"hydra": "hydra",
493
+ "nft-prefix-import": "nft-prefix-import",
494
"nixos-channel-scripts": "nixos-channel-scripts",
495
"nixpkgs": "nixpkgs",
496
"nixpkgs-swh": "nixpkgs-swh",
flake.nix
+5
@@ -70,6 +70,11 @@
70
inputs.nixpkgs.follows = "nixpkgs";
71
};
72
73
+ nft-prefix-import = {
74
+ url = "github:mweinelt/nft-prefix-import";
75
+ inputs.nixpkgs.follows = "nixpkgs-unstable";
76
+ };
77
+
78
srvos = {
79
url = "github:numtide/srvos";
80
inputs.nixpkgs.follows = "nixpkgs";