diff options
author | 2019-04-01 03:31:55 +0000 | |
---|---|---|
committer | 2019-04-01 03:31:55 +0000 | |
commit | 3461bfbe26fa73f3bbe2417f40539d34ecb631c5 (patch) | |
tree | c91e57ca843638531297ab271606beba65363651 | |
parent | deprecate TASKQ_CANTSLEEP since nothing uses it anymore (diff) | |
download | wireguard-openbsd-3461bfbe26fa73f3bbe2417f40539d34ecb631c5.tar.xz wireguard-openbsd-3461bfbe26fa73f3bbe2417f40539d34ecb631c5.zip |
Implement "Authentication Domain Names" configuration as per RFC 8310
section 7.1 for DoT servers.
We are setting the CA cert bundle path (/etc/ssl/cert.pem) directly in
libunbound so we need to losen pledge(2) a bit and allow rpath. At the
same time we unveil only /etc/ssl/cert.pem. We can drop the chroot(2)
since pledge(2) and unveil(2) give us more fine grained isolation.
prodding by tb@.
p.s. for portable it might be necessary to pass in a file descriptor
from the parent, slurp in the file and then use X509_STORE_load_mem()
(pointed out by sthen) in the guts of libunbound.
-rw-r--r-- | sbin/unwind/parse.y | 70 | ||||
-rw-r--r-- | sbin/unwind/printconf.c | 27 | ||||
-rw-r--r-- | sbin/unwind/resolver.c | 19 | ||||
-rw-r--r-- | sbin/unwind/unwind.conf.5 | 8 |
4 files changed, 103 insertions, 21 deletions
diff --git a/sbin/unwind/parse.y b/sbin/unwind/parse.y index 5691b9d7a36..8d813589cd2 100644 --- a/sbin/unwind/parse.y +++ b/sbin/unwind/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.1 2019/03/01 08:02:25 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.2 2019/04/01 03:31:55 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -100,7 +100,7 @@ typedef struct { %token STRICT YES NO INCLUDE ERROR %token FORWARDER DOT PORT CAPTIVE PORTAL URL EXPECTED RESPONSE -%token STATUS AUTO +%token STATUS AUTO AUTHENTICATION NAME %token <v.string> STRING %token <v.number> NUMBER @@ -359,6 +359,70 @@ forwarderoptsl : STRING { &conf->uw_dot_forwarder_list, uw_forwarder, entry); } + | STRING AUTHENTICATION NAME STRING DOT { + int ret; + struct sockaddr_storage *ss; + if ((ss = host_ip($1)) == NULL) { + yyerror("%s is not an ip-address", $1); + free($1); + YYERROR; + } + free(ss); + + if ((uw_forwarder = calloc(1, + sizeof(*uw_forwarder))) == NULL) + err(1, NULL); + + ret = snprintf(uw_forwarder->name, + sizeof(uw_forwarder->name), "%s#%s", $1, + $4); + if (ret == -1 || (size_t)ret >= + sizeof(uw_forwarder->name)) { + free(uw_forwarder); + yyerror("forwarder %s too long", $1); + free($1); + YYERROR; + } + + SIMPLEQ_INSERT_TAIL( + &conf->uw_dot_forwarder_list, uw_forwarder, + entry); + } + | STRING PORT NUMBER AUTHENTICATION NAME STRING DOT { + int ret; + struct sockaddr_storage *ss; + if ((ss = host_ip($1)) == NULL) { + yyerror("%s is not an ip-address", $1); + free($1); + YYERROR; + } + free(ss); + + if ($3 <= 0 || $3 > (int)USHRT_MAX) { + yyerror("invalid port: %lld", $3); + free($1); + YYERROR; + } + + if ((uw_forwarder = calloc(1, + sizeof(*uw_forwarder))) == NULL) + err(1, NULL); + + ret = snprintf(uw_forwarder->name, + sizeof(uw_forwarder->name), "%s@%d#%s", $1, + (int)$3, $6); + if (ret == -1 || (size_t)ret >= + sizeof(uw_forwarder->name)) { + free(uw_forwarder); + yyerror("forwarder %s too long", $1); + free($1); + YYERROR; + } + + SIMPLEQ_INSERT_TAIL( + &conf->uw_dot_forwarder_list, uw_forwarder, + entry); + } ; %% @@ -395,12 +459,14 @@ lookup(char *s) /* This has to be sorted always. */ static const struct keywords keywords[] = { {"DoT", DOT}, + {"authentication", AUTHENTICATION}, {"auto", AUTO}, {"captive", CAPTIVE}, {"dot", DOT}, {"expected", EXPECTED}, {"forwarder", FORWARDER}, {"include", INCLUDE}, + {"name", NAME}, {"no", NO}, {"port", PORT}, {"portal", PORTAL}, diff --git a/sbin/unwind/printconf.c b/sbin/unwind/printconf.c index 1e2747e29a0..78dcdab2824 100644 --- a/sbin/unwind/printconf.c +++ b/sbin/unwind/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.6 2019/02/17 14:49:15 florian Exp $ */ +/* $OpenBSD: printconf.c,v 1.7 2019/04/01 03:31:55 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -38,17 +38,28 @@ yesno(int flag) void print_forwarder(char *name) { - char *pos; + char *port_pos, *name_pos; - pos = strchr(name, '@'); + port_pos = strchr(name, '@'); + name_pos = strchr(name, '#'); - if (pos != NULL) { - *pos = '\0'; - printf("%s port %s", name, pos + 1); - *pos = '@'; + if (port_pos != NULL) { + *port_pos = '\0'; + if (name_pos != NULL) { + *name_pos = '\0'; + printf("%s port %s authentication name %s", name, + port_pos + 1, name_pos + 1); + *name_pos = '#'; + } else { + printf("%s port %s", name, port_pos + 1); + } + *port_pos = '@'; + } else if (name_pos != NULL) { + *name_pos = '\0'; + printf("%s authentication name %s", name, name_pos + 1); + *name_pos = '#'; } else printf("%s", name); - } void diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c index 74fdfefcc4c..9932c5fd6a0 100644 --- a/sbin/unwind/resolver.c +++ b/sbin/unwind/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.30 2019/03/31 00:57:41 tedu Exp $ */ +/* $OpenBSD: resolver.c,v 1.31 2019/04/01 03:31:55 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -35,6 +35,7 @@ #include <stdlib.h> #include <string.h> #include <time.h> +#include <tls.h> #include <unistd.h> #include "libunbound/config.h" @@ -183,11 +184,6 @@ resolver(int debug, int verbose) if ((pw = getpwnam(UNWIND_USER)) == NULL) fatal("getpwnam"); - if (chroot(pw->pw_dir) == -1) - fatal("chroot"); - if (chdir("/") == -1) - fatal("chdir(\"/\")"); - uw_process = PROC_RESOLVER; setproctitle("%s", log_procnames[uw_process]); log_procinit(log_procnames[uw_process]); @@ -197,7 +193,10 @@ resolver(int debug, int verbose) setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("can't drop privileges"); - if (pledge("stdio inet dns recvfd", NULL) == -1) + if (unveil(tls_default_ca_cert_file(), "r") == -1) + fatal("unveil"); + + if (pledge("stdio inet dns rpath recvfd", NULL) == -1) fatal("pledge"); ev_base = event_init(); @@ -573,7 +572,7 @@ resolver_dispatch_main(int fd, short event, void *bula) event_add(&iev_captiveportal->ev, NULL); break; case IMSG_STARTUP: - if (pledge("stdio inet dns", NULL) == -1) + if (pledge("stdio inet dns rpath", NULL) == -1) fatal("pledge"); break; case IMSG_RECONF_CONF: @@ -861,6 +860,8 @@ new_static_dot_forwarders(void) static_dot_forwarder = create_resolver(STATIC_DOT_FORWARDER); set_forwarders(static_dot_forwarder, &resolver_conf->uw_dot_forwarder_list); + ub_ctx_set_option(static_dot_forwarder->ctx, "tls-cert-bundle:", + tls_default_ca_cert_file()); ub_ctx_set_tls(static_dot_forwarder->ctx, 1); check_resolver(static_dot_forwarder); @@ -995,6 +996,8 @@ check_resolver(struct uw_resolver *res) case STATIC_DOT_FORWARDER: set_forwarders(check_res, &resolver_conf->uw_dot_forwarder_list); + ub_ctx_set_option(check_res->ctx, "tls-cert-bundle:", + tls_default_ca_cert_file()); ub_ctx_set_tls(check_res->ctx, 1); break; case RESOLVER_NONE: diff --git a/sbin/unwind/unwind.conf.5 b/sbin/unwind/unwind.conf.5 index 3a7f48549b0..b2b1f7d88a3 100644 --- a/sbin/unwind/unwind.conf.5 +++ b/sbin/unwind/unwind.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: unwind.conf.5,v 1.7 2019/02/05 19:39:19 jmc Exp $ +.\" $OpenBSD: unwind.conf.5,v 1.8 2019/04/01 03:31:56 florian Exp $ .\" .\" Copyright (c) 2018 Florian Obser <florian@openbsd.org> .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 5 2019 $ +.Dd $Mdocdate: April 1 2019 $ .Dt UNWIND.CONF 5 .Os .Sh NAME @@ -63,12 +63,14 @@ forwarder { $fwd1 $fwd2 } .Ed .Sh GLOBAL CONFIGURATION .Bl -tag -width Ds -.It Ic forwarder Brq Ar address Oo Ic port Ar number Oc Oo Ic DoT Oc ... +.It Ic forwarder Brq Ar address Oo Ic port Ar number Oc Oo Oo Ic authentication name Ar name Oc Ic DoT Oc ... A list of addresses of DNS name servers to forward queries to. If .Ic DoT is specified, use DNS over TLS when sending queries to the server at .Ar address . +.Ar name +validates the certificate of the DNS over TLS server. .El .Pp .Nm unwind |