승객 2.2.4, nginx 0.7.61 및 SSL

승객 2.2.4, nginx 0.7.61 및 SSL

SSL로 Passenger와 nginx를 구성한 사람이 있나요? 나는 이 구성이 내가 원하는 대로 작동하도록 하기 위해 인터넷에 있는 몇 가지 리소스를 사용하여 몇 시간을 보냈고 전달된 것으로 추정되는 헤더 중 어느 것도 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나는 심지어 Passenger 의 메소드를 수정하기까지 했습니다 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

벽에 머리를 부딪히는 데 지쳤기 때문에 제가 받을 수 있는 어떤 도움이라도 진심으로 감사하겠습니다!

답변1

passenger_set_cgi_param승객 3은 다음과 같이 동작하는 새로운 지시어로 이 기능을 구현합니다 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컨트롤러에서 액세스 가능).

아직 문서화되지 않았지만 여기에 추가 정보가 있습니다.

답변2

승객은 프록시와 동일하지 않으며 어떤 방식으로든 SCGI를 사용합니다. 내가 생각해낸 유일한 해결 방법은 다른(보호된) 포트에서 nginx를 통해 다시 프록시를 사용하는 것입니다. 이상적이지는 않지만 작동합니다.

답변3

흠... Proxy_set_header가 다시 한 번 사용되는 위치 지시문이 있습니까?

fastcgi나 Proxy_set_header와 같은 배열 지시문이 하위 수준에서 수정되면 상위 수준에서 상속되지 않기 때문에 묻습니다. 서버 수준에서 Proxy_set_header를 선언했으므로 예를 들어 "location"과 같은 낮은 수준의 다른 Proxy_set_header 지시문은 가장 최근 지시문을 제외하고 이 수준에 대해 지금까지 선언된 모든 항목을 정리합니다.

답변4

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 "";

관련 정보