Passenger 2.2.4, nginx 0.7.61 und SSL

Passenger 2.2.4, nginx 0.7.61 und SSL

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_handlerIch 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_paramdie 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-Certund die anderen Header in der Rack::RequestInstanz (zugänglich von #requestIhrem 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 "";

verwandte Informationen