diff options
| -rw-r--r-- | data/templates/dns-forwarding/override.conf.j2 | 8 | ||||
| -rw-r--r-- | data/templates/dns-forwarding/recursor.conf.j2 | 4 | ||||
| -rw-r--r-- | data/templates/dns-forwarding/recursor.conf.lua.j2 | 2 | ||||
| -rw-r--r-- | op-mode-definitions/dns-forwarding.xml.in | 20 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_dns_forwarding.py | 9 | ||||
| -rwxr-xr-x | src/conf_mode/service_dns_forwarding.py | 36 | ||||
| -rw-r--r-- | src/etc/systemd/system/pdns-recursor.service.d/override.conf | 8 | ||||
| -rwxr-xr-x | src/op_mode/dns.py | 64 | ||||
| -rwxr-xr-x | src/op_mode/dns_forwarding_reset.py | 54 | ||||
| -rwxr-xr-x | src/op_mode/dns_forwarding_restart.sh | 8 | ||||
| -rwxr-xr-x | src/op_mode/dns_forwarding_statistics.py | 32 | ||||
| -rwxr-xr-x | src/services/vyos-hostsd | 12 | 
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']: | 
