bind: Fix port number clash with 'shared' network connections

Closes: #707
Helps: #1570

- Network Manager's 'shared' connections use port 53 on those interfaces. Bind
by default also listens on them if possible. In some corner cases, this could
lead to a clash. This patch fixes to cases by making sure bind does not listen
on IP address likely used by Network Manager's 'shared' connections. If user
custom configures address, they will need to update the bind configuration
accordingly.

- App version increment is not necessary because in this release cycle we have
already incremented it once.

Tests:

- Install without patch. Increment the app version number (and the version
number in the privileged script). Notice that bind app setup is run again.
'listen-on' line is inserted into the configuration file as expected.

- Increment the version numbers again and a second 'listen-on' line is not
inserted.

- Without patch, on a machine with two network interfaces, start a 'shared'
network connection. Start bind. Notice the error that bind could not listen on
the shared network IP address.

- Without patch, on a machine with two network interface, start bind while
'shared' network connection is configured with just the IP address. Start bind
and it will listening on the IP address with shared network IP address.
Configure a shared connection and it fails to start.

- Apply the patch. Start 'shared' network connection. Start bind and notice that
bind does not attempt to listen on that shared network IP address and does not
print error message as well.

- Apply the patch. Start bind while 'shared' network connection is configured
with just the IP address. Bind does not attempt to listen on that shared network
IP address. Start the shared network connection. It start without issues.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2024-09-06 18:26:29 -07:00 committed by James Valleroy
parent 86c08e56ca
commit bc9e83e41f
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Configuration helper for BIND server."""
import pathlib
import re
from collections import defaultdict
from pathlib import Path
@ -18,6 +19,7 @@ acl goodclients {
localnets;
};
options {
listen-on { !10.42.0.1; !10.42.1.1; !10.42.2.1; !10.42.3.1; !10.42.4.1; !10.42.5.1; !10.42.6.1; !10.42.7.1; any; };
directory "/var/cache/bind";
recursion yes;
@ -31,8 +33,10 @@ forward first;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
'''
''' # noqa: E501
DEFAULT_FORWARDER = '127.0.0.53' # systemd-resolved
LISTEN_ON = 'listen-on { !10.42.0.1; !10.42.1.1; !10.42.2.1; !10.42.3.1; '\
'!10.42.4.1; !10.42.5.1; !10.42.6.1; !10.42.7.1; any; };'
@privileged
@ -45,6 +49,9 @@ def setup(old_version: int):
if not get_config()['forwarders']:
_set_forwarders(DEFAULT_FORWARDER)
if not _has_listen_on():
_insert_listen_on()
if old_version < 3:
_remove_dnssec()
@ -106,6 +113,26 @@ def _remove_dnssec():
file_handle.write(line + '\n')
def _has_listen_on():
"""Return whether listen-on config option is present."""
lines = pathlib.Path(CONFIG_FILE).read_text().splitlines()
regex = r'^\s*listen-on\s+{'
return any((re.match(regex, line) for line in lines))
def _insert_listen_on():
"""Insert the listen-on option."""
config_file = pathlib.Path(CONFIG_FILE)
lines = config_file.read_text().splitlines(keepends=True)
write_lines = []
for line in lines:
write_lines += line
if re.match(r'^\s*options\s+{', line):
write_lines += LISTEN_ON + '\n'
config_file.write_text(''.join(write_lines))
def get_served_domains():
"""Return list of domains service handles.