Thursday, July 23, 2015

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

Steps:

  1. Add a new user, accepting defaults.
  2. 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>
    $
    
  3. 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
    #
    
  4. Set it to start on reboot.
    # echo relayd_flags="" >> /etc/rc.conf.local
    #
    
  5. 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 {... and redirect 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.

No comments:

Post a Comment