cloud_discovery: allow DNS rebind for controller FQDNs

Add dnsmasq_rebind_allow() function to automatically whitelist controller
FQDNs for private IP resolution in air-gapped deployments.

When dnsmasq's boguspriv option is enabled (default), it blocks DNS
responses containing private IP addresses (RFC 1918) as a security
measure. This prevents DHCP Option 224 from resolving controller FQDNs
to local private IPs in air-gapped networks.

Solution: Inject rebind-domain-ok directives into /tmp/dnsmasq.d/
directory, which dnsmasq automatically includes via --conf-dir option.

Behaviour:
- DHCP discovery: Whitelist FQDN from dhcp_server field
- Standard FQDN discovery: Whitelist openwifi.network
- Centralized discovery: No changes (public IPs not affected)

This maintains security by only allowing specific controller domains
to resolve to private IPs whilst filtering all other RFC 1918 responses.

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin 2025-11-25 07:31:08 +01:00
parent f82097dd7e
commit 8e9c9588e1

View File

@ -145,6 +145,17 @@ function gateway_available() {
return true;
}
function dnsmasq_rebind_allow(fqdn) {
let config_dir = '/tmp/dnsmasq.d';
let config_file = `${config_dir}/cloud-discovery.conf`;
if (!fs.stat(config_dir))
fs.mkdir(config_dir);
fs.writefile(config_file, `rebind-domain-ok=/${fqdn}/\n`);
system('/etc/init.d/dnsmasq reload');
}
function set_state(set) {
if (state == set)
return;
@ -193,6 +204,7 @@ function discover_dhcp() {
let dhcp = readjsonfile('/tmp/cloud.json');
if (dhcp?.dhcp_server && dhcp?.dhcp_port) {
let fqdn = split(dhcp.dhcp_server, ':')[0];
dnsmasq_rebind_allow(fqdn);
if (gateway_write({
server: dhcp.dhcp_server,
port: dhcp.dhcp_port,
@ -264,6 +276,8 @@ function discover_standard_fqdn() {
let address = result[STANDARD_FQDN].A[0];
ulog(LOG_INFO, `Resolved ${STANDARD_FQDN} to ${address}\n`);
dnsmasq_rebind_allow(STANDARD_FQDN);
if (gateway_write({
server: STANDARD_FQDN,
port: STANDARD_FQDN_PORT,