4

我有一个在端口上运行的 Rails 应用程序,8080我需要欺骗它认为它在端口 80 上运行。

我在 port 上运行 Varnish80并将请求转发到 port 上的 nginx 8080,但是当用户尝试使用 OmniAuth 登录并且 Devise gem 生成一个 url 以重定向回服务器时,它认为它在端口 8080 上,然后用户将看到。

有什么办法可以欺骗 Rails 应用程序将端口硬编码为 80(我认为这是一个不好的做法),或者让 nginx 转发请求,就好像它在端口 80 上运行一样?

由于我没有为 Rails 应用程序运行 nginx 代理,所以我想不出一种方法来欺骗端口。

以前有没有人遇到过这个问题,如果是这样,需要什么样的配置来解决它?

提前致谢!

编辑: nginx 和 Varnish 都在同一台服务器上运行。

4

4 回答 4

7

我在端口 80 上使用 Varnish 和在端口 8080 上使用 nginx 进行相同的设置,而 OmniAuth(无设计)正在做同样的事情。我尝试X-Forwarded-Port在 Varnish 和fastcgi_param SERVER_PORT 80;nginx 中设置等,均未成功。我设置中的另一部分是Passenger(您没有提到),但如果您确实在使用Passenger,那么您可以使用:

passenger_set_cgi_param SERVER_PORT 80; 

(文档说你可以在一个http块中设置它,但这对我不起作用,我不得不将它添加到server块中。)

http://modrails.com/documentation/Users%20guide%20Nginx.html#passenger_set_cgi_param

于 2011-05-24T19:25:45.413 回答
2

X-Forwarded-Port在清漆中设置。请参阅此示例以及 Google 搜索“ varnish x-forwarded-port ”的其他结果。

当然,您还必须设置X-Forwarded-ForX-Forwarded-Proto.


标头X-Forwarded-ForX-Forwarded-ProtoX-Forwarded-Port是 HTTP 反向代理(例如 Nginx、Squid 或 Varnish)与“后端”HTTP 应用程序服务器、运行在 Thin 或 Unicorn 中的 Rails 应用程序、用户实际是谁以及如何进行通信的一种方式用户实际连接。

例如,假设您的 Rails 应用程序前面有 Nginx。您的 Rails 应用程序是使用 Thin 启动的,并且正在侦听 127.0.0.1:8080,而 Nginx 正在侦听 HTTP 的 0.0.0.0:80 和 HTTPS 的 0.0.0.0:443。Nginx 被配置为代理到 Rails 应用程序的所有连接。然后你的 Rails 应用程序会认为任何用户的 IP 地址是127.0.0.1,端口是8080,并且方案是http,即使实际用户通过端口连接1.2.3.4并请求页面。解决方法是配置 Nginx 设置 headers:https443

X-Forwarded-For: 1.2.3.4
X-Forwarded-Scheme: https
X-Forwarded-Port: 443

Rails 应用程序应该使用这些参数而不是默认参数。

这同样适用于您使用的任何反向代理,例如您使用的 Varnish。

于 2011-01-04T17:07:37.220 回答
0

您可以创建一个代理并将其作为您想要的任何端口提供服务。

也许有阿帕奇在上面,乘客独自站立......

<VirtualHost *:80>
 ServerName <name>
 DocumentRoot /home/deploy/<name>

 PassengerEnabled off
 ProxyPass / http://127.0.0.1:<port>/
 ProxyPassReverse / http://127.0.0.1:<port>/

</VirtualHost>

在外壳中:

passenger start -e staging -p 3003 -d
于 2011-01-04T05:56:41.210 回答
0

您的问题似乎您正在重定向到端口 8080。最好的解决方案是配置 Rails(或 OmniAuth/Devise gem)以将请求视为在端口 80 上触发(但我不知道如何或是否它是可能的)。

就像ablemike所说的那样;Apache 有一个很棒的模块(mod_proxy),它使用 ProxyPassReverse 将重定向重写为端口 80 重定向。更好的是,使用 mod_proxy_html 它将用 80 端口链接替换 ​​HTML 页面中的 8080 端口链接。

如果你只需要重写重定向,你可以在 Varnish VCL 中重写重定向,比如:

sub vcl_fetch {

  ...

  #Rewrite redirect from port 8080 to port 80
  if ( obj.http.Location ~ "^http://[^:]+:8080/.*" ) {
    set obj.http.Location = regsub(obj.http.Location, ""^(http://[^:]+):8080(/.*)","\1\2");
  }
}

(如果你使用清漆> = 2.1,我认为你必须用 beresp 替换 obj )

如果您必须重写 HTML 页面,使用 varnish 完全正确地做到这一点会困难得多。

于 2011-01-04T15:21:20.873 回答