diff --git a/man/systemd.dns-delegate.xml b/man/systemd.dns-delegate.xml index a06ccad529..0ef36d2bf5 100644 --- a/man/systemd.dns-delegate.xml +++ b/man/systemd.dns-delegate.xml @@ -69,6 +69,18 @@ + + FirewallMark= + + Takes a 32 bit unsigned integer value. Controls the firewall mark of packets generated by the + socket used to make DNS requests for this DNS delegate. This can be used in the firewall logic to + filter packets from this socket. + This sets the SO_MARK socket option. See iptables8 for + details. + + + @@ -79,10 +91,11 @@ # /etc/systemd/dns-delegate.d/foobar.dns-delegate [Delegate] DNS=203.0.113.47 -Domains=foobar.com +Domains=foobar.com +FirewallMark=42 This ensures lookups of foobar.com and any domains below it are directed to - DNS server 203.0.113.47. + DNS server 203.0.113.47 and any packets related to this lookup have a firewall mark set to 42. diff --git a/src/resolve/resolved-dns-delegate-gperf.gperf b/src/resolve/resolved-dns-delegate-gperf.gperf index 3040770f3a..27dfe43366 100644 --- a/src/resolve/resolved-dns-delegate-gperf.gperf +++ b/src/resolve/resolved-dns-delegate-gperf.gperf @@ -21,3 +21,4 @@ struct ConfigPerfItem; Delegate.DNS, config_parse_delegate_dns_servers, 0, 0 Delegate.Domains, config_parse_delegate_domains, 0, 0 Delegate.DefaultRoute, config_parse_tristate, 0, offsetof(DnsDelegate, default_route) +Delegate.FirewallMark, config_parse_unsigned, 0, offsetof(DnsDelegate, fwmark) diff --git a/src/resolve/resolved-dns-delegate.h b/src/resolve/resolved-dns-delegate.h index dfb8429de2..5ec070db37 100644 --- a/src/resolve/resolved-dns-delegate.h +++ b/src/resolve/resolved-dns-delegate.h @@ -23,6 +23,8 @@ typedef struct DnsDelegate { int default_route; + uint32_t fwmark; + DnsScope *scope; LIST_FIELDS(DnsDelegate, delegates); diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index c6c6bdc866..8fe0a8bc5f 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -475,6 +475,12 @@ static int dns_scope_socket( return r; } + if (s->delegate && s->delegate->fwmark > 0) { + r = setsockopt_int(fd, SOL_SOCKET, SO_MARK, s->delegate->fwmark); + if (r < 0) + return log_debug_errno(r, "Failed to set firewall mark on DNS socket: %m)"); + } + bool addr_is_nonlocal = s->link && !manager_find_link_address(s->manager, sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) && in_addr_is_localhost(sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) == 0; diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index e6ef9214a3..b3656da940 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -1452,6 +1452,7 @@ testcase_delegate() { [Delegate] DNS=192.168.77.78 Domains=exercise.test +FirewallMark=42 EOF systemctl reload systemd-resolved resolvectl status