Hello!

I think I found a bug in relayd, but maybe I misunderstood
how to configure it:

Bug reproduced (with a cert setup) as below:

$ cat /etc/relayd.conf:
table <"http"> { 127.0.0.1 }
http protocol "https" {
        tls keypair "lap1.josuah.net"
}
relay "https" {
        listen on 127.0.0.1 port 443 tls
        listen on ::1 port 443 tls
        protocol "https"
        forward to <"http"> port 80 check tcp
}

$ ktrace relayd -dvv # without the patch applied
 ...
 87874 relayd   CALL  open(0x7f7ffffe76d0,0<O_RDONLY>)
 87874 relayd   NAMI  "/etc/ssl/::1:443.crt"
 87874 relayd   RET   open -1 errno 2 No such file or directory
 87874 relayd   CALL  open(0x7f7ffffe76d0,0<O_RDONLY>)
 87874 relayd   NAMI  "/etc/ssl/::1.crt"
 87874 relayd   RET   open -1 errno 2 No such file or directory
 ...

The second "listen" block inherit its configuration from the
first, and /etc/ssl/::1.crt as certificate instead of the
keypair list.

Although, even with the patch it does not work on the extra
listen address (the one replicated):

$ openssl s_client -connect ::1:443 -servername lap1.josuah.net
CONNECTED(00000003)
5110093530528:error:1400A410:SSL routines:CONNECT_CR_CERT_REQ:sslv3 alert 
handshake failure:/usr/src/lib/libssl/tls13_lib.c:129:SSL alert number 40
---
no peer certificate available

If anyone has an idea on how to allow multiple listen
as shown in the example, I am interested.


The patch:

Check that there are no certificates in the keypair list
before searching the default /etc/ssl/$address.crt
certificate.

Index: src/usr.sbin/relayd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.253
diff -u -r1.253 parse.y
--- src/usr.sbin/relayd/parse.y 15 Oct 2021 15:01:28 -0000      1.253
+++ src/usr.sbin/relayd/parse.y 17 Aug 2022 11:52:34 -0000
@@ -3421,7 +3421,8 @@
                goto err;
        }

-       if (relay_load_certfiles(conf, rb, NULL) == -1) {
+       if (TAILQ_EMPTY(&rb->rl_proto->tlscerts) &&
+           relay_load_certfiles(conf, rb, NULL) == -1) {
                yyerror("cannot load certificates for relay %s",
                    rb->rl_conf.name);

Reply via email to