Кому-нибудь повезло с настройкой Passenger и nginx с SSL? Я потратил часы, пытаясь заставить эту конфигурацию работать так, как мне хотелось бы, используя то немногое ресурсов, которое есть в сети, и я не могу заставить ни один из якобы перенаправленных заголовков отображаться в контроллере Rails.
Например, с файлом conf следующего содержания (и нескольких его вариаций):
server {
listen 3000;
server_name .example.com;
root /Users/website/public;
passenger_enabled on;
rails_env development;
}
server {
listen 3443;
root /Users/website/public;
rails_env development;
passenger_enabled on;
ssl on;
#ssl_verify_client on;
ssl_certificate /Users/website/ssl/server.crt;
ssl_certificate_key /Users/website/ssl/server.key;
#ssl_client_certificate /Users/website/ssl/CA.crt;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X_FORWARDED_PROTO https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-SSL-Subject $ssl_client_s_dn;
#proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
proxy_redirect off;
proxy_max_temp_file_size 0;
}
и код Rails в контроллере следующим образом:
request.headers.each { |k, v|
RAILS_DEFAULT_LOGGER.error "Header #{k} Val #{v}"
}
появляются другие заголовки, но не заданные в nginx, например:
Header rack.multithread Val false
Header REQUEST_URI Val /login/new
Header REMOTE_PORT Val 64021
Header rack.multiprocess Val true
Header PASSENGER_USE_GLOBAL_QUEUE Val false
Header PASSENGER_APP_TYPE Val rails
Header SCGI Val 1
Header SERVER_PORT Val 3443
Header HTTP_ACCEPT_CHARSET Val ISO-8859-1,utf-8;q=0.7,*;q=0.7
Header rack.request.query_hash Val
Header DOCUMENT_ROOT Val /Users/website/public
Я даже зашел так далеко, что модифицировал пассажирский abstract_request_handler
с main_loop
метод, т.е.
headers, input = parse_request(client)
if headers
if headers[REQUEST_METHOD] == PING
process_ping(headers, input, client)
else
headers.each { |h,v|
log.unknown "abstract_request_handler: #{h} = #{v}"
}
process_request(headers, input, client)
end
end
только чтобы обнаружить, что якобы добавленных заголовков там тоже не существует:
abstract_request_handler: HTTP_KEEP_ALIVE = 300
abstract_request_handler: HTTP_USER_AGENT = Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
abstract_request_handler: PASSENGER_SPAWN_METHOD = smart-lv2
abstract_request_handler: CONTENT_LENGTH = 0
abstract_request_handler: HTTP_IF_NONE_MATCH = "b6e8b9afbc1110ee3bf0c87e119252ad"
abstract_request_handler: HTTP_ACCEPT_LANGUAGE = en-us,en;q=0.5
abstract_request_handler: SERVER_PROTOCOL = HTTP/1.1
abstract_request_handler: HTTPS = on
abstract_request_handler: REMOTE_ADDR = 127.0.0.1
abstract_request_handler: SERVER_SOFTWARE = nginx/0.7.61
abstract_request_handler: SERVER_ADDR = 127.0.0.1
abstract_request_handler: SCRIPT_NAME =
abstract_request_handler: PASSENGER_ENVIRONMENT = development
abstract_request_handler: REMOTE_PORT = 64021
abstract_request_handler: REQUEST_URI = /login/new
abstract_request_handler: HTTP_ACCEPT_CHARSET = ISO-8859-1,utf-8;q=0.7,*;q=0.7
abstract_request_handler: SERVER_PORT = 3443
abstract_request_handler: SCGI = 1
abstract_request_handler: PASSENGER_APP_TYPE = rails
abstract_request_handler: PASSENGER_USE_GLOBAL_QUEUE = false
Я устал биться головой об стену, поэтому буду признателен за любую помощь, которую могу получить!
Пассажир 3 реализует эту функцию с помощью новой директивы passenger_set_cgi_param
который ведет себя как proxy_set_header
.
Например, чтобы передать переменные SSL в Rack, вы можете сделать это:
server {
listen 443 default ssl;
# other SSL stuff goes here
# other passenger stuff here
passenger_set_cgi_param X_FORWARDED_PROTO https;
passenger_set_cgi_param X-SSL-Raw-Cert $ssl_client_raw_cert;
passenger_set_cgi_param X-SSL-Cert $ssl_client_cert;
passenger_set_cgi_param X-SSL-Client-S-DN $ssl_client_s_dn;
passenger_set_cgi_param X-SSL-Client-I-DN $ssl_client_i_dn;
passenger_set_cgi_param X-SSL-Client-Verify $ssl_client_verify;
}
Тогда у вас будет доступ к X-SSL-Raw-Cert
и другие заголовки в Rack::Request
экземпляр (доступен из #request
в вашем контроллере).
Это еще не задокументировано, но вот дополнительная информация:
Passenger - это не то же самое, что прокси, он в некотором роде использует SCGI. Единственная работа, которую я придумал, - это проксирование через nginx на другой (защищенный) порт. Это далеко не идеально, но работает.
Рекомендую добавить свою "звездочку" к 371 пассажирскому вопросу. http://code.google.com/p/phusion-passenger/issues/detail?id=371
Хммм ... У вас случайно есть директива местоположения, где снова используется proxy_set_header?
Я спрашиваю, потому что директивы массива, такие как fastcgi или proxy_set_header, не наследуются с более высокого уровня, когда они изменяются на более низком уровне. Поскольку вы объявляете свой proxy_set_header на уровне сервера, любая другая директива proxy_set_header на более низком уровне, например «location», будет очищать все, что было объявлено до сих пор для этого уровня, кроме вашей последней директивы.
Допустимые параметры для nginx / 1.8.1 Phusion_Passenger / 5.0.25
passenger_enabled on;
passenger_set_header X-SSL-Subject $ssl_client_s_dn;
passenger_set_header X-Client-DN $ssl_client_s_dn;
passenger_set_header X-Client-Verify $ssl_client_verify;
passenger_set_header X-Forwarded-For "";