Skip to content

Commit 40205ea

Browse files
Fix firewall4 fullcone
Add firewall4 fullcone6 support (NAT66, NOT recommended) Rework cgroup2 mounting odhcp6c: support dhcpv6 hotplug Co-authored-by: QiuSimons <45143996+QiuSimons@users.noreply.github.com> Signed-off-by: Nicholas Sun <nicholas-sun@outlook.com>
1 parent d8ef0ce commit 40205ea

12 files changed

Lines changed: 972 additions & 57 deletions

PATCH/cgroupfs-mount/0001-fix-cgroupfs-mount.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ index 0d6b68d..4ae3185 100755
2222

2323
- cgroupfs-mount
2424
+ umount_cgroup
25-
+ cgroupfs-mount v2
25+
+ cgroupfs-mount
2626
}

PATCH/cgroupfs-mount/900-add-cgroupfs2.patch

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
From 3855430e665c09b8b36d177a39245d0a69453397 Mon Sep 17 00:00:00 2001
2+
From: sbwml <admin@cooluc.com>
3+
Date: Wed, 23 Aug 2023 20:10:30 +0800
4+
Subject: [PATCH 1/2] mount cgroup v2 hierarchy to /sys/fs/cgroup/cgroup2
5+
6+
---
7+
cgroupfs-mount | 6 ++++++
8+
1 file changed, 6 insertions(+)
9+
10+
diff --git a/cgroupfs-mount b/cgroupfs-mount
11+
index 40810ba..114f7a1 100755
12+
--- a/cgroupfs-mount
13+
+++ b/cgroupfs-mount
14+
@@ -41,6 +41,12 @@ for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
15+
fi
16+
done
17+
18+
+# mount cgroup v2 hierarchy to /sys/fs/cgroup/cgroup2 if kernel support cgroup2 filesystem
19+
+if grep -q cgroup2 /proc/filesystems; then
20+
+ mkdir -p /sys/fs/cgroup/cgroup2
21+
+ mount -t cgroup2 -o rw,nosuid,nodev,noexec,relatime,nsdelegate cgroup2 /sys/fs/cgroup/cgroup2
22+
+fi
23+
+
24+
# example /proc/cgroups:
25+
# #subsys_name hierarchy num_cgroups enabled
26+
# cpuset 2 3 1
27+
--
28+
2.34.8
29+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
From 712d45f93d6d499f8c6e6da44084ed2bfdae1605 Mon Sep 17 00:00:00 2001
2+
From: sbwml <admin@cooluc.com>
3+
Date: Wed, 23 Aug 2023 20:11:57 +0800
4+
Subject: [PATCH 2/2] fix cgroupfs-umount
5+
6+
---
7+
cgroupfs-umount | 5 ++++-
8+
1 file changed, 4 insertions(+), 1 deletion(-)
9+
10+
diff --git a/cgroupfs-umount b/cgroupfs-umount
11+
index ac26b6b..5b4c86e 100755
12+
--- a/cgroupfs-umount
13+
+++ b/cgroupfs-umount
14+
@@ -24,8 +24,11 @@ for sys in *; do
15+
umount $sys
16+
fi
17+
if [ -d $sys ]; then
18+
- rmdir $sys || true
19+
+ rm -rf $sys || true
20+
fi
21+
done
22+
23+
+cd /
24+
+umount /sys/fs/cgroup || true
25+
+
26+
exit 0
27+
--
28+
2.34.8
29+
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
From d4081c498ddca184578903fe5199d390bbc0707b Mon Sep 17 00:00:00 2001
2+
From: Syrone Wong <wong.syrone@gmail.com>
3+
Date: Sat, 9 Apr 2022 13:24:19 +0800
4+
Subject: [PATCH] firewall4: add fullcone support
5+
6+
fullcone is drop-in replacement of masq for non-udp traffic
7+
8+
add runtime fullcone rule check, disable it globally if fullcone expr is
9+
invalid
10+
11+
defaults.fullcone is the global switch, while zone.fullcone4 and
12+
zone.fullcone6 are switches for IPv4 and IPv6 respectively, most
13+
IPv6 traffic do NOT need this FullCone NAT functionality.
14+
---
15+
root/etc/config/firewall | 3 +
16+
root/usr/share/firewall4/templates/ruleset.uc | 16 +++-
17+
.../firewall4/templates/zone-fullcone.uc | 4 +
18+
root/usr/share/ucode/fw4.uc | 76 ++++++++++++++++++-
19+
4 files changed, 96 insertions(+), 3 deletions(-)
20+
create mode 100644 root/usr/share/firewall4/templates/zone-fullcone.uc
21+
22+
diff --git a/root/etc/config/firewall b/root/etc/config/firewall
23+
index b9a4647..7187723 100644
24+
--- a/root/etc/config/firewall
25+
+++ b/root/etc/config/firewall
26+
@@ -5,6 +5,7 @@ config defaults
27+
option forward REJECT
28+
# Uncomment this line to disable ipv6 rules
29+
# option disable_ipv6 1
30+
+ option fullcone '1'
31+
32+
config zone
33+
option name lan
34+
@@ -20,6 +21,8 @@ config zone
35+
option input REJECT
36+
option output ACCEPT
37+
option forward REJECT
38+
+ option fullcone4 '1'
39+
+ option fullcone6 '0'
40+
option masq 1
41+
option mtu_fix 1
42+
43+
diff --git a/root/usr/share/firewall4/templates/ruleset.uc b/root/usr/share/firewall4/templates/ruleset.uc
44+
index eaa1f04..e29eae6 100644
45+
--- a/root/usr/share/firewall4/templates/ruleset.uc
46+
+++ b/root/usr/share/firewall4/templates/ruleset.uc
47+
@@ -310,6 +310,12 @@ table inet fw4 {
48+
{% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %}
49+
{%+ include("redirect.uc", { fw4, redirect }) %}
50+
{% endfor %}
51+
+{% if (zone.fullcone4): %}
52+
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %}
53+
+{% endif %}
54+
+{% if (zone.fullcone6): %}
55+
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "dstnat" }) %}
56+
+{% endif %}
57+
{% fw4.includes('chain-append', `dstnat_${zone.name}`) %}
58+
}
59+
60+
@@ -320,20 +326,26 @@ table inet fw4 {
61+
{% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %}
62+
{%+ include("redirect.uc", { fw4, redirect }) %}
63+
{% endfor %}
64+
-{% if (zone.masq): %}
65+
+{% if (zone.masq && !zone.fullcone4): %}
66+
{% for (let saddrs in zone.masq4_src_subnets): %}
67+
{% for (let daddrs in zone.masq4_dest_subnets): %}
68+
{%+ include("zone-masq.uc", { fw4, zone, family: 4, saddrs, daddrs }) %}
69+
{% endfor %}
70+
{% endfor %}
71+
{% endif %}
72+
-{% if (zone.masq6): %}
73+
+{% if (zone.masq6 && !zone.fullcone6): %}
74+
{% for (let saddrs in zone.masq6_src_subnets): %}
75+
{% for (let daddrs in zone.masq6_dest_subnets): %}
76+
{%+ include("zone-masq.uc", { fw4, zone, family: 6, saddrs, daddrs }) %}
77+
{% endfor %}
78+
{% endfor %}
79+
{% endif %}
80+
+{% if (zone.fullcone4): %}
81+
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %}
82+
+{% endif %}
83+
+{% if (zone.fullcone6): %}
84+
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "srcnat" }) %}
85+
+{% endif %}
86+
{% fw4.includes('chain-append', `srcnat_${zone.name}`) %}
87+
}
88+
89+
diff --git a/root/usr/share/firewall4/templates/zone-fullcone.uc b/root/usr/share/firewall4/templates/zone-fullcone.uc
90+
new file mode 100644
91+
index 0000000..77d9806
92+
--- /dev/null
93+
+++ b/root/usr/share/firewall4/templates/zone-fullcone.uc
94+
@@ -0,0 +1,4 @@
95+
+{# /usr/share/firewall4/templates/zone-fullcone.uc #}
96+
+ meta nfproto {{ fw4.nfproto(family) }} fullcone comment "!fw4: Handle {{
97+
+ zone.name
98+
+}} {{ fw4.nfproto(family, true) }} fullcone NAT {{ direction }} traffic"
99+
diff --git a/root/usr/share/ucode/fw4.uc b/root/usr/share/ucode/fw4.uc
100+
index 1b4764c..c5716da 100644
101+
--- a/root/usr/share/ucode/fw4.uc
102+
+++ b/root/usr/share/ucode/fw4.uc
103+
@@ -1,3 +1,5 @@
104+
+// /usr/share/ucode/fw4.uc
105+
+
106+
const fs = require("fs");
107+
const uci = require("uci");
108+
const ubus = require("ubus");
109+
@@ -428,6 +430,25 @@ function nft_try_hw_offload(devices) {
110+
return (rc == 0);
111+
}
112+
113+
+function nft_try_fullcone() {
114+
+ let nft_test =
115+
+ 'add table inet fw4-fullcone-test; ' +
116+
+ 'add chain inet fw4-fullcone-test dstnat { ' +
117+
+ 'type nat hook prerouting priority -100; policy accept; ' +
118+
+ 'fullcone; ' +
119+
+ '}; ' +
120+
+ 'add chain inet fw4-fullcone-test srcnat { ' +
121+
+ 'type nat hook postrouting priority -100; policy accept; ' +
122+
+ 'fullcone; ' +
123+
+ '}; ';
124+
+ let cmd = sprintf("/usr/sbin/nft -c '%s' 2>/dev/null", replace(nft_test, "'", "'\\''"));
125+
+ let ok = system(cmd) == 0;
126+
+ if (!ok) {
127+
+ warn("nft_try_fullcone: cmd "+ cmd + "\n");
128+
+ }
129+
+ return ok;
130+
+}
131+
+
132+
133+
return {
134+
read_kernel_version: function() {
135+
@@ -765,6 +786,18 @@ return {
136+
warn(`[!] ${msg}\n`);
137+
},
138+
139+
+ myinfo: function(fmt, ...args) {
140+
+ if (getenv("QUIET"))
141+
+ return;
142+
+
143+
+ let msg = sprintf(fmt, ...args);
144+
+
145+
+ if (getenv("TTY"))
146+
+ warn(`\033[32m${msg}\033[m\n`);
147+
+ else
148+
+ warn(`[I] ${msg}\n`);
149+
+ },
150+
+
151+
get: function(sid, opt) {
152+
return this.cursor.get("firewall", sid, opt);
153+
},
154+
@@ -946,6 +979,21 @@ return {
155+
}
156+
},
157+
158+
+ myinfo_section: function(s, msg) {
159+
+ if (s[".name"]) {
160+
+ if (s.name)
161+
+ this.myinfo("Section %s (%s) %s", this.section_id(s[".name"]), s.name, msg);
162+
+ else
163+
+ this.myinfo("Section %s %s", this.section_id(s[".name"]), msg);
164+
+ }
165+
+ else {
166+
+ if (s.name)
167+
+ this.myinfo("ubus %s (%s) %s", s.type || "rule", s.name, msg);
168+
+ else
169+
+ this.myinfo("ubus %s %s", s.type || "rule", msg);
170+
+ }
171+
+ },
172+
+
173+
parse_policy: function(val) {
174+
return this.parse_enum(val, [
175+
"accept",
176+
@@ -1385,6 +1433,7 @@ return {
177+
"dnat",
178+
"snat",
179+
"masquerade",
180+
+ "fullcone",
181+
"accept",
182+
"reject",
183+
"drop"
184+
@@ -1852,6 +1901,7 @@ return {
185+
}
186+
187+
let defs = this.parse_options(data, {
188+
+ fullcone: [ "bool", "0" ],
189+
input: [ "policy", "drop" ],
190+
output: [ "policy", "drop" ],
191+
forward: [ "policy", "drop" ],
192+
@@ -1884,6 +1934,11 @@ return {
193+
194+
delete defs.syn_flood;
195+
196+
+ if (!nft_try_fullcone()) {
197+
+ delete defs.fullcone;
198+
+ warn("nft_try_fullcone failed, disable fullcone globally\n");
199+
+ }
200+
+
201+
this.state.defaults = defs;
202+
},
203+
204+
@@ -1908,6 +1963,8 @@ return {
205+
masq_dest: [ "network", null, PARSE_LIST ],
206+
207+
masq6: [ "bool" ],
208+
+ fullcone4: [ "bool", "0" ],
209+
+ fullcone6: [ "bool", "0" ],
210+
211+
extra: [ "string", null, UNSUPPORTED ],
212+
extra_src: [ "string", null, UNSUPPORTED ],
213+
@@ -1940,6 +1997,18 @@ return {
214+
}
215+
}
216+
217+
+ if (this.state.defaults && !this.state.defaults.fullcone) {
218+
+ this.warn_section(data, "fullcone in defaults not enabled, ignore zone fullcone settings");
219+
+ zone.fullcone4 = false;
220+
+ zone.fullcone6 = false;
221+
+ }
222+
+ if (zone.fullcone4) {
223+
+ this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'");
224+
+ }
225+
+ if (zone.fullcone6) {
226+
+ this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'");
227+
+ }
228+
+
229+
if (zone.mtu_fix && this.kernel < 0x040a0000) {
230+
this.warn_section(data, "option 'mtu_fix' requires kernel 4.10 or later");
231+
return;
232+
@@ -2110,10 +2179,15 @@ return {
233+
zone.related_subnets = related_subnets;
234+
zone.related_physdevs = related_physdevs;
235+
236+
+ if (zone.fullcone4 || zone.fullcone6) {
237+
+ zone.dflags.snat = true;
238+
+ zone.dflags.dnat = true;
239+
+ }
240+
+
241+
if (zone.masq || zone.masq6)
242+
zone.dflags.snat = true;
243+
244+
- if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) {
245+
+ if ((zone.auto_helper && !(zone.masq || zone.masq6 || zone.fullcone4 || zone.fullcone6)) || length(zone.helper)) {
246+
zone.dflags.helper = true;
247+
248+
for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) {

0 commit comments

Comments
 (0)