Using httpd to add ACME Challenge support to existing relayd setup

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Using httpd to add ACME Challenge support to existing relayd setup

BergenBergen BergenBergen
Hi!

I have some webapps that need Let's Encrypt certificates. I currently
use relayd to forward matching hostnames to my Ruby on Rails ports
(https://puma.io/), and was wondering what would be the ideal way of
adding ACME Challenge support to this setup?

So far I've added an ACME challenge table, a port and a forward rule.
I've also enabled httpd, and attempted to set up a catch-all directive
listening on port 5000. Unfortunately though it doesn't work, so any
feedback or criticism would be greatly appreciated!

Thanks!

Regards,
Murk

--

% acme-client -v mysite.com
acme-client: Fetching http://mysite.com/.well-known/acme-challenge
/TgxaQYLZ0iwwH4VR-Ss5Zf6sBGxlKvn8ra8V-o4SpLs: Connection refused

--

# relayd.conf

localhost="lo0"
ext_if="vio0"

table <acme_challenge> { $localhost }
acme_challenge_port="5000"

table <mysite> { $localhost }
mysite_port="8080"

table <mysite2> { $localhost }
mysite2_port="8081"

http protocol "http" {
  pass request quick path "/.well-known/acme-challenge/*" forward to
<acme_challenge>

  pass request header "Host" value "mysite.com" forward to <mysite>
  pass request header "Host" value "www.mysite.com" forward to <mysite>

  pass request header "Host" value "mysite2.com" forward to <mysite2>
  pass request header "Host" value "www.mysite2.com" forward to <mysite2>
}

http protocol "https" {
  pass request header "Host" value "mysite.com" forward to <mysite>
  pass request header "Host" value "www.mysite.com" forward to <mysite>
  tls keypair "mysite"

  pass request header "Host" value "mysite2.com" forward to <mysite2>
  pass request header "Host" value "www.mysite2.com" forward to <mysite2>
  tls keypair "mysite2"

  # Preserve address headers
  match header set "X-Client-IP" value "$REMOTE_ADDR:$REMOTE_PORT"
  match header set "X-Forwarded-For" value "$REMOTE_ADDR"
  match header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"

  # Best practice security headers
  # https://securityheaders.com/
  match response header remove "Server"
  match response header set "X-Frame-Options" value "SAMEORIGIN"
  match response header set "X-XSS-Protection" value "1; mode=block"
  match response header set "Referrer-Policy" value "strict-origin"
  match response header set "Feature-Policy" value "accelerometer
'none'; ambient-light-sensor 'none'; battery 'none'; camera 'none';
geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone
'none'; midi 'none'; payment 'none'; usb 'none';"

  # Log extras
  match header log "Host"
  match header log "X-Forwarded-For"
  match header log "User-Agent"
  match header log "Referer"
  match url log
}

relay "http" {
  listen on $ext_if port http

  protocol "http"

  forward to <acme_challenge> port $acme_challenge_port
  forward to <mysite> port $mysite_port
  forward to <mysite2> port $mysite2_port
}

relay "https" {
  listen on $ext_if port https tls

  protocol "https"

  # Assumes that Rails has force HTTPS enabled
  # https://api.rubyonrails.org/classes/ActionDispatch/SSL.html
  forward to <mysite> port $mysite_port
  forward to <mysite2> port $mysite2_port
}

--

# httpd.conf

types {
  include "/usr/share/misc/mime.types"
}

localhost="lo0"
acme_challenge_port="5000"

server "*" {
  listen on $localhost port $acme_challenge_port
  root "/"
  location "/.well-known/acme-challenge/*" {
    root "/acme"
    request strip 2
  }
}

--

# acme-client.conf

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

domain mysite.com {
  alternative names { www.mysite.com }
  domain key "/etc/ssl/private/mysite.key"
  domain full chain certificate "/etc/ssl/mysite.crt"
  sign with letsencrypt
}

domain mysite2.com {
  alternative names { www.mysite2.com }
  domain key "/etc/ssl/private/mysite2.key"
  domain full chain certificate "/etc/ssl/mysite2.crt"
  sign with letsencrypt
}