4

我正在努力将 nginx 代理到 SSL 上游。我意识到代理到 HTTPS 很浪费,但这是我的设置,有时直接访问 API,有时我使用 nginx 为 JS 应用程序提供服务,该应用程序也是 API 的客户端,CORS 和浏览器安全要求 JS应用程序与提供应用程序的域相同的域进行通信:

 +--------------------+                      +---------------------+
 |                    |+-------------------->|                     |
 | Pure HTTP API Host |                      | CLI Tool API Client |
 |                    |<--------------------+|                     |
 +--------------------+                      +---------------------+
         |  ^ (:3152)
         |  |
         |  |                |               +---------------------+
         |  +--------------------------------|                     |
         |                   |               | Javascript App      |
         +---------------------------------->|                     |
                             |               +---------------------+
                             |

                         nginx proxy for CORS

有了这个,这里是堆栈。API 主机是用 GoLang 编写的,使用 StartSSL 的签名证书提供服务:

$ openssl s_client -ssl3 -connect local.api.theproject.io:3251
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : AES256-SHA
    Session-ID:
    Session-ID-ctx:
    Master-Key: E021B27717F5A4
    Key-Arg   : None
    Start Time: 1377589306
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)

我已经截断了该输出,但足以说明 Go 的ListenAndServeTLS似乎只适用于 SSLv3,因为以下失败:

$ openssl s_client -connect local.api.theproject.io:3251
CONNECTED(00000003)
35899:error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version:/SourceCache/OpenSSL098/OpenSSL098-47.1/src/ssl/s23_clnt.c:602:

因此,来自 nginx 的问题很明显:

2013/08/27 09:30:21 [error] 35674#0: *3 kevent() reported that connect() failed (61:
Connection refused) while connecting to upstream, client: 127.0.0.1, server: 
local.www.theproject.io, request: "GET / HTTP/1.1", upstream: "https://[::1]:3251//", 
host: "local.www.theproject.io:4443"
2013/08/27 09:30:21 [error] 35674#0: *3 SSL_do_handshake() failed (SSL: error:1407742
E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version) while SSL handshaking
to upstream, client: 127.0.0.1, server: local.www.theproject.io, request: "GET / 
HTTP/1.1", upstream: "https://127.0.0.1:3251//", host: "local.www.theproject.io:4443"

注:我正在使用[::1]这里使用,但这并不重要,当然也失败了127.0.0.1

因此,问题是,缺少什么:

  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
  proxy_pass https://local.api.theproject.io:3251/;

为了让它在内部使用 SSLv3 正确代理?

4

1 回答 1

1

你试过“ssl_ciphers ALL;”吗?

尽管不建议这样做(因为它允许使用弱密码),但这将缩小问题的范围。如果这不起作用,很可能是您使用的 openssl 没有合适的密码来完成与 Go 服务器的 SSL 握手。

请注意,Go 的 tls 包仅“部分”实现,支持的密码非常有限。

有两种解决方案:

  1. 您必须升级支持 Go 的 tls 包已经实现的 openssl 版本。然后,当然,重新编译你的 nginx。
  2. 您必须通过在 tls/cipher_suites.go 中将适当的套件 IDopenssl ciphers添加到 cipherSuites 来修补 tls 包以支持您当前提供的任何内容(我认为)
于 2013-10-01T23:25:35.540 回答