Я хочу запустить все свое приложение Rails с SSL, поэтому я решил использовать параметр конфигурации Rails global force_ssl, который отлично работает, за исключением того, что проверка работоспособности ELB никогда не будет работать, потому что, если я установлю его на http, Rails будет перенаправлять на https с 301, и проверка работоспособности завершится ошибкой, поскольку он не равен 200. Если я установлю https, nginx / rails не сможет обработать запрос, поскольку SSL обрабатывается ELB, а nginx / rails обрабатывает только HTTP.
Моим неидеальным решением было бы сделать исключение из global force_ssl
только для страницы проверки работоспособности, но Rails ' global force_ssl
config всегда переопределяет force_ssl :except => :health_check
так что, похоже, это не работает.
Другим решением было бы не использовать ELB для завершения SSL и настроить HAProxy или около того, но я хочу максимально использовать инфраструктуру Amazon для вещей, чтобы сосредоточиться на основной разработке проекта, а не на инфраструктуре.
Это мой первый пост о сбоях сервера, поэтому я ценю любую помощь, которую могу получить (или дополнительную информацию, которую могу предоставить). Спасибо.
Обновить:
До сих пор я «решил» эту проблему, предоставив ELB доступ к экземпляру EC2 через порт, отличный от порта 80, к которому может получить доступ только он, что кажется экстремальным, но сохраняет разделение между уровнями приложения и сервера. Если запрос проверки работоспособности поступает от ELB с этого порта, nginx перенаправит заголовок X-Forwarded-Proto, установленный на https, что позволит Rack подумать, что он пришел через SSL, и пропустить его. Для всего остального трафика, поступающего через стандартный порт 80, он просто пересылает заголовок X-Forwarded-Proto, предоставленный ELB, который точно сообщит, что использовал внешний пользователь, и позволит Rails решить принудительно использовать https или нет.
Все еще ожидаю более чистого решения, но это то, что у меня есть.
6 месяцев спустя - вот ваше чистящее средство.
# config/environments/production.rb
config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/health_check') } }
Следует отметить, что опция исключения для config.ssl_options устарела, и вам необходимо используйте гем Rack-ssl, чтобы добиться того же поведения.
Мне не показалось хорошей идеей включать и инициализировать новое промежуточное ПО для стойки только для проверки работоспособности, поэтому я решил вместо этого использовать nginx, чтобы установить заголовок $ http_x_forwarded_proto для средства проверки работоспособности.
Вот что я придумал:
location @unicorn {
if ($http_user_agent ~ "ELB-HealthChecker")
{
set $http_x_forwarded_proto https;
}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
Теперь rails видит запросы Health Checker как https (хотя это не так) и возвращает успех.
После нескольких дней борьбы с конфигами и т. Д. Я нашел эту замечательную жемчужину:
https://github.com/lserman/aws-healthcheck
Нет необходимости в какой-либо специальной настройке nginx (работает через стойку). Он возвращается 200
on / healthcheck, который работает как шарм. Просто добавьте его к своим драгоценным камням, и все готово.
Если вам на самом деле все равно, попадет ли ваша проверка работоспособности в ваше приложение Rails (что, вероятно, вам следует ...), вы можете указать его на статический файл, например /robots.txt, и использовать HTTP / 80 вместо HTTPS / 443. Nginx будет обслуживать статический файл без участия Rails.
Не то чтобы я действительно рекомендую это в долгосрочной перспективе, но если вы изо всех сил пытаетесь получить что-то, что можно пройти через ваш ELB, это поможет устранить неполадки.