No Hair Blog

Relayd as reverse proxy; blacklisting

OpenBSD relayd was originally a load balancer (hoststated) but has matured into a workable reverse proxy. It does not have the rewrite functionality of nginx or others. For my websites and blog which consist of static pages hosted on a small fanless appliance, relayd is more than adequate to block traffic to httpd and improve security and response time.

The FILTERS stanza below is an example of a working reverse proxy. The language and commands are fairly easy to suss out, even if the examples on the man page are basic and limited.

#
# Filtering rules for reverse proxy
#

http protocol revproxy {

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

#       # Return HTTP/HTML error pages
        return error

#       # Make log more informative for debugging - add connection info to log
        match header log "Host"
        match header log "X-Forwarded-For"
        match header log "User-Agent"
        match header log "Referer"
        match url log

#       # Adjust headers to make httpd logging more informative
        match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
       	match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"

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

        tls keypair "www.example.net"
        tls keypair "www.example.cc"
        tls { no tlsv1.0, ciphers "HIGH" }

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

#       # Block bots and other user agent strings
        block request quick header "User-Agent" value "*Ahrefs*"
        block request quick header "User-Agent" value "*Semrush*"
        block request quick header "User-Agent" value "*Yandex*"
        block request quick header "User-Agent" value "*seznam*"
        block request quick header "User-Agent" value "*MJ12*"

#       # Block request paths containing forbidden file types or URI strings
        block request quick path "/*.dat*"
        block request quick path "/*.asp*"
        block request quick path "/*.xml*"
        block request quick path "/*.png*"
        block request quick path "/*.cfg*"
        block request quick path "/*.ico*"
        block request quick path "*cgi*"
        block request quick path "*php*"
        block request quick path "*wp-*"
        block request quick path "*login*"
        block request quick path "*shell*"

#       # Block all queries
        block request quick query "*" value "*"

#       # Pass GET; drop all other HTTP requests
        pass request quick method "GET" forward to <webserver>
	
#       # Block all requests not passed to this point
        block request

        }

An important point to remember is that relayd uses shell globbing rules, not regex. This limits some of the expression flexibility, but is workable. While the default shell (zsh on OpenBSD) has a fairly robust globbing syntax, the globbing rules in relayd.conf are quite limited (see glob(7)). For example, {text1,text2} type curly bracket substitution does not work.

Blacklisting can easily become cumbersome when one tries to list all the malicious traffic and trash in the httpd logs. So, the next generation is whitelisting with relayd which is under testing. What is still under development is logic based on match and tag directives. This is poorly documented and, at this point, progress has been based on trial and error on lab machines. Configuration details will follow once this is working well.


Posted by Gordon, No Hair Blog, April 12, 2020

© nohair.net and the author

For comments, corrections, and addenda, email: gordon[AT]nohair.net

Blog | Entries | Tags | Home