Proxy golang web server with relayd on OpenBSD 5.7
If you are new to OpenBSD, you may wonder why the httpd daemon that in the base install does not provide the ability to proxy web requests. The reason is that this capability is already provided in base by another daemon called relayd.
This post gives you a quick recipe for how to setup relayd to proxy http requests to a golang web server running as a non-priviledged user. Note that this barely scratches the surface of what relayd can do; for more info, you can read
- Basic relayd Config (cont)
- Recent work in OpenBSD relayd
- Relayd: a load balancer for OpenBSD - SlideShare
- relayd/etc/relayd.conf
- relayd(8)
- relay.conf(5)
Steps:
- Add a new user, accepting defaults.
- As that user, start up golang web server, listening on port 8080.
$ cat > srv.go package main import ( "fmt" "log" "net/http" "time" ) func withalog(h http.Handler) http.Handler { f := func(w http.ResponseWriter, r *http.Request) { fmt.Printf( "%s - - [%s] \"%s %s %s\"\n", r.Header["X-Forwarded-For"], //r.RemoteAddr, time.Now().Format("02/Jan/2006 03:04:05 EST"), r.Method, r.URL, r.Proto) h.ServeHTTP(w, r) } return http.HandlerFunc(f) } func main() { handler := http.FileServer(http.Dir("/usr/share/doc")) log.Fatal(http.ListenAndServe(":8080", withalog(handler))) } ^D $ go build srv.go $ ./srv & $ curl http://127.0.0.1:8080/../.. [] - - [04/Jul/2015 10:20:21 EST] "GET / HTTP/1.1" <pre> <a href="mg/">mg/ </pre> $
- Configure relayd to forward 80 to 8080
# cat > /etc/relayd.conf http protocol "littleproto" { return error match request header append "X-Forwarded-For" \ value "$REMOTE_ADDR" } relay myproxy { listen on 192.168.30.6 port 80 protocol "littleproto" forward to 127.0.0.1 port 8080 } ^D # relayd -n configuration OK #
- Set it to start on reboot.
# echo relayd_flags="" >> /etc/rc.conf.local #
- Start it and test.
# relayd # curl http://192.168.30.6 <pre> <a href="mg/">mg/ </pre>
Questions
- What does
return error
do in http protocol? - Tells relayd to return an error pages. If you don't specify the
style option (see man page), this is the default styling:
- If I just want a http reverse proxy, do I need to configure PF?
- No.
- What's the differences between
relay httpproxy {...
andredirect www {...
, both of which are in/etc/examples/relayd.conf
. - Not 100% sure. From reading relay.conf(5), it says that a redirection does stateful forwarding, and a relay is for general purpose TCP proxy.