diff options
-rw-r--r-- | man/resolved.conf.xml | 19 | ||||
-rw-r--r-- | src/resolve/resolved-dnstls-gnutls.c | 20 | ||||
-rw-r--r-- | src/resolve/resolved-dnstls-openssl.c | 15 |
3 files changed, 34 insertions, 20 deletions
diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml index 0f70ced5b5..37161ebcbc 100644 --- a/man/resolved.conf.xml +++ b/man/resolved.conf.xml @@ -193,11 +193,17 @@ <varlistentry> <term><varname>DNSOverTLS=</varname></term> <listitem> - <para>Takes a boolean argument or <literal>opportunistic</literal>. - If true all connections to the server will be encrypted. Note that - this mode requires a DNS server that supports DNS-over-TLS and has - a valid certificate for it's IP. If the DNS server does not support - DNS-over-TLS all DNS requests will fail. When set to <literal>opportunistic</literal> + <para>Takes a boolean argument or <literal>opportunistic</literal>. If + true all connections to the server will be encrypted. Note that this + mode requires a DNS server that supports DNS-over-TLS and has a valid + certificate. If the hostname was specified in <varname>DNS=</varname> + by using the format format <literal>address#server_name</literal> it + is used to validate its certificate and also to enable Server Name + Indication (SNI) when opening a TLS connection. Otherwise + the certificate is checked against the server's IP. + If the DNS server does not support DNS-over-TLS all DNS requests will fail.</para> + + <para>When set to <literal>opportunistic</literal> DNS request are attempted to send encrypted with DNS-over-TLS. If the DNS server does not support TLS, DNS-over-TLS is disabled. Note that this mode makes DNS-over-TLS vulnerable to "downgrade" @@ -214,9 +220,6 @@ resolver is not capable of authenticating the server, so it is vulnerable to "man-in-the-middle" attacks.</para> - <para>Server Name Indication (SNI) can be used when opening a TLS connection. - Entries in <varname>DNS=</varname> should be in format <literal>address#server_name</literal>.</para> - <para>In addition to this global DNSOverTLS setting <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> also maintains per-link DNSOverTLS settings. For system DNS diff --git a/src/resolve/resolved-dnstls-gnutls.c b/src/resolve/resolved-dnstls-gnutls.c index 2a4a95989c..e5dd00692c 100644 --- a/src/resolve/resolved-dnstls-gnutls.c +++ b/src/resolve/resolved-dnstls-gnutls.c @@ -56,15 +56,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { } if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) { - stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS; - if (server->family == AF_INET) { - stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr; - stream->dnstls_data.validation.size = 4; - } else { - stream->dnstls_data.validation.data = server->address.in6.s6_addr; - stream->dnstls_data.validation.size = 16; + if (server->server_name) + gnutls_session_set_verify_cert(gs, server->server_name, 0); + else { + stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS; + if (server->family == AF_INET) { + stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr; + stream->dnstls_data.validation.size = 4; + } else { + stream->dnstls_data.validation.data = server->address.in6.s6_addr; + stream->dnstls_data.validation.size = 16; + } + gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0); } - gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0); } if (server->server_name) { diff --git a/src/resolve/resolved-dnstls-openssl.c b/src/resolve/resolved-dnstls-openssl.c index 8f58efacbd..7763cbcb5a 100644 --- a/src/resolve/resolved-dnstls-openssl.c +++ b/src/resolve/resolved-dnstls-openssl.c @@ -6,6 +6,7 @@ #include <openssl/bio.h> #include <openssl/err.h> +#include <openssl/x509v3.h> #include "io-util.h" #include "resolved-dns-stream.h" @@ -80,13 +81,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) { X509_VERIFY_PARAM *v; - const unsigned char *ip; SSL_set_verify(s, SSL_VERIFY_PEER, NULL); v = SSL_get0_param(s); - ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr; - if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0) - return -ECONNREFUSED; + if (server->server_name) { + X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + if (X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0) + return -ECONNREFUSED; + } else { + const unsigned char *ip; + ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr; + if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0) + return -ECONNREFUSED; + } } if (server->server_name) { |