Go, sudo, and apache port 80

bvpx picture bvpx · Jun 28, 2014 · Viewed 12.7k times · Source

I am using gorilla/mux package in golang, but there are some problems. The first is I have no permissions to use port 80 on my application becuase I cannot run the application from sudo as the $GOPATH is not set when using sudo.

Here is the error I get from my program:

$ go run app.go 
2014/06/28 00:34:12 Listening...
2014/06/28 00:34:12 ListenAndServe: listen tcp :80: bind: permission denied
exit status 1

I am unsure if it will even work when I fix the sudo problem, because apache is already using port 80 and I am not sure if both my app and apache can "play nice" together.

Any advice on how to solve this would be great. Thank you.

Answer

Rick-777 picture Rick-777 · Jun 28, 2014

Quoting elithar's comment,

You have two options: either turn off Apache (because only one service can bind to a port), or (better!) use Apache's ProxyPass to proxy any incoming requests to a specific Hostname to your Go server running on port (e.g.) 8000. The second method is very popular, robust, and you can use Apache to handle request logging and SSL for you.

Reverse Proxying

Using Apache on port 80 in this way is called a reverse proxy. It receives all incoming connections on port 80 (and/or port 443 for https) and passes them on, usually unencrypted, via internal localhost connections only, to your Go program running on whatever port you choose. 8000 and 8080 are often used. The traffic between Apache and your server is itself HTTP traffic.

Because your Go program does not run as root, it is unable to alter critical functions on the server. Therefore it gives an extra degree of security, should your program ever contain security flaws, because any attacker would gain only limited access.

FastCGI

You can improve the overall performance of the reverse proxying by not using HTTP for the connection from Apache to the Go server. This is done via the FastCGI protocol, originally developed for shell, Perl and PHP scripts, but working well with Go too. To use this, you have to modify your Go server to listen using the fcgi API. Apache FastCGI is also required. The traffic from Apache to your server uses a more compact format (not HTTP) and this puts less load on each end.

The choice of socket type is also open: instead of the usual TCP sockets, it is possible to use Unix sockets, which reduce the processing load even further. I haven't done this in Go myself, but the API supports the necessary bits (see a related question).

Nginx

Whilst all the above describes using Apache, there are other server products that can provide a reverse proxy too. The most notable is Nginx (Nginx reverse proxy example), which will give you small but useful performance and scalability advantages. If you have this option on your servers, it is worth the effort to learn and deploy.