Duplicate Code Opportunity
Summary
- Pattern: Identical
execa('iptables', ...) pair (one UDP rule + one TCP rule on port 53) repeated for every destination that needs DNS access
- Locations:
src/host-iptables-rules.ts — DNS server loop (~lines 228–247), DoH proxy block (~lines 262–270)
- Impact: Any change to the iptables rule structure (e.g., adding a comment prefix, connection tracking, or LOG target) must be made in multiple places; missing one creates a security inconsistency
Evidence
DNS server loop (lines 239–247) — repeated for every IPv4 upstream DNS server:
await execa('iptables', [
'-t', 'filter', '-A', CHAIN_NAME,
'-p', 'udp', '-d', dnsServer, '--dport', '53',
'-j', 'ACCEPT',
]);
await execa('iptables', [
'-t', 'filter', '-A', CHAIN_NAME,
'-p', 'tcp', '-d', dnsServer, '--dport', '53',
'-j', 'ACCEPT',
]);
DoH proxy block (lines 264–270) — same pattern for the DoH sidecar IP:
await execa('iptables', [
'-t', 'filter', '-A', CHAIN_NAME,
'-p', 'udp', '-d', dohProxyIp, '--dport', '53',
'-j', 'ACCEPT',
]);
await execa('iptables', [
'-t', 'filter', '-A', CHAIN_NAME,
'-p', 'tcp', '-d', dohProxyIp, '--dport', '53',
'-j', 'ACCEPT',
]);
The same structure also appears for IPv6 (ip6tables, lines 228–237).
Suggested Refactoring
Extract a small helper in src/host-iptables-rules.ts (or src/host-iptables-shared.ts):
async function addDnsRules(
cmd: 'iptables' | 'ip6tables',
chain: string,
destination: string,
): Promise<void> {
for (const proto of ['udp', 'tcp'] as const) {
await execa(cmd, [
'-t', 'filter', '-A', chain,
'-p', proto, '-d', destination, '--dport', '53',
'-j', 'ACCEPT',
]);
}
}
Usage:
// DNS servers loop
await addDnsRules('iptables', CHAIN_NAME, dnsServer);
// DoH proxy
await addDnsRules('iptables', CHAIN_NAME, dohProxyIp);
// IPv6 DNS servers
await addDnsRules('ip6tables', CHAIN_NAME_V6, dnsServer);
This is security-critical: DNS allowlist rules must be consistent, and a helper makes that consistency structural rather than by convention.
Affected Files
src/host-iptables-rules.ts — lines 228–247 (DNS server loop), 262–270 (DoH proxy block), 228–237 (IPv6 DNS)
Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-16
Generated by Duplicate Code Detector · ● 9.9M · ◷
Duplicate Code Opportunity
Summary
execa('iptables', ...)pair (one UDP rule + one TCP rule on port 53) repeated for every destination that needs DNS accesssrc/host-iptables-rules.ts— DNS server loop (~lines 228–247), DoH proxy block (~lines 262–270)Evidence
DNS server loop (lines 239–247) — repeated for every IPv4 upstream DNS server:
DoH proxy block (lines 264–270) — same pattern for the DoH sidecar IP:
The same structure also appears for IPv6 (ip6tables, lines 228–237).
Suggested Refactoring
Extract a small helper in
src/host-iptables-rules.ts(orsrc/host-iptables-shared.ts):Usage:
This is security-critical: DNS allowlist rules must be consistent, and a helper makes that consistency structural rather than by convention.
Affected Files
src/host-iptables-rules.ts— lines 228–247 (DNS server loop), 262–270 (DoH proxy block), 228–237 (IPv6 DNS)Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-16