fix: the remote access clients' resolver answers on the internal address by default, chosen by p2s.dns_listen, so the name server can take port 53 of the external addresses.
Release / release (push) Successful in 36s

This commit is contained in:
slawek committed 2026-10-26 16:11:08 +01:00
1 parent ea8ca97417
commit dabe4e8365
8 files changed
+58 -24

No files matched your search

+13
View File
@@ -1,3 +1,16 @@
vpn-router (0.31.1-1) unstable; urgency=medium
fix: the remote access clients' resolver answers on the internal address by default, chosen by p2s.dns_listen, so the name server can take port 53 of the external addresses.
* The new setting p2s.dns_listen chooses the addresses of the resolver the
road-warrior and OpenVPN clients are given: internal, the default,
external or both. The firewall opens port 53 for the client pools on
those addresses only.
* dns.listen is refused only when it shares an interface with
p2s.dns_listen while IKEv2 or OpenVPN is enabled.
-- Slawomir Koszewski <slawek@koszewscy.waw.pl> Mon, 26 Oct 2026 23:00:00 +0100
vpn-router (0.31.0-1) unstable; urgency=medium
feature: Caddy serves static web sites from folders on the router, defined in their own database, with files uploaded through the web service or WebDAV, and an optional PowerDNS name server answers for a zone of the sites.
+3 -2
View File
@@ -241,10 +241,11 @@ def filter_block(ctx):
pools = [pool for ready, pool in ((vpnrouter.p2s_ready(ctx), ctx['p2s_address_pool']),
(vpnrouter.openvpn_ready(ctx), ctx['openvpn_pool'])) if ready]
if pools and ctx['local_addr_list']:
# The remote access clients' resolver answers on the addresses of p2s.dns_listen.
if pools and ctx['p2s_resolver_addrs']:
lines += ['', '# P2S DNS RULES START']
for pool in pools:
for address in ctx['local_addr_list']:
for address in ctx['p2s_resolver_addrs']:
lines += [
f'-A ufw-before-input -s {pool} -d {address} -p udp --dport 53 -j ACCEPT',
f'-A ufw-before-input -s {pool} -d {address} -p tcp --dport 53 -j ACCEPT',
@@ -53,7 +53,7 @@ SCHEMA = {
'wan': {'local_fqdn': ''},
'local': {'cidrs': [], 'int_addr': '', 'int_gateway_ip': ''},
'site_to_site': {},
'p2s': {'enabled': False, 'address_pool': ''},
'p2s': {'enabled': False, 'address_pool': '', 'dns_listen': 'internal'},
'wireguard': {'enabled': False, 'address': '', 'listen_port': 51820},
'openvpn': {'enabled': False, 'address_pool': '', 'port': 1194, 'protocol': 'udp'},
'docker': {'mode': 'auto', 'exposed_ports': []},
@@ -581,9 +581,15 @@ def validate(cfg):
raise ConfigError(f'dns.listen: {dns["listen"]!r} is not one of {", ".join(LISTEN_CHOICES)}')
if not DNS_TTL_RANGE[0] <= dns['ttl'] <= DNS_TTL_RANGE[1]:
raise ConfigError(f'dns.ttl: {dns["ttl"]} is not between {DNS_TTL_RANGE[0]} and {DNS_TTL_RANGE[1]} seconds')
if dns['enabled'] and dns['listen'] != 'internal' and (_get(cfg, 'p2s', 'enabled') or _get(cfg, 'openvpn', 'enabled')):
raise ConfigError('dns.listen: port 53 of the external addresses is the resolver of the remote access clients '
'while p2s.enabled or openvpn.enabled is true; the name server can listen on internal only')
resolver_listen = _get(cfg, 'p2s', 'dns_listen')
if resolver_listen not in LISTEN_CHOICES:
raise ConfigError(f'p2s.dns_listen: {resolver_listen!r} is not one of {", ".join(LISTEN_CHOICES)}')
sides = {'internal': {'internal'}, 'external': {'external'}, 'both': {'internal', 'external'}}
if dns['enabled'] and (_get(cfg, 'p2s', 'enabled') or _get(cfg, 'openvpn', 'enabled')) and \
sides[dns['listen']] & sides[resolver_listen]:
raise ConfigError(f'dns.listen: port 53 of the {" and ".join(sorted(sides[dns["listen"]] & sides[resolver_listen]))} '
f'addresses is the resolver of the remote access clients (p2s.dns_listen {resolver_listen}) '
'while p2s.enabled or openvpn.enabled is true')
for option in ('root_name', 'p2s_name', 's2s_name'):
value = _get(cfg, 'pki', option)
@@ -933,6 +939,10 @@ def build_context(cfg, public_ip=None):
openvpn_pool = _get(cfg, 'openvpn', 'address_pool')
openvpn_network = ipaddress.ip_network(openvpn_pool) if openvpn_pool else None
identities = {'fqdn': local_fqdn, 'public_ip': public_ip or '', 'internal_ip': int_addr}
# The addresses the remote access clients' resolver answers on, which p2s.dns_listen chooses.
resolver_addrs = [address for address in {'internal': [int_addr], 'external': local_addrs,
'both': [int_addr, *local_addrs]}[_get(cfg, 'p2s', 'dns_listen')]
if address]
connections = []
for name, connection in cfg['site_to_site'].items():
@@ -976,7 +986,8 @@ def build_context(cfg, public_ip=None):
'p2s_enabled': _get(cfg, 'p2s', 'enabled'),
'p2s_address_pool': _get(cfg, 'p2s', 'address_pool'),
'public_ip': public_ip or '',
'p2s_dns': _join(local_addrs, _split_list(extras['EXTRA_P2S_DNS'])),
'p2s_resolver_addrs': resolver_addrs,
'p2s_dns': _join(resolver_addrs, _split_list(extras['EXTRA_P2S_DNS'])),
'wg_enabled': _get(cfg, 'wireguard', 'enabled'),
'wg_address': _get(cfg, 'wireguard', 'address'),
'wg_listen_port': _get(cfg, 'wireguard', 'listen_port'),
@@ -994,7 +1005,7 @@ def build_context(cfg, public_ip=None):
'openvpn_ldap_conf': str(OPENVPN_LDAP),
'openvpn_status': vpnrouter_status.OPENVPN_STATUS,
'openvpn_status_seconds': vpnrouter_status.OPENVPN_STATUS_SECONDS,
'p2s_dns_list': _split_list(_join(local_addrs, _split_list(extras['EXTRA_P2S_DNS']))),
'p2s_dns_list': _split_list(_join(resolver_addrs, _split_list(extras['EXTRA_P2S_DNS']))),
'openvpn_ca': str(vpnrouter_pki.OPENVPN_CA),
'openvpn_crl': str(vpnrouter_pki.OPENVPN_CRL),
'server_cert': str(vpnrouter_pki.VPN_SERVER_CERT),
@@ -1218,7 +1229,8 @@ def configure(cfg=None, public_ip=None):
elif remove(ROAD_WARRIOR):
changed.add('swanctl')
if p2s_ready(ctx) or openvpn_ready(ctx):
# The resolver of the remote access clients answers on the addresses of p2s.dns_listen only.
if (p2s_ready(ctx) or openvpn_ready(ctx)) and ctx['p2s_resolver_addrs']:
if render(env, ctx, 'p2s-forwarder.conf.j2', P2S_FORWARDER, 0o644):
changed.add('resolved')
elif remove(P2S_FORWARDER):
@@ -4,8 +4,8 @@ No platform-specific configuration is currently required.
The Azure platform resolver 168.63.129.16 is deliberately *not* advertised to
road-warrior clients and *not* added to the traffic selectors. Clients are
given the router itself as their DNS server, and the router forwards through
its own systemd-resolved via the p2s-forwarder drop-in. That resolves
given the router's addresses of p2s.dns_listen as their DNS servers, and the router
forwards through its own systemd-resolved via the p2s-forwarder drop-in. That resolves
Azure-internal names without routing the wireserver address through the tunnel
and without a second resolver in the pool.
"""
@@ -38,7 +38,8 @@
},
"p2s": {
"enabled": false,
"address_pool": "172.16.0.0/24"
"address_pool": "172.16.0.0/24",
"dns_listen": "internal"
},
"wireguard": {
"enabled": false,
@@ -1,4 +1,4 @@
[Resolve]
{% for address in local_addr_list -%}
{% for address in p2s_resolver_addrs -%}
DNSStubListenerExtra={{ address }}
{% endfor -%}