Go, sudo, and apache port 80

huangapple go评论106阅读模式
英文:

Go, sudo, and apache port 80

问题

我正在使用golang中的gorilla/mux包,但是遇到了一些问题。首先,我没有权限在我的应用程序上使用端口80,因为当使用sudo时,$GOPATH没有设置,所以无法从sudo运行应用程序。

这是我从程序中得到的错误信息:

$ 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

我不确定在解决sudo问题后是否会起作用,因为apache已经在使用端口80,我不确定我的应用程序和apache是否可以“友好共存”。

对于如何解决这个问题的任何建议都将非常有帮助。谢谢。

英文:

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.

答案1

得分: 8

引用elithar的评论,

> 你有两个选择:要么关闭Apache(因为只有一个服务可以绑定到一个端口),要么(更好!)使用Apache的ProxyPass将任何传入的请求代理到特定主机名上运行的Go服务器,该服务器运行在(例如)8000端口上。第二种方法非常流行、稳定,并且您可以使用Apache来处理请求日志和SSL。

反向代理

以这种方式在端口80上使用Apache被称为反向代理。它接收所有传入的连接在端口80(和/或端口443用于https),并将它们通过内部本地主机连接,通常是未加密的,传递给您选择的任何端口上运行的Go程序。通常使用8000和8080。Apache和您的服务器之间的流量本身就是HTTP流量

由于您的Go程序不以root身份运行,因此无法更改服务器上的关键功能。因此,如果您的程序包含安全漏洞,它会提供额外的安全性,因为任何攻击者只能获得有限的访问权限。

FastCGI

您可以通过不使用HTTP从Apache到Go服务器的连接来提高反向代理的整体性能。这是通过FastCGI协议实现的,该协议最初用于shell、Perl和PHP脚本,但在Go中也可以很好地工作。要使用此功能,您必须修改Go服务器以使用fcgi API进行侦听。还需要Apache FastCGI。从Apache到您的服务器的流量使用更紧凑的格式(而不是HTTP),这会减少每一端的负载。

套接字类型的选择也是开放的:可以使用Unix套接字而不是通常的TCP套接字,这样可以进一步减少处理负载。我自己没有在Go中做过这个,但API支持必要的部分(参见相关问题)。

Nginx

虽然上述所有内容都描述了使用Apache,但还有其他服务器产品也可以提供反向代理。最值得注意的是NginxNginx反向代理示例),它将为您提供小而有用的性能和可扩展性优势。如果您的服务器上有这个选项,学习和部署它是值得的。

英文:

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.

答案2

得分: -2

根据之前关于环境变量的回答,我能够轻松解决sudo问题。

https://stackoverflow.com/a/8636711/2576956

在终端中运行以下命令:

sudo visudo

添加以下行:

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

顺便提一下,我使用的是Ubuntu 12.04。我认为之前关于使用端口80的代理的回答是正确的选择,因为在解决sudo问题后,我遇到了关于端口80的错误:

$ 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

这意味着sudo命令已经修复,但是由于另一个服务已经在使用端口80(apache),所以代理绑定无法工作。

英文:

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

https://stackoverflow.com/a/8636711/2576956

 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).

huangapple
  • 本文由 发表于 2014年6月28日 08:40:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/24462505.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定