| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
It's time. sd-json was already done earlier in this cycle, let's now
make sd-varlink public too.
This is mostly just a search/replace job of epical proportions.
I left some functions internal (mostly IDL handling), and I turned some
static inline calls into regular calls.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- add missing initialization for DnsQuery.answer_ede_rcode,
- clear EDE code and message in dns_transaction_reset_answer(),
otherwise the previous EDE code or message may be mistakenly reused
on restart. This fixes memory leak of DnsTransaction.answer_ede_msg.
- also clear EDE code and message in dns_query_reset_answer(),
otherwise ede message is leaked if dns_query_accept() is called
multiple times for the same DnsQuery.
Follow-up for 9ca133e97a0c8795b1f293ccea4965b4ad1accc4.
Fixes #30752.
|
|
|
|
|
|
|
|
|
| |
This new transaction result is emitted when the upstream server
indicates a fatal error that we will not try to recover from.
Currently, it is emitted when a validating recursive resolver reports an
error validating dnssec records for a domain. The extended error message
should help give context to the admin.
|
| |
|
|
|
|
| |
Further review comments from: https://github.com/systemd/systemd/pull/22845
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* The new varlink interface exposes a method to subscribe to DNS
resolutions on the system. The socket permissions are open for owner and
group only.
* Notifications are sent to subscriber(s), if any, after successful
resolution of A and AAAA records.
This feature could be used by applications for auditing/logging services
downstream of the resolver. It could also be used to asynchronously
update the firewall. For example, a system that has a tightly configured
firewall could open up connections selectively to known good hosts based
on a known allow-list of hostnames. Of course, updating the firewall
asynchronously will require other design considerations (such as
queueing packets in the user space while a verdict is made).
See also:
https://lists.freedesktop.org/archives/systemd-devel/2022-August/048202.html
https://lists.freedesktop.org/archives/systemd-devel/2022-February/047441.html
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change from the last three commits:
/* size: 312, cachelines: 5, members: 46 */
/* sum members: 296, holes: 5, sum holes: 16 */
↓
/* size: 288, cachelines: 5, members: 46 */
/* sum members: 286, holes: 1, sum holes: 1 */
It's not a big difference, but we might have quite a few queries in flight,
so let' make this a bit more efficient.
|
|
|
|
|
|
| |
It can never go above 16, so let's use a narrower type.
Order will be adjusted later to remove holes.
|
|
|
|
|
|
| |
It can never go above 64, so let's use a narrower type.
Order will be adjusted later to remove holes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
let's make sure we set the "aa" bit in the stub only if we answer with
fully authoritative data. For this ensure:
1. Either all data is synthetic, including all CNAME/DNAME redirects
2. Or all data comes from the local trust anchor or the local zones
(i.e. not the network or the cache)
Follow-up for 4ad017cda57b04b9d65e7da962806cfcc50b5f0c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This does some refactoring: the dns_query_process_cname() function
becomes two: dns_query_process_cname_one() and
dns_query_process_cname_many(). The former will process exactly one
CNAME chain element, the latter will follow a chain for as long as
possible within the current packet.
dns_query_process_cname_many() is mostly identical to the old
dns_query_process_cname(), and all existing code is moved over to using
that.
This is mostly preparation for the next commit, where we make direct use
of dns_query_process_cname_one().
This also renames the DNS_QUERY_RESTARTED return value to
DNS_QUERY_CNAME. That's because in the dns_query_process_cname_many()
case as before if we return this we restarted the query in case we
reached the end of the chain without a conclusive answer, as before. But
in dns_query_process_cname_one() we'll only go one step anyway, and
leave restarting if needed to the caller. Hence DNS_QUERY_RESTARTED is a
bit of a misnomer in that case.
This also gets rid of the weird tail recursion in
dns_query_process_cname() and replaces it with an explicit loop in
dns_query_process_cname_many(). The old recursion wasn't a security
issue since we put a limit on the number of CNAMEs we follow anyway, but
it's still icky to scale stack use by that.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
questions
When we checking if the responses we collected for a DnsQuery are
sufficient to complete it we previously only check if one of the
collected response RRs matches at least one of the question RR keys.
This changes the logic to require that there must be at least one
response RR matched *each* of the question RR keys before considering
the answer complete.
Otherwise we might end up accepting an A reply as complete answer for an
A/AAAA query and vice versa, but we want to make sure we wait until we
get a reply on both types before returning this to the user in all
cases.
This has been broken for basically forever, but didn't surface until
b1eea703e01da1e280e179fb119449436a0c9b8e since until then we'd basically
ignore the auxiliary RRs included in CNAME/DNAME replies. Once that
commit was made we'd start using the auxiliary RRs included in
CNAME/DNAME replies but those typically included only A or only AAAA
which we then took for complete.
Fixe: #19049
|
|
|
|
|
|
| |
Let's rename it a bit, to be more explanatory while exporting it.
(And let's bump the CNAME limit to 16 — 8 just sounded so little)
|
|
|
|
|
|
|
| |
The stub DNS server is authoritative for the RRs we synthesize, such as
localhost, _gateway, and entries from /etc/hosts, and also for trust anchors.
Partially fixes https://github.com/systemd/systemd/issues/17972
|
|
|
|
|
| |
This is extremely useful when debugging stuff: knowing whether a result
was cached, came from network, or was synthesized.
|
|
|
|
|
|
|
|
| |
Let's introduce a new flag that indicates whether the response was
acquired in "confidential" mode, i.e. via encrypted DNS-over-TLS, or
synthesized locally.
Fixes: #12859
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Let's use the same flags type we use for client communication, i.e.
instead of "bool answer_authenticated", let's use "uint64_t
answer_query_flags", with the SD_RESOLVED_AUTHENTICATED flag.
This is mostly just search/replace, i.e. a refactoring, no change in
behaviour.
This becomes useful once in a later commit SD_RESOLVED_CONFIDENTIAL is
added to indicate resolution that either were encrypted (DNS-over-TLS)
or never left the local system.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Follow-up for 4ea8b443de. The logic that manages DnsQueryCandidate is rather
complicated: a calls to dns_query_complete() that wants to destroy a
DnsQueryCandidate can be nested inside a deep chain of calls. Using reference
counts seems like the simplest approach.
DnsSearchDomain already uses reference counting.
This patch effectively brings dns_query_candidate_go() to the state before
4ea8b443de, but wraps the iteration over DnsQueryCandidate.transactions in
dns_query_candidate_ref+dns_query_candidate_unref.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DnsPacket should better be a "dead" object, i.e. list facts, not track
resources. By including an fd in its fields it started tracking
resources however, without actually taking a ref to the fd (i.e. no
dup() or so was called on it).
Let's hence rework things so that we don#t have to keep track of the fd
a packet came in from. Instead, pass around the DnsStubListenerExtra
object wherever we need to.
This should be useful as soon as we start caching whole DnsPacket
objects to allow replying to DNSSEC/CO packets, i.e. where we have to
keep a copy of the original DnsPacket around for a long time in cache,
potentially much longer than the fds the packet was received on.
|
|
|
|
|
|
| |
This allows us to later port nss-resolve to use Varlink rather than
D-Bus for resolution. This has the benefit that nss-resolve based
resoluton works even without D-Bus being up. And it's faster too.
|
|
|
|
|
|
|
|
| |
It's strictly bus-specific, hence let's move this to resolved-bus.c like
the rest of the bus specific logic.
This is also in preparation for adding an alternative varlink transport,
which needs similar functionality, but varlink instead of bus-specific.
|
|
|
|
|
|
| |
Let's prepare for adding a new varlink interface, and thus rename the
"request" field to "bus_request", so that we can later add a
varlink_request field too.
|
|
|
|
| |
It's unused since 90bdc8be66765df09bbc355783cee7204a5ebb31.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
|
|
|
|
|
| |
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
|
|
|
|
|
|
|
| |
answer
When following a CNAME chain, don't set the authenticated bit, unless
all lookups in the chain could be authenticated.
|
|
|
|
|
|
|
|
| |
Clients expect us to follow CNAMEs for them, hence do so. On the first
iteration start putting together a packet, and then keep adding data we
acquire through CNAMEs to it, until we finally send it off.
Fixes: #3826
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In order to improve compatibility with local clients that speak DNS directly
(and do not use NSS or our bus API) listen locally on 127.0.0.53:53 and process
any queries made that way.
Note that resolved does not implement a full DNS server on this port, but
simply enough to allow normal, local clients to resolve RRs through resolved.
Specifically it does not implement queries without the RD bit set (these are
requests where recursive lookups are explicitly disabled), and neither queries
with DNSSEC DO set in combination with DNSSEC CD (i.e. DNSSEC lookups with
validation turned off). It also refuses zone transfers and obsolete RR types.
All lookups done this way will be rejected with a clean error code, so that the
client side can repeat the query with a reduced feature set.
The code will set the DNSSEC AD flag however, depending on whether the data
resolved has been validated (or comes from a local, trusted source).
Lookups made via this mechanisms are propagated to LLMNR and mDNS as necessary,
but this is only partially useful as DNS packets cannot carry IP scope data
(i.e. the ifindex), and hence link-local addresses returned cannot be used
properly (and given that LLMNR/mDNS are mostly about link-local communication
this is quite a limitation). Also, given that DNS tends to use IDNA for
non-ASCII names, while LLMNR/mDNS uses UTF-8 lookups cannot be mapped 1:1.
In general this should improve compatibility with clients bypassing NSS but
it is highly recommended for clients to instead use NSS or our native bus API.
This patch also beefs up the DnsStream logic, as it reuses the code for local
TCP listening. DnsStream now provides proper reference counting for its
objects.
In order to avoid feedback loops resolved will no silently ignore 127.0.0.53
specified as DNS server when reading configuration.
resolved listens on 127.0.0.53:53 instead of 127.0.0.1:53 in order to leave
the latter free for local, external DNS servers or forwarders.
This also changes the "etc.conf" tmpfiles snippet to create a symlink from
/etc/resolv.conf to /usr/lib/systemd/resolv.conf by default, thus making this
stub the default mode of operation if /etc is not populated.
|
|
|
|
|
|
|
|
|
|
|
| |
When we return the full RR wire data, let's make sure the TTL included in it is
adjusted by the time the RR sat in the cache.
As an optimization we do this only for ResolveRecord() and not for
ResolveHostname() and friends, since adjusting the TTL means copying the RR
object, and we don#t want to do that if there's no reason to.
(ResolveHostname() and friends don't return the TTL hence there's no reason to
in that case)
|
|
|
|
|
| |
This should be handled fine now by .dir-locals.el, so need to carry that
stuff in every file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, if a hostanem is resolved with AF_UNSPEC specified, this would be used as indication to resolve both an
AF_INET and an AF_INET6 address. With this change this logic is altered: an AF_INET address is only resolved if there's
actually a routable IPv4 address on the specific interface, and similar an AF_INET6 address is only resolved if there's
a routable IPv6 address. With this in place, it's ensured that the returned data is actually connectable by
applications. This logic mimics glibc's resolver behaviour.
Note that if the client asks explicitly for AF_INET or AF_INET6 it will get what it asked for.
This also simplifies the logic how it is determined whether a specific lookup shall take place on a scope.
Specifically, the checks with dns_scope_good_key() are now moved out of the transaction code and into the query code,
so that we don't even create a transaction object on a specific scope if we cannot execute the resolution on it anyway.
|
|
|
|
|
|
| |
Whenever we encounter an OS error we did not expect, we so far put the transaction into DNS_TRANSACTION_RESOURCES
state. Rename this state to DNS_TRANSACTION_ERRNO, and save + propagate the actual system error to the caller. This
should make error messages triggered by system errors much more readable by the user.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
|
|
|
|
|
| |
This ensures we properly resolve the CNAME chain as far as we can, rather
than only CNAME chains of length one.
|
|
|
|
|
|
| |
the the bus client
It's useful to generate useful errors, so let's do that.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds initial support for validating RRSIG/DNSKEY/DS chains when
doing lookups. Proof-of-non-existance, or proof-of-unsigned-zones is not
implemented yet.
With this change DnsTransaction objects will generate additional
DnsTransaction objects when looking for DNSKEY or DS RRs to validate an
RRSIG on a response. DnsTransaction objects are thus created for three
reasons now:
1) Because a user asked for something to be resolved, i.e. requested by
a DnsQuery/DnsQueryCandidate object.
2) As result of LLMNR RR probing, requested by a DnsZoneItem.
3) Because another DnsTransaction requires the requested RRs for
validation of its own response.
DnsTransactions are shared between all these users, and are GC
automatically as soon as all of these users don't need a specific
transaction anymore.
To unify the handling of these three reasons for existance for a
DnsTransaction, a new common naming is introduced: each DnsTransaction
now tracks its "owners" via a Set* object named "notify_xyz", containing
all owners to notify on completion.
A new DnsTransaction state is introduced called "VALIDATING" that is
entered after a response has been receieved which needs to be validated,
as long as we are still waiting for the DNSKEY/DS RRs from other
DnsTransactions.
This patch will request the DNSKEY/DS RRs bottom-up, and then validate
them top-down.
Caching of RRs is now only done after verification, so that the cache is
not poisoned with known invalid data.
The "DnsAnswer" object gained a substantial number of new calls, since
we need to add/remove RRs to it dynamically now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds a new SD_RESOLVED_AUTHENTICATED flag for responses we return
on the bus. When set, then the data has been authenticated. For now this
mostly reflects the DNSSEC AD bit, if DNSSEC=trust is set. As soon as
the client-side validation is complete it will be hooked up to this flag
too.
We also set this bit whenver we generated the data ourselves, for
example, because it originates in our local LLMNR zone, or from the
built-in trust anchor database.
The "systemd-resolve-host" tool has been updated to show the flag state
for the data it shows.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DnsTransaction objects
Previously we'd only store the DnsPacket in the DnsTransaction, and the
DnsQuery would then take the DnsPacket's DnsAnswer and return it. With
this change we already pull the DnsAnswer out inside the transaction.
We still store the DnsPacket in the transaction, if we have it, since we
still need to determine from which peer a response originates, to
implement caching properly. However, the DnsQuery logic doesn't care
anymore for the packet, it now only looks at answers and rcodes from the
successfuly candidate.
This also has the benefit of unifying how we propagate incoming packets,
data from the local zone or the local cache.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds support for searching single-label hostnames in a set of
configured search domains.
A new object DnsQueryCandidate is added that links queries to scopes.
It keeps track of the search domain last used for a query on a specific
link. Whenever a host name was unsuccessfuly resolved on a scope all its
transactions are flushed out and replaced by a new set, with the next
search domain appended.
This also adds a new flag SD_RESOLVED_NO_SEARCH to disable search domain
behaviour. The "systemd-resolve-host" tool is updated to make this
configurable via --search=.
Fixes #1697
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
|
|
|
|
|
| |
This is a continuation of the previous include sort patch, which
only sorted for .c files.
|