Securing web applications with
relayd
Combination of httpd and relayd in
OpenBSD is quite versatile. I have a web application which should not
have any human users, but is used to send messages back and forth
between two remote systems in a secure way. The application is set up
where it verifies messages it receives and does something with those
messages. The details are not important. What is important is that it
only has one endpoint, let's call it /inbound/call.
So far, all requests coming to the subdomain that hosts this
application would go through the webserver which would gladly serve a
404 or other error code.
To further lock it down, I blocked all other paths and methods from
ever reaching the webserver, removing responsibility from myself. relayd
can easily do this.
block
pass request header "Host" value "sub.domain.com" method POST path "/inbound/call" forward to <dest>Now, all other paths, methods, and hosts are filtered out and only
that single endpoint hits the webserver. An example of a full
relayd.conf is here:
log state changes
log connection errors
table <myapp> { 127.0.0.1 }
http protocol www {
tls keypair www.myapp.com
match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
match request header append "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
match response header remove "Server"
match response header append "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"
match response header append "X-Frame-Options" value "SAMEORIGIN"
match response header append "X-XSS-Protection" value "1; mode=block"
match response header append "X-Content-Type-Options" value "nosniff"
match response header append "Referrer-Policy" value "strict-origin"
match response header append "Permissions-Policy" value "accelerometer=(none), camera=(none), geolocation=(none), gyroscope=(none), magnetometer=(none), microphone=(none), payment=(none), usb=(none)"
tcp { nodelay, sack, socket buffer 65536, backlog 100 }
block
pass request header "Host" value "calls.myapp.com" method POST path "/inbound/call" forward to <myapp>
}
relay myrelays {
listen on 0.0.0.0 port 443 tls
protocol www
forward to <myapp> port 8080
}