Hat jemand Glück gehabt, Passenger und nginx mit SSL zu konfigurieren? Ich habe Stunden damit verbracht, diese Konfiguration mithilfe der wenigen Ressourcen, die es im Internet gibt, so zum Laufen zu bringen, wie ich es möchte, und ich kann keinen der angeblich weitergeleiteten Header im Rails-Controller anzeigen lassen.
Beispielsweise mit einer Conf-Datei wie folgt (und mehreren Variationen davon):
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;
}
und Rails-Code im Controller wie folgt:
request.headers.each { |k, v|
RAILS_DEFAULT_LOGGER.error "Header #{k} Val #{v}"
}
andere Header werden angezeigt, aber nicht die in nginx festgelegten, zB:
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
Ich bin sogar so weit gegangen, Passengers Methode zu ändern main_loop
, d.h.
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
nur um festzustellen, dass die angeblich hinzugefügten Header auch dort nicht vorhanden sind:
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
Ich habe es satt, meinen Kopf immer gegen die Wand zu schlagen, daher bin ich für jede Hilfe, die ich bekommen kann, wirklich dankbar!
Antwort1
Passenger 3 implementiert diese Funktion mit einer neuen Anweisung, passenger_set_cgi_param
die sich wie folgt verhält proxy_set_header
:
Um beispielsweise SSL-Variablen an Rack zu übergeben, können Sie Folgendes tun:
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;
}
Sie hätten dann Zugriff auf X-SSL-Raw-Cert
und die anderen Header in der Rack::Request
Instanz (zugänglich von #request
Ihrem Controller aus).
Es ist noch nicht dokumentiert, aber hier sind weitere Informationen:
Antwort2
Passenger ist nicht dasselbe wie Proxying, es verwendet in gewisser Weise SCGI. Die einzige Lösung, die mir eingefallen ist, ist, über nginx auf einem anderen (geschützten) Port zurück zu proxyen. Das ist zwar alles andere als ideal, aber es funktioniert.
Antwort3
Hmmm … Haben Sie zufällig eine Standortdirektive, bei der proxy_set_header erneut verwendet wird?
Ich frage, weil Array-Direktiven wie fastcgi oder proxy_set_header nicht von einer höheren Ebene übernommen werden, wenn sie auf einer niedrigeren Ebene geändert werden. Da Sie Ihren proxy_set_header auf Serverebene deklarieren, bereinigt jede andere proxy_set_header-Direktive auf einer niedrigeren Ebene wie beispielsweise „location“ alles, was bisher für diese Ebene deklariert wurde, außer Ihrer letzten Direktive.
Antwort4
Die gültigen Optionen für 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 "";