thoughts/data/relayd-multidomain.md
Tommy Skaug 805a34f937
All checks were successful
Export / Explore-GitHub-Actions (push) Successful in 2m19s
initial migration
2024-08-05 20:24:56 +02:00

3.4 KiB

While running a relayd service for a multi-domain instance recently I quickly came into an issue with relayd routing.

relayd(8) is the relay daemon in OpenBSD.

I run two local services that I front with relayd:

  • service A
  • service B

These two I define in relayd.conf(5):

ext_addr="<SOME-IP>"
honk_port="31337"
inks_port="31338"
table <serviceA> { 127.0.0.1 }
table <serviceB> { 127.0.0.1 }

To make sure relayd logs sufficiently for traceability I apply the following options:

log state changes
log connection

The next part of my relayd.conf is creating a configuration for the relay service ("protocols are templates defining settings and rules for relays"):

http protocol https { }

For the service definition I make sure to add the remote address and local address:

  match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
  match request header append "X-Forwarded-By" \
    value "$SERVER_ADDR:$SERVER_PORT"

A further important logging configuration comes next, and I make sure my relay logs the host, X-Forwarded-For, User-Agent, Referer and url:

match header log "Host"
match header log "X-Forwarded-For"
match header log "User-Agent"
match header log "Referer"
match url log

For performance [1]:

tcp { nodelay, sack, socket buffer 65536, backlog 100 }

Next I disable vulnerable ciphers:

tls no tlsv1.0
tls no tlsv1.1
tls tlsv1.2

Sadly tlsv1.3 is still in -current, so we will have to wait for that.

I configure keys like follows:

tls ca cert "/etc/ssl/cert.pem"
tls keypair serviceA.domain
tls keypair serviceB.domain

Finally we use the tables defined initially to route traffic to the right internal service:

match request header "Host" value "serviceA.domain" forward to <serviceA>
match request header "Host" value "serviceB.domain" forward to <serviceB>

And that is it for the service definition.

In addition we define the relay ("relays will forward traffic between a client and a target server") like follows. The "protocol https" is the junction between the two parts of the config.

relay https_relay {
  listen on $ext_addr port https tls
  protocol https
  
  forward to <honk> port $honk_port check tcp
  forward to <inks> port $inks_port check tcp
}

The whole config:

ext_addr="159.100.245.242" honk_port="31337" inks_port="31338" table { 127.0.0.1 } table { 127.0.0.1 }

log state changes log connection

http protocol https { match request header append "X-Forwarded-For" value "$REMOTE_ADDR" match request header append "X-Forwarded-By"
value "$SERVER_ADDR:$SERVER_PORT" match request header set "Connection" value "close"

match header log "Host" match header log "X-Forwarded-For" match header log "User-Agent" match header log "Referer" match url log

tcp { nodelay, socket buffer 65536, backlog 100 }

tls no tlsv1.0 tls no tlsv1.1 tls tlsv1.2 tls ca cert "/etc/ssl/cert.pem"

tls keypair cybsec.network tls keypair inks.cybsec.network

match request header "Host" value "cybsec.network" forward to match request header "Host" value "inks.cybsec.network" forward to }

relay https_relay { listen on $ext_addr port https tls protocol https

forward to port $honk_port check tcp forward to port $inks_port check tcp }

[1] https://calomel.org/relayd.html