Skip to content

Commit babcbfa

Browse files
CopilotlpcoxCopilot
authored
refactor: extract addDnsRules helper to eliminate duplicate DNS iptables rule pairs (#3273)
* Initial plan * refactor: extract addDnsRules helper for DNS iptables rules * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent d487d78 commit babcbfa

2 files changed

Lines changed: 42 additions & 30 deletions

File tree

src/host-iptables-rules.ts

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
CHAIN_NAME,
88
CHAIN_NAME_V6,
99
NETWORK_NAME,
10+
addDnsRules,
1011
disableIpv6ViaSysctl,
1112
getDockerBridgeGateway,
1213
getNetworkBridgeName,
@@ -224,28 +225,10 @@ export async function setupHostIptables(squidIp: string, squidPort: number, dnsS
224225
const isV6 = dnsServer.includes(':');
225226
if (isV6) {
226227
if (ip6tablesAvailable) {
227-
await execa('ip6tables', [
228-
'-t', 'filter', '-A', CHAIN_NAME_V6,
229-
'-p', 'udp', '-d', dnsServer, '--dport', '53',
230-
'-j', 'ACCEPT',
231-
]);
232-
await execa('ip6tables', [
233-
'-t', 'filter', '-A', CHAIN_NAME_V6,
234-
'-p', 'tcp', '-d', dnsServer, '--dport', '53',
235-
'-j', 'ACCEPT',
236-
]);
228+
await addDnsRules('ip6tables', CHAIN_NAME_V6, dnsServer);
237229
}
238230
} else {
239-
await execa('iptables', [
240-
'-t', 'filter', '-A', CHAIN_NAME,
241-
'-p', 'udp', '-d', dnsServer, '--dport', '53',
242-
'-j', 'ACCEPT',
243-
]);
244-
await execa('iptables', [
245-
'-t', 'filter', '-A', CHAIN_NAME,
246-
'-p', 'tcp', '-d', dnsServer, '--dport', '53',
247-
'-j', 'ACCEPT',
248-
]);
231+
await addDnsRules('iptables', CHAIN_NAME, dnsServer);
249232
}
250233
}
251234

@@ -259,16 +242,7 @@ export async function setupHostIptables(squidIp: string, squidPort: number, dnsS
259242
// 5a. Allow DNS traffic to DoH proxy sidecar (when enabled)
260243
if (dohProxyIp) {
261244
logger.debug(`Allowing DNS traffic to DoH proxy sidecar at ${dohProxyIp}:53`);
262-
await execa('iptables', [
263-
'-t', 'filter', '-A', CHAIN_NAME,
264-
'-p', 'udp', '-d', dohProxyIp, '--dport', '53',
265-
'-j', 'ACCEPT',
266-
]);
267-
await execa('iptables', [
268-
'-t', 'filter', '-A', CHAIN_NAME,
269-
'-p', 'tcp', '-d', dohProxyIp, '--dport', '53',
270-
'-j', 'ACCEPT',
271-
]);
245+
await addDnsRules('iptables', CHAIN_NAME, dohProxyIp);
272246
}
273247

274248
// 5b. Allow traffic to API proxy sidecar (when enabled)

src/host-iptables-shared.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,44 @@ export async function disableIpv6ViaSysctl(): Promise<void> {
107107
}
108108
}
109109

110+
/**
111+
* Adds both UDP and TCP ACCEPT rules on port 53 for the given destination to a chain.
112+
* This helper keeps DNS allowlist rules as a consistent pair by rolling back any
113+
* successfully-added rule if a later add fails.
114+
*/
115+
export async function addDnsRules(
116+
cmd: 'iptables' | 'ip6tables',
117+
chain: string,
118+
destination: string,
119+
): Promise<void> {
120+
const addedProtos: Array<'udp' | 'tcp'> = [];
121+
122+
try {
123+
for (const proto of ['udp', 'tcp'] as const) {
124+
await execa(cmd, [
125+
'-t', 'filter', '-A', chain,
126+
'-p', proto, '-d', destination, '--dport', '53',
127+
'-j', 'ACCEPT',
128+
]);
129+
addedProtos.push(proto);
130+
}
131+
} catch (error) {
132+
for (const proto of addedProtos.reverse()) {
133+
try {
134+
await execa(cmd, [
135+
'-t', 'filter', '-D', chain,
136+
'-p', proto, '-d', destination, '--dport', '53',
137+
'-j', 'ACCEPT',
138+
]);
139+
} catch (rollbackError) {
140+
logger.warn(`Failed to roll back ${cmd} DNS ${proto} rule for ${destination}:`, rollbackError);
141+
}
142+
}
143+
144+
throw error;
145+
}
146+
}
147+
110148
/**
111149
* Re-enables IPv6 via sysctl if it was previously disabled.
112150
*/

0 commit comments

Comments
 (0)