summaryrefslogtreecommitdiff
path: root/hosts/surtr/vpn
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2022-07-29 11:07:19 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2022-07-29 11:07:19 +0200
commitbda1a6b603a3944223707a6d090622b574ea7505 (patch)
treee223290d0c3e4f91862f429e65f083d3ecb3b1cd /hosts/surtr/vpn
parentece84e99219c1d57dcee7ee93045edc81cd0cbc7 (diff)
downloadnixos-bda1a6b603a3944223707a6d090622b574ea7505.tar
nixos-bda1a6b603a3944223707a6d090622b574ea7505.tar.gz
nixos-bda1a6b603a3944223707a6d090622b574ea7505.tar.bz2
nixos-bda1a6b603a3944223707a6d090622b574ea7505.tar.xz
nixos-bda1a6b603a3944223707a6d090622b574ea7505.zip
bump & vpn
Diffstat (limited to 'hosts/surtr/vpn')
-rw-r--r--hosts/surtr/vpn/default.nix177
-rw-r--r--hosts/surtr/vpn/geri.pub1
-rw-r--r--hosts/surtr/vpn/ruleset.nft189
-rw-r--r--hosts/surtr/vpn/surtr.priv26
-rw-r--r--hosts/surtr/vpn/surtr.pub1
5 files changed, 394 insertions, 0 deletions
diff --git a/hosts/surtr/vpn/default.nix b/hosts/surtr/vpn/default.nix
new file mode 100644
index 00000000..4f334105
--- /dev/null
+++ b/hosts/surtr/vpn/default.nix
@@ -0,0 +1,177 @@
1{ pkgs, config, lib, ... }:
2
3with lib;
4
5let
6 trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str;
7 prefix4 = "10.84.47";
8 prefix6 = "2a03:4000:52:ada:5";
9in {
10 config = {
11 boot.kernel.sysctl = {
12 "net.netfilter.nf_log_all_netns" = true;
13 };
14
15 networking.namespaces = {
16 enable = true;
17 containers."vpn".config = {
18 boot.kernel.sysctl = {
19 "net.core.rmem_max" = "4194304";
20 "net.core.wmem_max" = "4194304";
21 };
22
23 environment = {
24 noXlibs = true;
25 systemPackages = with pkgs; [ wireguard-tools ];
26 };
27
28 networking = {
29 useDHCP = false;
30 useNetworkd = true;
31 useHostResolvConf = false;
32 firewall.enable = false;
33 nftables = {
34 enable = true;
35 rulesetFile = ./ruleset.nft;
36 };
37 };
38
39 services.resolved.fallbackDns = [
40 "9.9.9.9#dns.quad9.net"
41 "149.112.112.112#dns.quad9.net"
42 "2620:fe::fe#dns.quad9.net"
43 "2620:fe::9#dns.quad9.net"
44 ];
45
46 systemd.tmpfiles.rules = [
47 "d /etc/wireguard 0755 root systemd-network - -"
48 "C /etc/wireguard/surtr.priv 0640 root systemd-network - /run/host/credentials/surtr.priv"
49 ];
50
51 systemd.network = {
52 netdevs = {
53 vpn = {
54 netdevConfig = {
55 Name = "vpn";
56 Kind = "wireguard";
57 };
58 wireguardConfig = {
59 PrivateKeyFile = "/etc/wireguard/surtr.priv";
60 ListenPort = 51820;
61 };
62 wireguardPeers = [
63 { wireguardPeerConfig = {
64 AllowedIPs = ["${prefix6}:1::/96" "${prefix4}.1/32"];
65 PublicKey = trim (readFile ./geri.pub);
66 };
67 }
68 ];
69 };
70 };
71
72 networks = {
73 upstream = {
74 name = "upstream";
75 matchConfig = {
76 Name = "upstream";
77 };
78 linkConfig = {
79 RequiredForOnline = true;
80 };
81 networkConfig = {
82 Address = [ "185.243.10.86/32" "2a03:4000:20:259::/64" ];
83 LLMNR = false;
84 MulticastDNS = false;
85 };
86 routes = [
87 { routeConfig = {
88 Destination = "202.61.240.0/22";
89 };
90 }
91 { routeConfig = {
92 Destination = "0.0.0.0/0";
93 Gateway = "202.61.240.1";
94 };
95 }
96 { routeConfig = {
97 Destination = "::/0";
98 Gateway = "fe80::1";
99 };
100 }
101 ];
102 extraConfig = ''
103 [Neighbor]
104 Address=202.61.240.1
105 LinkLayerAddress=00:00:5e:00:01:01
106 '';
107 };
108 vpn = {
109 name = "vpn";
110 matchConfig = {
111 Name = "vpn";
112 };
113 address = ["${prefix6}::/96" "${prefix4}.0/32"];
114 routes = [
115 { routeConfig = {
116 Destination = "${prefix6}::/80";
117 };
118 }
119 { routeConfig = {
120 Destination = "${prefix4}.0/24";
121 };
122 }
123 ];
124 linkConfig = {
125 RequiredForOnline = false;
126 };
127 networkConfig = {
128 LLMNR = false;
129 MulticastDNS = false;
130 };
131 };
132 };
133 };
134 };
135 };
136
137 systemd.services = {
138 "vpn-upstream" = {
139 bindsTo = ["netns@vpn.service"];
140 after = ["netns@vpn.service"];
141 serviceConfig = {
142 Type = "oneshot";
143 RemainAfterExit = true;
144 ExecStop = "${pkgs.iproute}/bin/ip netns exec vpn ip link delete upstream";
145 };
146 path = with pkgs; [ iproute procps ];
147 script = ''
148 ip netns exec vpn sysctl \
149 net.ipv6.conf.all.forwarding=1 \
150 net.ipv6.conf.default.forwarding=1 \
151 net.ipv4.conf.all.forwarding=1 \
152 net.ipv4.conf.default.forwarding=1
153
154 ip link add link ens3 name upstream type ipvlan mode l2
155 ip link set upstream netns vpn
156 '';
157 };
158
159 "netns-container@vpn" = {
160 wantedBy = ["multi-user.target" "network-online.target"];
161 after = ["vpn-upstream.service"];
162 bindsTo = ["vpn-upstream.service"];
163
164 serviceConfig = {
165 LoadCredential = [
166 "surtr.priv:${config.sops.secrets.vpn.path}"
167 ];
168 };
169 };
170 };
171
172 sops.secrets.vpn = {
173 format = "binary";
174 sopsFile = ./surtr.priv;
175 };
176 };
177}
diff --git a/hosts/surtr/vpn/geri.pub b/hosts/surtr/vpn/geri.pub
new file mode 100644
index 00000000..ed5de2b2
--- /dev/null
+++ b/hosts/surtr/vpn/geri.pub
@@ -0,0 +1 @@
sYuQSNZHzfegv8HRz71jnZm2nFLGeRnaGwVonhKUj2k=
diff --git a/hosts/surtr/vpn/ruleset.nft b/hosts/surtr/vpn/ruleset.nft
new file mode 100644
index 00000000..3cdb7a8a
--- /dev/null
+++ b/hosts/surtr/vpn/ruleset.nft
@@ -0,0 +1,189 @@
1define icmp_protos = {ipv6-icmp, icmp, igmp}
2
3table arp filter {
4 limit lim_arp {
5 rate over 50 mbytes/second burst 50 mbytes
6 }
7
8 counter arp-rx {}
9 counter arp-tx {}
10
11 counter arp-ratelimit-rx {}
12 counter arp-ratelimit-tx {}
13
14 chain input {
15 type filter hook input priority filter
16 policy accept
17
18 limit name lim_arp counter name arp-ratelimit-rx drop
19
20 counter name arp-rx
21 }
22
23 chain output {
24 type filter hook output priority filter
25 policy accept
26
27 limit name lim_arp counter name arp-ratelimit-tx drop
28
29 counter name arp-tx
30 }
31}
32
33table inet filter {
34 limit lim_reject {
35 rate over 1000/second burst 1000 packets
36 }
37
38 limit lim_icmp {
39 rate over 50 mbytes/second burst 50 mbytes
40 }
41
42 counter invalid-fw {}
43 counter fw-lo {}
44 counter fw-vpn {}
45 counter fw-upstream {}
46
47 counter icmp-ratelimit-upstream-fw {}
48 counter icmp-ratelimit-vpn-fw {}
49 counter icmp-ratelimit-established-fw {}
50
51 counter icmp-upstream-fw {}
52 counter icmp-vpn-fw {}
53 counter icmp-established-fw {}
54
55 counter reject-ratelimit-fw {}
56 counter reject-fw {}
57 counter reject-tcp-fw {}
58 counter reject-icmp-fw {}
59
60 counter drop-fw {}
61
62 counter invalid-rx {}
63
64 counter rx-lo {}
65 counter invalid-local4-rx {}
66 counter invalid-local6-rx {}
67
68 counter icmp-ratelimit-rx {}
69 counter icmp-rx {}
70
71 counter wg-rx {}
72
73 counter established-rx {}
74
75 counter reject-ratelimit-rx {}
76 counter reject-rx {}
77 counter reject-tcp-rx {}
78 counter reject-icmp-rx {}
79
80 counter drop-rx {}
81
82 counter tx-lo {}
83
84 counter icmp-ratelimit-tx {}
85 counter icmp-tx {}
86
87 counter wg-tx {}
88
89 counter tx {}
90
91 chain forward {
92 type filter hook forward priority filter
93 policy drop
94
95
96 ct state invalid log level debug prefix "vpn: drop invalid forward: " counter name invalid-fw drop
97
98
99 iifname lo counter name fw-lo accept
100
101 meta l4proto $icmp_protos iifname upstream limit name lim_icmp counter name icmp-ratelimit-upstream-fw drop
102 meta l4proto $icmp_protos iifname upstream counter name icmp-upstream-fw accept
103 meta l4proto $icmp_protos iifname vpn limit name lim_icmp counter name icmp-ratelimit-vpn-fw drop
104 meta l4proto $icmp_protos iifname vpn counter name icmp-vpn-fw accept
105 meta l4proto $icmp_protos ct state {established, related} limit name lim_icmp counter name icmp-ratelimit-established-fw drop
106 meta l4proto $icmp_protos ct state {established, related} counter name icmp-established-fw accept
107
108
109 iifname upstream oifname vpn ct state {established, related} counter name fw-vpn accept
110 iifname vpn oifname upstream counter name fw-upstream accept
111
112
113 limit name lim_reject log level debug prefix "vpn: drop forward: " counter name reject-ratelimit-fw drop
114 log level debug prefix "vpn: reject forward: " counter name reject-fw
115 meta l4proto tcp ct state new counter name reject-tcp-fw reject with tcp reset
116 ct state new counter name reject-icmp-fw reject
117
118
119 counter name drop-fw
120 }
121
122 chain input {
123 type filter hook input priority filter
124 policy drop
125
126
127 ct state invalid log level debug prefix "vpn: drop invalid input: " counter name invalid-rx drop
128
129
130 iifname lo counter name rx-lo accept
131 iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject
132 iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject
133
134 meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-rx drop
135 meta l4proto $icmp_protos counter name icmp-rx accept
136
137 udp dport 51820 counter name wg-rx accept
138
139 ct state {established, related} counter name established-rx accept
140
141
142 limit name lim_reject log level debug prefix "vpn: drop input: " counter name reject-ratelimit-rx drop
143 log level debug prefix "vpn: reject input: " counter name reject-rx
144 meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset
145 ct state new counter name reject-icmp-rx reject
146
147
148 counter name drop-rx
149 }
150
151 chain output {
152 type filter hook output priority filter
153 policy accept
154
155
156 oifname lo counter name tx-lo accept
157
158 meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-tx drop
159 meta l4proto $icmp_protos counter name icmp-tx accept
160
161
162 udp sport 51820 counter name wg-tx
163
164
165 counter name tx
166 }
167}
168
169table inet nat {
170 counter nat {}
171
172 chain postrouting {
173 type nat hook postrouting priority srcnat
174 policy accept
175
176 iifname vpn counter name nat masquerade
177 }
178}
179
180table ip mss_clamp {
181 counter mss-clamp {}
182
183 chain postrouting {
184 type filter hook postrouting priority mangle
185 policy accept
186
187 iifname vpn oifname upstream tcp flags & (syn|rst) == syn counter name mss-clamp tcp option maxseg size set rt mtu
188 }
189} \ No newline at end of file
diff --git a/hosts/surtr/vpn/surtr.priv b/hosts/surtr/vpn/surtr.priv
new file mode 100644
index 00000000..707287f5
--- /dev/null
+++ b/hosts/surtr/vpn/surtr.priv
@@ -0,0 +1,26 @@
1{
2 "data": "ENC[AES256_GCM,data:dhGFzsKjzYTfFwxrcCGTVPKQoy12RDLfIqdBcxO7/aib90w/yfTWBQP2zNRa,iv:71HbOJRbpzLxYWztxzvM/qJNLdJQckaZVDOIAl5UKjI=,tag:JjF2zr78zjI7RPXqQaHmyg==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2022-07-28T19:09:57Z",
10 "mac": "ENC[AES256_GCM,data:Q2179Mp3h/FXVzM1T5sRfci+mo/gCGfUm5824GBTbCzwIsTMjSpPz/wByg0WQJ/WB3wnns+VfCh+epqnKcP73KKUmNysGNJ9DH1hNukmTWMZEI309yLE/GgDs76xGyt9hXdHClq30qhKT17bXQ7Pq08c437vfSwSCcKoKOcr6Ls=,iv:u81NRHwKSKb7Nfz2gC1tjdYlfrFETjF/gEMGAha4Y7g=,tag:zdxYtbiKtY46MGP/nO8S5w==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2022-07-28T19:09:57Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdAa7ohlS2wGvuH11I4GvYZQmKbQVZUcwpV1XX6YMvLQV0w\n8fMshflTFWUnmHAR5ERg6ZpESFiAXAlkUMTLIZBhDTAN92jCu7+nnNFK1QgBVE07\n0lwBilABJT++m953o6ic4h/9yeyx5Wc6+XxS3d1Mc4qgNBzX/TBVEoKmuUgkHwET\nd0nftLYbKmICgCBgDgllWJLSOU4XSksmYIeMwiSpyNzv8oKz8u73SZz20rJ9kQ==\n=phWI\n-----END PGP MESSAGE-----\n",
15 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
16 },
17 {
18 "created_at": "2022-07-28T19:09:57Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DyFKFNkTVG5oSAQdAV4pW8CJP/QP0S/w5e7S/Xrox+Ix/NBvw2N2fWp+5FwAw\nATp3d/QGyk+vwuQpQj3zq/cEzrWrrq19Gl+UUjSyI2rkpUnxWboA2xICYVkb91Oz\n0lwBLu54X/3X5Nd2krPv+Qa7AWPBKF6BkE2PIjjrvPgyJ4/XiFzawJsILH37QPqs\n7PcrteF15UNR416omVNZoWpF3Tq/j4Jw+ewRhU9WjOXe2GO8/X9zjTD9fRrpIQ==\n=YtV+\n-----END PGP MESSAGE-----\n",
20 "fp": "7ED22F4AA7BB55728B643DC5471B7D88E4EF66F8"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.3"
25 }
26} \ No newline at end of file
diff --git a/hosts/surtr/vpn/surtr.pub b/hosts/surtr/vpn/surtr.pub
new file mode 100644
index 00000000..48edc8fc
--- /dev/null
+++ b/hosts/surtr/vpn/surtr.pub
@@ -0,0 +1 @@
99nWsdE/KJHfOZjmG5suUQSfIj6UBuxS5+zOL+ynYmU=