summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-02-01 21:32:59 +0100
committerGitHub <noreply@github.com>2024-02-01 21:32:59 +0100
commitcd4b03898e99b7317d2cbdf614bc14caf2e9bbce (patch)
treea7d0846c15c1124c10a639c80a3c71523582a502
parent9109a5603963216180f6d6fe09820ee1ba227ade (diff)
parent7255115be80ea14dc53bf7d7382da2da831dc300 (diff)
downloadvyos-1x-cd4b03898e99b7317d2cbdf614bc14caf2e9bbce.tar.gz
vyos-1x-cd4b03898e99b7317d2cbdf614bc14caf2e9bbce.zip
Merge pull request #2922 from vyos/mergify/bp/sagitta/pr-2854
dns: T5959: Streamline dns forwarding service (backport #2854)
-rw-r--r--data/templates/dns-forwarding/override.conf.j28
-rw-r--r--data/templates/dns-forwarding/recursor.conf.j24
-rw-r--r--data/templates/dns-forwarding/recursor.conf.lua.j22
-rw-r--r--op-mode-definitions/dns-forwarding.xml.in20
-rwxr-xr-xsmoketest/scripts/cli/test_service_dns_forwarding.py9
-rwxr-xr-xsrc/conf_mode/service_dns_forwarding.py36
-rw-r--r--src/etc/systemd/system/pdns-recursor.service.d/override.conf8
-rwxr-xr-xsrc/op_mode/dns.py64
-rwxr-xr-xsrc/op_mode/dns_forwarding_reset.py54
-rwxr-xr-xsrc/op_mode/dns_forwarding_restart.sh8
-rwxr-xr-xsrc/op_mode/dns_forwarding_statistics.py32
-rwxr-xr-xsrc/services/vyos-hostsd12
12 files changed, 102 insertions, 155 deletions
diff --git a/data/templates/dns-forwarding/override.conf.j2 b/data/templates/dns-forwarding/override.conf.j2
new file mode 100644
index 000000000..9d81a2977
--- /dev/null
+++ b/data/templates/dns-forwarding/override.conf.j2
@@ -0,0 +1,8 @@
+[Unit]
+ConditionPathExists={{ config_file }}
+After=vyos-router.service
+
+[Service]
+RuntimeDirectoryPreserve=yes
+ExecStart=
+ExecStart=/usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no --config-dir={{ config_dir }}
diff --git a/data/templates/dns-forwarding/recursor.conf.j2 b/data/templates/dns-forwarding/recursor.conf.j2
index 55b37732b..e4e8e7044 100644
--- a/data/templates/dns-forwarding/recursor.conf.j2
+++ b/data/templates/dns-forwarding/recursor.conf.j2
@@ -12,7 +12,7 @@ allow-from={{ allow_from | join(',') }}
log-common-errors=yes
non-local-bind=yes
query-local-address={{ source_address | join(',') }}
-lua-config-file=recursor.conf.lua
+lua-config-file={{ config_dir }}/recursor.conf.lua
# cache-size
max-cache-entries={{ cache_size }}
@@ -56,4 +56,4 @@ serve-rfc1918={{ 'no' if no_serve_rfc1918 is vyos_defined else 'yes' }}
# zones
auth-zones={% for z in authoritative_zones %}{{ z.name }}={{ z.file }}{{- "," if not loop.last -}}{% endfor %}
-forward-zones-file=recursor.forward-zones.conf
+forward-zones-file={{ config_dir }}/recursor.forward-zones.conf
diff --git a/data/templates/dns-forwarding/recursor.conf.lua.j2 b/data/templates/dns-forwarding/recursor.conf.lua.j2
index 816f69160..8026442c7 100644
--- a/data/templates/dns-forwarding/recursor.conf.lua.j2
+++ b/data/templates/dns-forwarding/recursor.conf.lua.j2
@@ -5,4 +5,4 @@
dofile("/usr/share/pdns-recursor/lua-config/rootkeys.lua")
-- Load lua from vyos-hostsd --
-dofile("recursor.vyos-hostsd.conf.lua")
+dofile("{{ config_dir }}/recursor.vyos-hostsd.conf.lua")
diff --git a/op-mode-definitions/dns-forwarding.xml.in b/op-mode-definitions/dns-forwarding.xml.in
index a4c650c38..ebedae6eb 100644
--- a/op-mode-definitions/dns-forwarding.xml.in
+++ b/op-mode-definitions/dns-forwarding.xml.in
@@ -11,7 +11,7 @@
<children>
<node name="forwarding">
<properties>
- <help>Monitor last lines of DNS forwarding</help>
+ <help>Monitor last lines of DNS Forwarding</help>
</properties>
<command>journalctl --no-hostname --follow --boot --unit pdns-recursor.service</command>
</node>
@@ -47,12 +47,12 @@
<children>
<node name="forwarding">
<properties>
- <help>Show DNS forwarding information</help>
+ <help>Show DNS Forwarding information</help>
</properties>
<children>
<leafNode name="statistics">
<properties>
- <help>Show DNS forwarding statistics</help>
+ <help>Show DNS Forwarding statistics</help>
</properties>
<command>sudo ${vyos_op_scripts_dir}/dns.py show_forwarding_statistics</command>
</leafNode>
@@ -71,9 +71,9 @@
<children>
<leafNode name="forwarding">
<properties>
- <help>Restart DNS forwarding service</help>
+ <help>Restart DNS Forwarding service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dns_forwarding_restart.sh</command>
+ <command>if cli-shell-api existsActive service dns forwarding; then sudo systemctl restart pdns-recursor.service; else echo "DNS forwarding not configured"; fi</command>
</leafNode>
</children>
</node>
@@ -88,19 +88,19 @@
<children>
<node name="forwarding">
<properties>
- <help>Reset DNS forwarding cache</help>
+ <help>Reset DNS Forwarding cache</help>
</properties>
<children>
<tagNode name="domain">
- <command>sudo ${vyos_op_scripts_dir}/dns_forwarding_reset.py $5</command>
+ <command>sudo ${vyos_op_scripts_dir}/dns.py reset_forwarding --domain $5</command>
<properties>
- <help>Reset DNS forwarding cache for a domain</help>
+ <help>Reset DNS Forwarding cache for a domain</help>
</properties>
</tagNode>
<leafNode name="all">
- <command>sudo ${vyos_op_scripts_dir}/dns_forwarding_reset.py --all</command>
+ <command>sudo ${vyos_op_scripts_dir}/dns.py reset_forwarding --all</command>
<properties>
- <help>Reset DNS forwarding cache</help>
+ <help>Reset DNS Forwarding cache for all domains</help>
</properties>
</leafNode>
</children>
diff --git a/smoketest/scripts/cli/test_service_dns_forwarding.py b/smoketest/scripts/cli/test_service_dns_forwarding.py
index 85a5f1448..652c4fa7b 100755
--- a/smoketest/scripts/cli/test_service_dns_forwarding.py
+++ b/smoketest/scripts/cli/test_service_dns_forwarding.py
@@ -24,9 +24,10 @@ from vyos.template import bracketize_ipv6
from vyos.utils.file import read_file
from vyos.utils.process import process_named_running
-CONFIG_FILE = '/run/powerdns/recursor.conf'
-FORWARD_FILE = '/run/powerdns/recursor.forward-zones.conf'
-HOSTSD_FILE = '/run/powerdns/recursor.vyos-hostsd.conf.lua'
+PDNS_REC_RUN_DIR = '/run/pdns-recursor'
+CONFIG_FILE = f'{PDNS_REC_RUN_DIR}/recursor.conf'
+FORWARD_FILE = f'{PDNS_REC_RUN_DIR}/recursor.forward-zones.conf'
+HOSTSD_FILE = f'{PDNS_REC_RUN_DIR}/recursor.vyos-hostsd.conf.lua'
PROCESS_NAME= 'pdns_recursor'
base_path = ['service', 'dns', 'forwarding']
@@ -279,7 +280,7 @@ class TestServicePowerDNS(VyOSUnitTestSHIM.TestCase):
def test_listening_port(self):
# We can listen on a different port compared to '53' but only one at a time
- for port in ['1053', '5353']:
+ for port in ['10053', '10054']:
self.cli_set(base_path + ['port', port])
for network in allow_from:
self.cli_set(base_path + ['allow-from', network])
diff --git a/src/conf_mode/service_dns_forwarding.py b/src/conf_mode/service_dns_forwarding.py
index c186f47af..ecad765f4 100755
--- a/src/conf_mode/service_dns_forwarding.py
+++ b/src/conf_mode/service_dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright (C) 2018-2024 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -26,18 +26,18 @@ from vyos.template import render
from vyos.template import bracketize_ipv6
from vyos.utils.process import call
from vyos.utils.permission import chown
-from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
-pdns_rec_user = pdns_rec_group = 'pdns'
-pdns_rec_run_dir = '/run/powerdns'
+pdns_rec_user_group = 'pdns'
+pdns_rec_run_dir = '/run/pdns-recursor'
pdns_rec_lua_conf_file = f'{pdns_rec_run_dir}/recursor.conf.lua'
pdns_rec_hostsd_lua_conf_file = f'{pdns_rec_run_dir}/recursor.vyos-hostsd.conf.lua'
pdns_rec_hostsd_zones_file = f'{pdns_rec_run_dir}/recursor.forward-zones.conf'
pdns_rec_config_file = f'{pdns_rec_run_dir}/recursor.conf'
+pdns_rec_systemd_override = '/run/systemd/system/pdns-recursor.service.d/override.conf'
hostsd_tag = 'static'
@@ -55,6 +55,9 @@ def get_config(config=None):
get_first_key=True,
with_recursive_defaults=True)
+ dns['config_file'] = pdns_rec_config_file
+ dns['config_dir'] = os.path.dirname(pdns_rec_config_file)
+
# some additions to the default dictionary
if 'system' in dns:
base_nameservers = ['system', 'name-server']
@@ -251,11 +254,16 @@ def generate(dns):
if not dns:
return None
- render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.j2',
- dns, user=pdns_rec_user, group=pdns_rec_group)
+ render(pdns_rec_systemd_override, 'dns-forwarding/override.conf.j2', dns)
+
+ render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.j2', dns,
+ user=pdns_rec_user_group, group=pdns_rec_user_group)
- render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.j2',
- dns, user=pdns_rec_user, group=pdns_rec_group)
+ render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.j2', dns,
+ user=pdns_rec_user_group, group=pdns_rec_user_group)
+
+ render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.j2', dns,
+ user=pdns_rec_user_group, group=pdns_rec_user_group)
for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'):
os.unlink(zone_filename)
@@ -263,21 +271,25 @@ def generate(dns):
if 'authoritative_zones' in dns:
for zone in dns['authoritative_zones']:
render(zone['file'], 'dns-forwarding/recursor.zone.conf.j2',
- zone, user=pdns_rec_user, group=pdns_rec_group)
+ zone, user=pdns_rec_user_group, group=pdns_rec_user_group)
# if vyos-hostsd didn't create its files yet, create them (empty)
for file in [pdns_rec_hostsd_lua_conf_file, pdns_rec_hostsd_zones_file]:
with open(file, 'a'):
pass
- chown(file, user=pdns_rec_user, group=pdns_rec_group)
+ chown(file, user=pdns_rec_user_group, group=pdns_rec_user_group)
return None
def apply(dns):
+ systemd_service = 'pdns-recursor.service'
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+
if not dns:
# DNS forwarding is removed in the commit
- call('systemctl stop pdns-recursor.service')
+ call(f'systemctl stop {systemd_service}')
if os.path.isfile(pdns_rec_config_file):
os.unlink(pdns_rec_config_file)
@@ -345,7 +357,7 @@ def apply(dns):
hc.apply()
### finally (re)start pdns-recursor
- call('systemctl restart pdns-recursor.service')
+ call(f'systemctl reload-or-restart {systemd_service}')
if __name__ == '__main__':
try:
diff --git a/src/etc/systemd/system/pdns-recursor.service.d/override.conf b/src/etc/systemd/system/pdns-recursor.service.d/override.conf
deleted file mode 100644
index 158bac02b..000000000
--- a/src/etc/systemd/system/pdns-recursor.service.d/override.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-[Service]
-WorkingDirectory=
-WorkingDirectory=/run/powerdns
-RuntimeDirectory=
-RuntimeDirectory=powerdns
-RuntimeDirectoryPreserve=yes
-ExecStart=
-ExecStart=/usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no --config-dir=/run/powerdns --socket-dir=/run/powerdns
diff --git a/src/op_mode/dns.py b/src/op_mode/dns.py
index 2168aef89..309bef3b9 100755
--- a/src/op_mode/dns.py
+++ b/src/op_mode/dns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2024 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,17 +15,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import typing
import sys
+import vyos.opmode
from tabulate import tabulate
-
from vyos.configquery import ConfigTreeQuery
-from vyos.utils.process import cmd
+from vyos.utils.process import cmd, rc_cmd
-import vyos.opmode
-
-def _data_to_dict(data, sep="\t") -> dict:
+def _forwarding_data_to_dict(data, sep="\t") -> dict:
"""
Return dictionary from plain text
separated by tab
@@ -52,15 +51,15 @@ def _data_to_dict(data, sep="\t") -> dict:
return dictionary
-def _get_raw_forwarding_statistics() -> dict:
- command = cmd('rec_control --socket-dir=/run/powerdns get-all')
- data = _data_to_dict(command)
+def _get_forwarding_statistics_raw() -> dict:
+ command = cmd('rec_control get-all')
+ data = _forwarding_data_to_dict(command)
data['cache-size'] = "{0:.2f}".format( int(
- cmd('rec_control --socket-dir=/run/powerdns get cache-bytes')) / 1024 )
+ cmd('rec_control get cache-bytes')) / 1024 )
return data
-def _get_formatted_forwarding_statistics(data):
+def _get_forwarding_statistics_formatted(data):
cache_entries = data.get('cache-entries')
max_cache_entries = data.get('max-cache-entries')
cache_size = data.get('cache-size')
@@ -69,19 +68,48 @@ def _get_formatted_forwarding_statistics(data):
output = tabulate(data_entries, headers, numalign="left")
return output
+def _verify_forwarding(func):
+ """Decorator checks if DNS Forwarding config exists"""
+ from functools import wraps
-def show_forwarding_statistics(raw: bool):
-
- config = ConfigTreeQuery()
- if not config.exists('service dns forwarding'):
- raise vyos.opmode.UnconfiguredSubsystem('DNS forwarding is not configured')
+ @wraps(func)
+ def _wrapper(*args, **kwargs):
+ config = ConfigTreeQuery()
+ if not config.exists('service dns forwarding'):
+ raise vyos.opmode.UnconfiguredSubsystem('DNS Forwarding is not configured')
+ return func(*args, **kwargs)
+ return _wrapper
- dns_data = _get_raw_forwarding_statistics()
+@_verify_forwarding
+def show_forwarding_statistics(raw: bool):
+ dns_data = _get_forwarding_statistics_raw()
if raw:
return dns_data
else:
- return _get_formatted_forwarding_statistics(dns_data)
+ return _get_forwarding_statistics_formatted(dns_data)
+@_verify_forwarding
+def reset_forwarding(all: bool, domain: typing.Optional[str]):
+ """
+ Reset DNS Forwarding cache
+
+ :param all (bool): reset cache all domains
+ :param domain (str): reset cache for specified domain
+ """
+ if all:
+ rc, output = rc_cmd('rec_control wipe-cache ".$"')
+ if rc != 0:
+ print(output)
+ return None
+ print('DNS Forwarding cache reset for all domains!')
+ return output
+ elif domain:
+ rc, output = rc_cmd(f'rec_control wipe-cache "{domain}$"')
+ if rc != 0:
+ print(output)
+ return None
+ print(f'DNS Forwarding cache reset for domain "{domain}"!')
+ return output
if __name__ == '__main__':
try:
diff --git a/src/op_mode/dns_forwarding_reset.py b/src/op_mode/dns_forwarding_reset.py
deleted file mode 100755
index 55e20918f..000000000
--- a/src/op_mode/dns_forwarding_reset.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2018 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# File: vyos-show-version
-# Purpose:
-# Displays image version and system information.
-# Used by the "run show version" command.
-
-
-import os
-import argparse
-
-from sys import exit
-from vyos.config import Config
-from vyos.utils.process import call
-
-PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns'
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-a", "--all", action="store_true", help="Reset all cache")
-parser.add_argument("domain", type=str, nargs="?", help="Domain to reset cache entries for")
-
-if __name__ == '__main__':
- args = parser.parse_args()
-
- # Do nothing if service is not configured
- c = Config()
- if not c.exists_effective(['service', 'dns', 'forwarding']):
- print("DNS forwarding is not configured")
- exit(0)
-
- if args.all:
- call(f"{PDNS_CMD} wipe-cache \'.$\'")
- exit(0)
-
- elif args.domain:
- call(f"{PDNS_CMD} wipe-cache \'{0}$\'".format(args.domain))
-
- else:
- parser.print_help()
- exit(1)
diff --git a/src/op_mode/dns_forwarding_restart.sh b/src/op_mode/dns_forwarding_restart.sh
deleted file mode 100755
index 64cc92115..000000000
--- a/src/op_mode/dns_forwarding_restart.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-if cli-shell-api existsEffective service dns forwarding; then
- echo "Restarting the DNS forwarding service"
- systemctl restart pdns-recursor.service
-else
- echo "DNS forwarding is not configured"
-fi
diff --git a/src/op_mode/dns_forwarding_statistics.py b/src/op_mode/dns_forwarding_statistics.py
deleted file mode 100755
index 32b5c76a7..000000000
--- a/src/op_mode/dns_forwarding_statistics.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-
-import jinja2
-from sys import exit
-
-from vyos.config import Config
-from vyos.utils.process import cmd
-
-PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns'
-
-OUT_TMPL_SRC = """
-DNS forwarding statistics:
-
-Cache entries: {{ cache_entries }}
-Cache size: {{ cache_size }} kbytes
-
-"""
-
-if __name__ == '__main__':
- # Do nothing if service is not configured
- c = Config()
- if not c.exists_effective('service dns forwarding'):
- print("DNS forwarding is not configured")
- exit(0)
-
- data = {}
-
- data['cache_entries'] = cmd(f'{PDNS_CMD} get cache-entries')
- data['cache_size'] = "{0:.2f}".format( int(cmd(f'{PDNS_CMD} get cache-bytes')) / 1024 )
-
- tmpl = jinja2.Template(OUT_TMPL_SRC)
- print(tmpl.render(data))
diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd
index e34a4b740..1ba90471e 100755
--- a/src/services/vyos-hostsd
+++ b/src/services/vyos-hostsd
@@ -271,8 +271,8 @@ SOCKET_PATH = "ipc://" + os.path.join(RUN_DIR, 'vyos-hostsd.sock')
RESOLV_CONF_FILE = '/etc/resolv.conf'
HOSTS_FILE = '/etc/hosts'
-PDNS_REC_USER = PDNS_REC_GROUP = 'pdns'
-PDNS_REC_RUN_DIR = '/run/powerdns'
+PDNS_REC_USER_GROUP = 'pdns'
+PDNS_REC_RUN_DIR = '/run/pdns-recursor'
PDNS_REC_LUA_CONF_FILE = f'{PDNS_REC_RUN_DIR}/recursor.vyos-hostsd.conf.lua'
PDNS_REC_ZONES_FILE = f'{PDNS_REC_RUN_DIR}/recursor.forward-zones.conf'
@@ -436,18 +436,18 @@ def make_hosts(state):
def make_pdns_rec_conf(state):
logger.info(f"Writing {PDNS_REC_LUA_CONF_FILE}")
- # on boot, /run/powerdns does not exist, so create it
- makedir(PDNS_REC_RUN_DIR, user=PDNS_REC_USER, group=PDNS_REC_GROUP)
+ # on boot, /run/pdns-recursor does not exist, so create it
+ makedir(PDNS_REC_RUN_DIR, user=PDNS_REC_USER_GROUP, group=PDNS_REC_USER_GROUP)
chmod_755(PDNS_REC_RUN_DIR)
render(PDNS_REC_LUA_CONF_FILE,
'dns-forwarding/recursor.vyos-hostsd.conf.lua.j2',
- state, user=PDNS_REC_USER, group=PDNS_REC_GROUP)
+ state, user=PDNS_REC_USER_GROUP, group=PDNS_REC_USER_GROUP)
logger.info(f"Writing {PDNS_REC_ZONES_FILE}")
render(PDNS_REC_ZONES_FILE,
'dns-forwarding/recursor.forward-zones.conf.j2',
- state, user=PDNS_REC_USER, group=PDNS_REC_GROUP)
+ state, user=PDNS_REC_USER_GROUP, group=PDNS_REC_USER_GROUP)
def set_host_name(state, data):
if data['host_name']: