diff options
author | Lucas Christian <lucas@lucasec.com> | 2020-10-05 14:35:17 -0500 |
---|---|---|
committer | Lucas Christian <lucas@lucasec.com> | 2020-10-06 11:14:31 -0500 |
commit | e9cac63933ae9ddbb13a64406cff77640ab901dc (patch) | |
tree | f9fb72642db37ebdd685921fa9fef1daee99aca1 | |
parent | 5accf7227858cde303e0c49f8c36408ef4c5fb93 (diff) | |
download | vyos-1x-e9cac63933ae9ddbb13a64406cff77640ab901dc.tar.gz vyos-1x-e9cac63933ae9ddbb13a64406cff77640ab901dc.zip |
pdns_recursor: T2964: Expose query-local-address to dns config.
In certain split DNS configurations, there is a need for more
fine-grained control over the local address DNS forwarding uses to
issue queries. The current pdns_recursor configuration allows the
recursor to send queries from any available address on the interface
the OS selects for the query, with no option to limit queries to a
particular address or set of addresses.
This commit exposes the `query-local-address` option in
`recursor.conf` to users via the `service` `dns` `forwarding`
`source-address` config node.
If the parameter is unspecified, the default value of 0.0.0.0 (any
IPv4 address) and :: (any IPv6 address) are used to match current
behavior.
Users who want more control can specify one or more IPv4 and IPv6
addresses to issue queries from. Per pdns_recursor docs, the recursor
will load balance queries between any available addresses in the
pools. Since IPv4 and IPv6 are different pools, note that specifying
only one type of address will disable issuing queries for the other
address family.
-rw-r--r-- | data/templates/dns-forwarding/recursor.conf.tmpl | 4 | ||||
-rw-r--r-- | interface-definitions/dns-forwarding.xml.in | 21 | ||||
-rwxr-xr-x | src/conf_mode/dns_forwarding.py | 16 |
3 files changed, 39 insertions, 2 deletions
diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl index b0ae3cc61..8799718b0 100644 --- a/data/templates/dns-forwarding/recursor.conf.tmpl +++ b/data/templates/dns-forwarding/recursor.conf.tmpl @@ -10,8 +10,8 @@ threads=1 allow-from={{ allow_from | join(',') }} log-common-errors=yes non-local-bind=yes -query-local-address=0.0.0.0 -query-local-address6=:: +query-local-address={{ source_address_v4 | join(',') }} +query-local-address6={{ source_address_v6 | join(',') }} lua-config-file=recursor.conf.lua # cache-size diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 07e63d54a..62fb8b946 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -177,6 +177,27 @@ </constraint> </properties> </leafNode> + <leafNode name="source-address"> + <properties> + <help>Local addresses from which to send DNS queries. + If unspecified, the querier will use any available address on + the outbound interface.</help> + <valueHelp> + <format>ipv4</format> + <description>IPv4 address from which to send traffic</description> + </valueHelp> + <valueHelp> + <format>ipv6</format> + <description>IPv6 address from which to send traffic</description> + </valueHelp> + <multi/> + <constraint> + <validator name="ipv4-address"/> + <validator name="ipv6-address"/> + </constraint> + </properties> + <defaultValue>0.0.0.0 ::</defaultValue> + </leafNode> <leafNode name="system"> <properties> <help>Use system name servers</help> diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 5101c1e79..2187b3c73 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -26,6 +26,7 @@ from vyos.util import chown from vyos.util import vyos_dict_search from vyos.template import render from vyos.xml import defaults +from vyos.validate import is_ipv6 from vyos import ConfigError from vyos import airbag @@ -65,6 +66,21 @@ def get_config(config=None): if conf.exists(base_nameservers_dhcp): dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)}) + # Split the source_address property into separate IPv4 and IPv6 lists + # NOTE: In future versions of pdns-recursor (> 4.4.0), this logic can be removed + # as both IPv4 and IPv6 addresses can be specified in a single setting. + source_address_v4 = [] + source_address_v6 = [] + + for source_address in dns['source_address']: + if is_ipv6(source_address): + source_address_v6.append(source_address) + else: + source_address_v4.append(source_address) + + dns.update({'source_address_v4': source_address_v4}) + dns.update({'source_address_v6': source_address_v6}) + return dns def verify(dns): |