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
Release / release (push) Successful in 36s
This commit is contained in:
1 parent
ea8ca97417
commit
dabe4e8365
8 files changed
+58
-24
No files matched your search
@@ -1144,8 +1144,9 @@ Status: Accepted
|
||||
Context: Sites get subdomains of a selected domain, delegated to the router, without a registrar
|
||||
change per site. Ubuntu has BIND, Knot and PowerDNS; only PowerDNS's gpgsql backend reads records
|
||||
from PostgreSQL, so changes are rows, without zone files or reloads. systemd-resolved's stub holds
|
||||
127.0.0.53, and its stub on the external addresses answers the remote access clients while P2S or
|
||||
OpenVPN is enabled.
|
||||
127.0.0.53 and 127.0.0.54, and its extra stub answered the remote access clients on the external
|
||||
addresses, the addresses an authoritative server needs. The extra stub answers on the internal
|
||||
address just as well, since the clients reach it through the tunnel when it is in `local.cidrs`.
|
||||
|
||||
Decision: While `dns.enabled` is true, setup runs `pdns.service` with
|
||||
`/etc/powerdns/pdns.d/vpn-router.conf`, written before the packages are installed, on the
|
||||
@@ -1153,8 +1154,9 @@ addresses of `dns.listen`, with the gpgsql backend on the database `vpn-router-d
|
||||
own schema. It writes one zone, `dns.zone`, through the procedure `dns_apply` of
|
||||
`/usr/share/vpn-router/sql/dns.sql`: SOA, NS, A and AAAA records of `dns.addresses` for the apex,
|
||||
the name server and every site host name in the zone, and manual records administrators add; the
|
||||
serial grows only when the records change. `dns.listen` on the external interface is refused while
|
||||
P2S or OpenVPN is enabled.
|
||||
serial grows only when the records change. The remote access clients' resolver answers on the
|
||||
addresses of the new setting `p2s.dns_listen`, by default the internal one; a `dns.listen` that
|
||||
shares an interface with it is refused while P2S or OpenVPN is enabled.
|
||||
|
||||
Consequences: The zone follows the sites at each setup run. One zone only, without DNSSEC or
|
||||
transfers; the delegation is made at the parent zone by hand.
|
||||
@@ -115,6 +115,7 @@ must have the type shown below; an unknown section or setting is an error.
|
||||
| `site_to_site` | | object | | The site-to-site connections, each a name and an object of the settings below |
|
||||
| `p2s` | `enabled` | boolean | `false` | Road-warrior access |
|
||||
| `p2s` | `address_pool` | string | | CIDR assigned to road-warrior clients |
|
||||
| `p2s` | `dns_listen` | string | `internal` | The addresses of the resolver the road-warrior and OpenVPN clients are given: `internal`, `external` or `both` |
|
||||
| `wireguard` | `enabled` | boolean | `false` | WireGuard endpoint |
|
||||
| `wireguard` | `address` | string | | The router's own address on `wg0` with the prefix of the peers' network, for example `192.168.200.1/24`; the network and the broadcast address of a network larger than /31 are refused |
|
||||
| `wireguard` | `listen_port` | integer | `51820` | UDP port |
|
||||
@@ -634,8 +635,8 @@ certificate and key from `/etc/caddy/vpn-router-pki/<name>/`, readable by its gr
|
||||
With `openvpn.enabled`, an `address_pool` and `wan.local_fqdn` set, `vpn-router-setup` runs
|
||||
`openvpn-server@vpn-router` with `/etc/openvpn/server/vpn-router.conf`. The server uses the
|
||||
router's VPN server certificate, the root and the P2S CA and their CRLs (see Certificates),
|
||||
pushes routes to `local.cidrs` and the router as DNS server, and opens `openvpn.port` on the
|
||||
external interface.
|
||||
pushes routes to `local.cidrs` and the router's addresses of `p2s.dns_listen` as DNS servers, and
|
||||
opens `openvpn.port` on the external interface.
|
||||
|
||||
A client needs both a certificate of the P2S CA and the password of the user the
|
||||
certificate names:
|
||||
@@ -871,9 +872,13 @@ deploying.
|
||||
which is how a deferred install is expressed. `generic` is the module to choose when the
|
||||
router should be configured but the platform adds nothing.
|
||||
|
||||
The shipped modules currently add nothing. Road-warrior clients are given the router
|
||||
itself as their DNS server and the router forwards through its own `systemd-resolved`, so
|
||||
no provider resolver has to be advertised or routed through the tunnel on any platform.
|
||||
The shipped modules currently add nothing. Road-warrior and OpenVPN clients are given the
|
||||
router's addresses of `p2s.dns_listen` as their DNS servers, by default the internal address,
|
||||
where the drop-in `/etc/systemd/resolved.conf.d/p2s-forwarder.conf` makes the router's own
|
||||
`systemd-resolved` answer and the firewall opens port 53 for the client pools, so no provider
|
||||
resolver has to be advertised or routed through the tunnel on any platform. The clients reach
|
||||
the internal address when it is inside `local.cidrs`, which they route through the tunnel. Port 53
|
||||
of the other addresses stays free for the name server (see Name server).
|
||||
The modules exist as the documented place for platform specifics if that changes.
|
||||
|
||||
A module may define any of the following, and takes the default for anything it omits:
|
||||
@@ -1569,8 +1574,8 @@ missing, without the recommended bind backend.
|
||||
Records added with `/dns` or the Router Manager (A, AAAA, CNAME, TXT, MX, SRV, CAA) are served
|
||||
too, but not those of a name and type the zone's own records have. Setup writes the zone at each
|
||||
run; the SOA's serial grows only when the records change. While P2S or OpenVPN is enabled,
|
||||
systemd-resolved answers their clients on port 53 of the external addresses, so `dns.listen` must
|
||||
be `internal`. The parent zone must delegate `dns.zone` to `dns.nameserver`, with glue records for
|
||||
systemd-resolved answers their clients on port 53 of the addresses of `p2s.dns_listen`, by default
|
||||
the internal address, so `dns.listen` must not share an interface with it. The parent zone must delegate `dns.zone` to `dns.nameserver`, with glue records for
|
||||
a name server inside the zone.
|
||||
|
||||
```sh
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 -%}
|
||||
Reference in new issue
Block a user