Go, sudo, and apache port 80
Asked Answered
R

2

11

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.

Roemer answered 28/6, 2014 at 0:40 Comment(4)
possible duplicate of Golang production web application configurationVexillum
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.Tish
@Tish i am new to golang and web programming can you provide me some of Apache's ProxyPass and how we will handling it golang i will be very thankfulErnie
Have you tried building the application with go build app.go and then executing it with sudo ./app?Fancyfree
M
8

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.

Midcourse answered 28/6, 2014 at 20:15 Comment(0)
R
-2

Based on this previous answer about environment variables, I was able to solve the sudo problem easily.

https://mcmap.net/q/64372/-how-to-keep-environment-variables-when-using-sudo-closed

 sudo visudo

added these lines:

Defaults env_keep +="GOPATH"
Defaults env_keep +="GOROOT"

Using ubuntu 12.04 by the way. I think the previous answer about the proxy for using port 80 is the correct choice, because after fixing the sudo issue I was given this error about port 80 instead:

$ sudo go run app.go 
2014/06/28 01:26:30 Listening...
2014/06/28 01:26:30 ListenAndServe: listen tcp :80: bind: address already in use
exit status 1

Meaning the sudo command was fixed but the proxy binding would not work with another service already using port 80 (apache).

Roemer answered 28/6, 2014 at 1:31 Comment(2)
See my comment on your question for a better solution. Notably, running your Go application as root is NOT good security practice. You either give it a capability to bind to port 80 (only) or reverse proxy it behind Apache.Tish
Could you write it as an answer so I can accept it?Roemer

© 2022 - 2024 — McMap. All rights reserved.