On Tue Oct 20, 2026 at 05:35:53PM -0700, James J. Lippard wrote:
> I have multiple servers listening on the same host and port and using
> "ticket lifetime default" in their tls config blocks.  Now httpd
> crashes out on the first ticket rekey with:
> 
> httpd[6452]: fatal in server: proc_dispatch: server 2 got invalid imsg 23 
> peerid -1 from parent 1
> 
> The parent starts a rekey timer for every non-location TLS server
> block and sends IMSG_TLSTICKET_REKEY with that block's id. In the
> server processes, blocks sharing a socket are merged, the first
> becomes the struct server and the rest are attached as srv_hosts.
> server_byid() only searches the top-level servers, so the rekey for
> any merged block finds nothing.  In OpenBSD 7.9 those misses were
> ignored:
> 
>               srv = server_byid(key.tt_id);
>               if (srv) {
>                       tls_config_add_ticket_key(...);
>               }
> 
> but in 8.0 it returns -1 which proc_dispatch() reports as "invalid imsg"
> and turns into fatalx().  Using -vv the line before the fatal is
> the "invalid sever id" (typo in source) message; here's a patch that
> makes it non-fatal again":
> 
> Index: usr.sbin/httpd/server.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/httpd/server.c,v
> diff -u -p -r1.143 server.c
> --- usr.sbin/httpd/server.c   15 Oct 2026 10:59:00 -0000      1.143
> +++ usr.sbin/httpd/server.c   20 Oct 2026 00:00:00 -0000
> @@ -1425,8 +1425,14 @@ server_dispatch_parent(int fd, struct pr
>               memcpy(&key, imsg->data, sizeof(key));
>               /* apply to the right server */
>               if ((srv = server_byid(key.tt_id)) == NULL) {
> -                     log_debug("%s: invalid sever id", __func__);
> -                     return (-1);
> +                     /*
> +                      * Not a listening server, but a name-based host
> +                      * merged onto another server's socket; their shared
> +                      * TLS context is rekeyed via the listening server.
> +                      */
> +                     log_debug("%s: ignoring rekey for server id %u",
> +                         __func__, key.tt_id);
> +                     break;
>               }
>               if (tls_config_add_ticket_key(srv->srv_tls_config,
>                   key.tt_keyrev, key.tt_key, sizeof(key.tt_key)) == -1) {

Hi James,

thanks for the report and the patch.

I think the stricter imsg handling in 8.0 found a real problem. The TLS
config is per socket, not per server block. Only the first server on a
socket sets up the tls_config. For the other virtual servers only the
cert/key (for SNI) is used, so their "ticket lifetime" has no effect.

This also means: if the first server has no ticket lifetime but a later
one has, tickets are disabled for the whole socket, without any warning.
Welcome to the httpd.conf/parse.y madness where everything is valid!

So I would do this in two steps:

1) Replace the return (-1) with your patch, so httpd does not crash.

2) Make the config stricter: warn (or fail) in parse.y if servers on
   the same socket have different TLS settings, start rekey timers only
   for the listening server, and document in httpd.conf(5) that these
   TLS options apply per socket.

kirill@ are you ok with this?

Rafael

Reply via email to