%

Relayd: Manage HTTP headers

Article published the ; modified the
4 minutes to read

This article has 691 words.
RAW source of the article:
Commit version: e21600e

Description

OpenBSD has, by default, in basesystem, since 5.7:

  • a webserver, named httpd,

  • un server relay, named relayd

  • Webiste: https://bsd.plumbing/

  • OpenBSD: 6.6, 6.7


httpd is not able to manage HTTP headers; and the author do not want it!

So we pass the relay to the relayd server which is able to do it; so, it does in the global manner, not-domain specific.

Configuration

We need to modify the httpd and relayd configuration, i.e.:

  • relayd will receive all traffic on web port and redirects to localhost on corresponding ports. Off course, il possible to act on both IPv4 and IPv6 protocols.
  • httpd will query only the localhost on the dedicated ports.

Do not forget to restart both daemons after modyfing the configuration.

httpd

  • File configuration is: /etc/httpd.conf

Into the context server, we need to set 3 importants details:

  • listen on: the listener on the localhost — cf : listen on
  • log: the logger; you need to modify the option style to forwarder paramater — cf : style
Info

Only, the HSTS header is managed differently:

httpd: HSTS

We can modify the HSTS header by using simply the option hsts (cf : hsts).

It is managed, of course, in the context of the HTTPS protocol, via TLS .

httpd: example

Code: httpd

server "domain.tld" {

    listen on 127.0.0.1 port 80
    listen on ::1 port 80 
    
    # enable hsts only if you use TLS for HTTPS
    hsts {
		max-age 63072000
		preload
		subdomains
    }

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

    location "/" {
        directory index index.html
    } 

    log {
        access "domain.tld/access.log"
        error  "domain.tld/errors.log"
        style forwarded
    }

    root "/htdocs/domain.tld/www"
}

httpd: log

Here is a log example:

domain.tld 127.0.0.1 - - [06/May/2020:04:08:51 +0200] "GET / HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 66.249.79.202 - domain.tld 127.0.0.1 - - [06/May/2020:09:48:36 +0200] "GET /robots.txt HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" 5.196.87.174 - domain.tld 127.0.0.1 - - [06/May/2020:10:29:29 +0200] "GET / HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" 54.36.148.31 -

We remark that address IP of the client is specified on the end of the line. It’s due to the parameter forwarder.

relayd

  • File configuration is: /etc/relayd.conf

In the facts:

  • We declare a http protocol
  • the matching filters match to create the responses headers.
    • both first values are needed to capture and redirect correctly:
      • $SERVER_ADDR:$SERVER_PORT for X-Forwarded-By parameter,
      • $REMOTE_ADDR for X-Forwarded-For parameter.
  • next, we relay by setting the matching relay :
    • listen: the listener on the public address IP and the web port,
    • when we target the http protocol to apply the rules on the headers
    • forward: to redirect to the localhost, and the choosed port, matching to the one the httpd server listen on.

relayd: Httpoxy

Someone, more attentives, have seen the follow declaration:

match request header remove "Proxy"

This is usefull to mitigate the Httpoxy vulnerability that affect CGI, PHP applications.

It is recognized as the best way to block this. Another way to protect you is to use HTTPS .

relayd: example

Code: relayd

ip4 = "ipv4_public_address"
ip6 = "ipv6_public_address"

http protocol "hw" {
    match request header set "X-Forwarded-By"   value "$SERVER_ADDR:$SERVER_PORT"    
    match request header set "X-Forwarded-For"  value "$REMOTE_ADDR"

    match request header remove "Proxy"

    match response header set "Cache-Control"           value "max-age=1814400"
    match response header set "Content-Security-Policy" value "upgrade-insecure-requests; default-src https: 'self'"
    match response header set "Permissions-Policy"      value "fullscreen=(), geolocation=(), microphone()"
    match response header set "Frame-Options"           value "SAMEORIGIN"
    match response header set "Referrer-Policy"         value "strict-origin"
    match response header set "Server"                  value "OpenBSD Relayd+httpd"
    
    match response header set "X-Content-Type-Options" value "nosniff"
    match response header set "X-Download-Options"     value "noopen"
    match response header set "X-Frame-Options"        value "SAMEORIGIN"
    match response header set "X-Powered-By"           value "!"
    match response header set "X-Robots-Tag"           value "index, nofollow"
    match response header set "X-Xss-Protection"       value "1; mode=block"
    
    tcp { nodelay, sack, socket buffer 65536, backlog 100 }
    
    pass
}

relay "www" {
    listen on $ip4 port 80
    protocol hw
    forward to 127.0.0.1 port 80
}

relay "www6" {
    listen on $ip6 port 80
    protocol hw
    forward to ::1 port 80
}

Documentations

Manpages

Autres documentations