Iptables restrictions bugfix: #2: Restrict inter-host access

This commit is contained in:
2026-09-27 15:57:36 +01:00
parent 65b321f73b
commit 5560567143
2 changed files with 26 additions and 15 deletions
@@ -21,7 +21,7 @@ describe("buildHostIptablesScripts", () => {
expect(res.post_up).not.toContain("WGUI0FWD -s");
expect(res.post_down).toContain("iptables -X WGUI0FWD");
expect(res.post_down).toContain(
"iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE 2>/dev/null || true",
"iptables -t nat -D POSTROUTING -j MASQUERADE 2>/dev/null || true",
);
});
@@ -67,11 +67,12 @@ describe("buildHostIptablesScripts", () => {
expect(res.success).toBe(true);
expect(res.post_up).toContain(
"iptables -A WGUI0FWD -s 10.0.0.3/32 -d 192.168.1.10/32 -p tcp -m multiport --dports 80,443 -j ACCEPT",
"iptables -A WGUI0FWD -s 10.0.0.3/32 -p tcp -m multiport --dports 80,443 -j ACCEPT",
);
expect(res.post_up).not.toContain(
"iptables -A WGUI0IN -s 10.0.0.3/32 -d 192.168.1.10/32 -p tcp -m multiport --dports 80,443 -j ACCEPT",
expect(res.post_up).toContain(
"iptables -A WGUI0IN -s 10.0.0.3/32 -p tcp -m multiport --dports 80,443 -j ACCEPT",
);
expect(res.post_up).not.toContain("-d 192.168.1.10/32");
});
test("protocol any with ports emits tcp and udp", () => {
@@ -99,6 +100,12 @@ describe("buildHostIptablesScripts", () => {
expect(res.post_up).toContain(
"iptables -A WGUI0FWD -s 10.0.0.4/32 -p udp --dport 53 -j ACCEPT",
);
expect(res.post_up).toContain(
"iptables -A WGUI0IN -s 10.0.0.4/32 -p tcp --dport 53 -j ACCEPT",
);
expect(res.post_up).toContain(
"iptables -A WGUI0IN -s 10.0.0.4/32 -p udp --dport 53 -j ACCEPT",
);
});
test("rejects invalid destination", () => {
@@ -149,17 +156,17 @@ describe("buildHostIptablesScripts", () => {
expect(res.success).toBe(true);
expect(res.post_up).toContain(
"iptables -t nat -C POSTROUTING -s 10.2.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -s 10.2.0.0/24 -o eth0 -j MASQUERADE",
"iptables -t nat -C POSTROUTING -s 10.2.0.0/24 -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -s 10.2.0.0/24 -j MASQUERADE",
);
expect(res.post_up).not.toContain(
"iptables -t nat -A POSTROUTING -i eth0 -j MASQUERADE",
);
expect(res.post_down).toContain(
"iptables -t nat -D POSTROUTING -s 10.2.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || true",
"iptables -t nat -D POSTROUTING -s 10.2.0.0/24 -j MASQUERADE 2>/dev/null || true",
);
});
test("masquerade falls back to the target interface without a subnet", () => {
test("masquerade without a subnet applies to all postrouting traffic", () => {
const res = buildHostIptablesScripts({
...base,
clients: [
@@ -173,11 +180,11 @@ describe("buildHostIptablesScripts", () => {
expect(res.success).toBe(true);
expect(res.post_up).toContain(
"iptables -t nat -C POSTROUTING -o eth0 -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE",
"iptables -t nat -C POSTROUTING -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -j MASQUERADE",
);
});
test("all access with host_subnet is scoped to the subnet", () => {
test("all access accepts the client on forward and input regardless of host_subnet", () => {
const res = buildHostIptablesScripts({
...base,
host_subnet: "10.6.0.0/24",
@@ -192,17 +199,16 @@ describe("buildHostIptablesScripts", () => {
expect(res.success).toBe(true);
expect(res.post_up).toContain(
"iptables -A WGUI0FWD -s 10.0.0.7/32 -d 10.6.0.0/24 -j ACCEPT",
"iptables -A WGUI0FWD -s 10.0.0.7/32 -j ACCEPT",
);
expect(res.post_up).toContain(
"iptables -A WGUI0IN -s 10.0.0.7/32 -j ACCEPT",
);
expect(res.post_up).not.toContain(
"iptables -A WGUI0FWD -s 10.0.0.7/32 -o eth0 -j ACCEPT",
);
expect(res.post_up).not.toContain("-d 10.6.0.0/24");
expect(res.post_up).not.toContain("-o eth0");
});
test("port-only rules are not mirrored onto the input chain", () => {
test("port-only rules are mirrored onto both forward and input chains", () => {
const res = buildHostIptablesScripts({
...base,
clients: [
@@ -224,7 +230,7 @@ describe("buildHostIptablesScripts", () => {
expect(res.post_up).toContain(
"iptables -A WGUI0FWD -s 10.0.0.8/32 -p tcp --dport 53 -j ACCEPT",
);
expect(res.post_up).not.toContain(
expect(res.post_up).toContain(
"iptables -A WGUI0IN -s 10.0.0.8/32 -p tcp --dport 53 -j ACCEPT",
);
});
@@ -322,6 +322,11 @@ export default function buildHostIptablesScripts({
}
}
accept_lines.push(
`# Prevent clients from forwarding traffic back into the WireGuard network`,
`iptables -A ${forward} -o ${interface_name} -j DROP`,
);
const post_up = [
`#!/bin/bash`,
``,