Обманывая приложение Rails, чтобы думать, что оно находится на другом порту - PullRequest
4 голосов
/ 04 января 2011

У меня есть приложение Rails, работающее на порту 8080, которое мне нужно обмануть, чтобы думать, что оно работает на порте 80.

Я запускаю Varnish на порту 80 и пересылаю запросы на nginx на порту 8080, но когда пользователь пытается войти в систему с помощью OmniAuth, а гем Devise генерирует URL для перенаправления обратно на сервер, он считает, что он включен порт 8080, который затем увидит пользователь.

Есть ли способ обмануть приложение Rails, чтобы жестко кодировать порт как 80 (я бы подумал, что это плохая практика), или сделать так, чтобы nginx перенаправлял запрос, как будто он работает на порту 80?

Поскольку я не использую прокси nginx для приложения Rails, я не могу придумать, как обмануть порт.

Кто-нибудь сталкивался с этой проблемой раньше, если да, то какая конфигурация необходима для ее устранения?

Заранее спасибо!

EDIT: И nginx, и Varnish работают на одном сервере.

Ответы [ 4 ]

7 голосов
/ 24 мая 2011

У меня такая же настройка с Varnish на порту 80 и nginx на порту 8080, и OmniAuth (без Devise) делал то же самое. Я попытался установить 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

2 голосов
/ 04 января 2011

Настройка X-Forwarded-Port в Лак.См. этот пример и другие результаты поиска Google для " varnish x-forwarded-port ".

Вы, конечно, также должны настроить X-Forwarded-For и X-Forwarded-Proto.


Заголовки X-Forwarded-For, X-Forwarded-Proto и X-Forwarded-Port - это способ, с помощью которого обратные прокси-серверы HTTP, такие как Nginx, Squid или Varnish, могут общаться с-end "сервер приложений HTTP, ваше приложение Rails, работающее в Thin или Unicorn, кто этот пользователь на самом деле и как пользователь фактически подключился.

Например, предположим, что у вас есть Nginx перед вашим приложением Rails.Ваше Rails-приложение загружено с Thin и прослушивает 127.0.0.1:8080, в то время как Nginx прослушивает 0.0.0.0:80 для HTTP и 0.0.0.0:443 для HTTPS.Nginx настроен для прокси всех подключений к приложению Rails.Тогда ваше Rails-приложение будет думать, что IP-адрес любого пользователя 127.0.0.1, порт 8080 и схема http, даже если реальный пользователь подключился с 1.2.3.4 и запросил страницу через https напорт 443.Решение состоит в том, чтобы настроить Nginx для установки заголовков:

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

, и приложение Rails должно использовать эти параметры вместо значений по умолчанию.

То же самое относится к любому используемому вами обратному прокси,например лак в вашем случае.

0 голосов
/ 04 января 2011

Ваша проблема, кажется, вы получаете перенаправления на порт 8080. Лучшее решение было бы настроить Rails (или гем OmniAuth / Devise) для обработки запросов, как если бы они были запущены на порту 80 (но я не знаю, как или если это возможно).

Как сказал смайлик; Apache имеет отличный модуль для этого (mod_proxy), с ProxyPassReverse он переписывает перенаправления обратно в перенаправления порта 80. Более того, mod_proxy_html заменит ссылки на порт 8080 на страницах HTML ссылками на порт 80.

Если вам нужно только переписать перенаправления, вы можете переписать перенаправления в 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");
  }
}

(я думаю, вы должны заменить obj на beresp, если вы используете лак> = 2.1)

Если вам придется переписывать HTML-страницы, это будет намного сложнее сделать полностью корректно с помощью лака.

0 голосов
/ 04 января 2011

Вы можете создать прокси-сервер и настроить его под любой порт.

Может быть, с апачем сверху и пассажиром в одиночестве ...

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