Transparent Reverse Proxy Using OpenBSD's relayd - updated
You are here: Home > Blog > Entries > Transparent Reverse Proxy Using relayd - updated
Transparent reverse proxy using OpenBSD relayd

[Ed. this is a revised entry of Transparent Reverse Proxy Using relayd updated for OpenBSD -current which is 6.5 at present.]

I've been using OpenBSD's relayd as a reverse proxy in front of OpenBSD's httpd webserver since 6.1. It is a perfectly functional reverse proxy, properly configured, which can perform a variety of filters on incoming HTTP traffic in order to screen and secure a webserver. Prior posts on this topic are here and the link above.

To set this up, first configure pf to pass and redirect HTTP requests to the webserver running at 127.0.0.1. Add the anchor for relayd but comment this out for testing. The relevant pf.conf stanzas are:

...
# Relayd anchor
#anchor "relayd/*"
...
# redirect http traffic to relayd -> httpd (transparent reverse proxy)
pass in proto tcp from any to $lan_if port $wwwports rdr-to 127.0.0.1 port 8080
pass out on $lan_if divert-reply
...

Next, configure httpd to listen on the appropriate port:

...
#
# Macros
#

ext_addr="127.0.0.1"
ext_port="8080"

# Servers
#

# nohair.net web server
server "www.nohair.net" {
        alias "nohair.net"
        listen on $ext_addr port $ext_port
        log style combined
        root "/htdocs/vhosts/nohair.net"
        }
...

Now start PF and httpd and confirm the redirection works. Once that is working to your satisfaction, configure relayd.conf, as follows:

##
## $OpenBSD: relayd.conf,v 1.3 2014/12/12 10:05:09 reyk
## Modified 3/3/18 by gordon

##
## Macros
##

httpd_addr="127.0.0.1"

##
## Global Options
##
# interval 10
# timeout 1000

prefork 3
log connection

##
## Tables
##

table  {127.0.0.1}

##
## Redirections
##

##
## Protocols
##

#
# Filtering rules for reverse HTTP proxy
#

http protocol reverseproxy {

#       # TCP performance options 
        tcp {nodelay, sack, socket buffer 65536, backlog 100 }

#       # Return HTTP/HTML error pages
        return error

#       # Change timeout
        match header set "Keep-Alive" value "$TIMEOUT"

#       # Anonymize our webserver's name/type
        match response header set  "Server" value "Microsoft IIS 9 beta 1"

#       # Pass GET and HEAD; drop all other HTTP requests
        pass request quick method "HEAD" forward to 
        pass request quick method "GET" forward to 
        match request label "HTTP Request Not Allowed"
        block request

        }

##
## Relays
##

#
# Relay for a reverse HTTP proxy
#

relay reverseproxy {

        # listen on pf-rdr redirected port for http and https traffic
        listen on 127.0.0.1 port 8080

        # apply web filters listed above
        protocol reverseproxy

        # transparent forward with pf redirect
        forward to $httpd_addr port 8080

        }


##
## Routers
##

##
## End of /etc/relayd.conf
##

Now, uncomment "anchor "relayd/*" in pf.conf and reload pf, then enable and start relayd. Works fine for me. Changes to relayd have altered the configuration slightly compared to earlier versions. In order to do transparent forwarding, you need to specify the actual ip address of the webserver, not use the table ("<webserver>"). With this, I can now get the passage of the client ip address for proper logging by the webserver. Further, filtering by http query and path can be done (see man relayd.conf for OpenBSD.


Posted by Gordon, No Hair Blog, Sep 18, 2019

© nohair.net and the author