Mastodon Mastodon Mastodon Systeemkabouter blog – How I run multiple TLS secured websites using OpenBSD httpd

How I run multiple TLS secured websites using OpenBSD httpd

Posted on zo 24 oktober 2021 in openbsd

I was trying to add another TLS secured website to the openbsd httpd instance hosting this website. Apparently this is possible, but not totally how I expected. The thing is that httpd will happily serve multiple TLS secured websites using the SNI (Server Name Indication) option, but it will only do so using a shared TLS certificate/key.

Where in apache httpd or nginx, you can specify a separate key/certificate per website, openbsd httpd currently only allows you to configure a single certificate/key used by all co figured sites. If you just create a certificate that is valid for multiple domain names it all works fine. When checking the certificate client side, you will see the names of all the domains where this certificate is valid for.

The alternatives mentioned are running relayd instead of httpd or just using multiple IP adresses instead of using SNI.

For reference a config sample that should work:

server "example.org" {
  listen on * tls port 443
  root "/htdocs/example_org"
  tls {
    certificate "/etc/ssl/example.org.pem"
    key "/etc/ssl/private/example.org.key"
  }

  directory {
    index "index.html"
  }

  location "/.well-known/acme-challenge/*" {
    root "/acme"
    request strip 2
  }
}

server "second-example.com" {
  listen on * tls port 443
  root "/htdocs/second-example_com"
  tls {
    certificate "/etc/ssl/example.org.pem"
    key "/etc/ssl/private/example.org.key"
  }

  directory {
    index "index.html"
  }

  location "/.well-known/acme-challenge/*" {
    root "/acme"
    request strip 2
  }
}

I use acme-client to fetch a Lets Encrypt certificate. THe config now looks similar to this:

authority letsencrypt {
  api url "https://acme-v02.api.letsencrypt.org/directory"
  account key "/etc/ssl/private/letsencrypt.key"
}

domain example.org {
  domain key "/etc/ssl/private/example.org.key"
  domain certificate "/etc/ssl/example.org.crt"
  domain full chain certificate "/etc/ssl/example.org.pem"
  sign with letsencrypt
  alternative names { www.example.org, second-example.org, www.second-example.org }
}