nginx (https) 到 tomcat (https)
nginx (https) to tomcat (https)
我无法让 https nginx 服务器连接到同样使用 https 的 tomcat 实例。 Nginx 将此写入错误日志:
2015/03/02 23:15:34 [error] 20074#0: *11 SSL_do_handshake() failed (SSL: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol) while SSL handshaking to upstream, client: 127.0.0.1, server: localhost, request: "GET /app/ HTTP/1.1", upstream: "https://127.0.0.1:8443/app/", host: "127.0.0.1"
设置是这样的:
browser -> nginx(https) -> tomcat(https) /app
结果如下:
OK: wget https://localhost:8443/app
FAIL: wget https://localhost/app
所以我可以直接访问 tomcat https 端口但不被 nginx 代理的 webapp。以下是我如何创建证书并设置 tomcat 和 nginx.
Nginx
Create the private server key:
sudo openssl genrsa -des3 -out server.key 2048
Create a certificate signing request (common name set to localhost):
sudo openssl req -new -key server.key -out server.csr
Remove the password:
sudo cp server.key server.key.org
sudo openssl rsa -in server.key.org -out server.key
Sign your SSL Certificate:
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Edit nginx.conf to add this:
server {
listen 80;
listen 443 ssl;
server_name localhost;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_verify_client off;
ssl_trusted_certificate tomcat.crt;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_set_header Host $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_pass https://127.0.0.1:8443;
}
}
Tomcat
Create a local self-signed Certificate:
keytool -genkey -alias tomcat -keyalg RSA -keystore localhost.keystore
Edit server.xml config to add this:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="localhost.keystore"
keystorePass="password0" proxyPort="443" proxyHost="localhost"/>
这是在 Mac 上设置的
- apache-tomcat-8.0.18
- nginx/1.7.10
- 达尔文内核版本 13.4.0:8 月 17 日星期日 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64
- java1.8.0_31
在 Windows 8.1 上进行相同的设置工作得很好。
有几处错误:
首先,当我使用最新的 ssl 模块从源代码重建并纠正了一些错误时,我的 nginx 构建似乎有问题。
其次,尝试使用 localhost 作为 nginx 和 tomcat 上的主机名是个坏主意,如果您为每个证书创建了两个不同的证书。相反,我为 tomcat 和 nginx 添加了一些 FQDN 到 /private/etc/hosts(在 Mac 上)
127.0.0.1 nginx.localhost.com tomcat.localhost.com
然后我为 nginx 和 tomcat 重新创建了证书,使用 nginx 证书的通用名称 'nginx.localhost.com' 和 tomcat 证书的 'tomcat.localhost.com'。记住在 tomcat 步骤中当提示输入名字和姓氏时使用 'tomcat.localhost.com'(因为这实际上是 Common Name 字段,应该是主机或 IP 地址)。
我从 JRE cacerts 和 Mac 的钥匙链中删除了所有旧的本地主机证书。然后启动nginx和tomcat。然后使用 safari 访问 urls https://nginx.localhost.com and https://tomcat.localhost.com。 Safari弹出一个证书对话框,然后点击show certificate,然后展开证书的Trust部分,然后select "Always Trust" for "When using this certificate"选项。然后单击信任证书按钮。这会在 'login' 链下的 Macs Keychain 中添加浏览器信任的两个证书。
现在浏览器很高兴,但我有两个 tomcat 网络应用程序通过 nginx 相互通信,它们需要创建两个证书来验证它们连接到的 ssl 主机名,所以我将它们添加到 Java cacerts 文件通过这样做:
通过 运行 这些命令获取 tomcat 和 nginx 服务器证书
openssl s_client -connect tomcat.localhost.com:8443
openssl s_client -connect nginx.localhost.com:443
并复制写入屏幕的证书,以此标签“-----BEGIN CERTIFICATE-----”开始并以此标签“-----END CERTIFICATE-----”结束
然后使用以下命令将这些服务器证书导入 java cacerts 文件:
sudo keytool -import -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/security/cacerts -file tomcat.localhost.com -alias tomcat.localhost.com
sudo keytool -import -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/security/cacerts -file nginx.localhost.com -alias nginx.localhost.com
重新启动 nginx 和 tomcat 现在一切正常。
我无法让 https nginx 服务器连接到同样使用 https 的 tomcat 实例。 Nginx 将此写入错误日志:
2015/03/02 23:15:34 [error] 20074#0: *11 SSL_do_handshake() failed (SSL: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol) while SSL handshaking to upstream, client: 127.0.0.1, server: localhost, request: "GET /app/ HTTP/1.1", upstream: "https://127.0.0.1:8443/app/", host: "127.0.0.1"
设置是这样的:
browser -> nginx(https) -> tomcat(https) /app
结果如下:
OK: wget https://localhost:8443/app
FAIL: wget https://localhost/app
所以我可以直接访问 tomcat https 端口但不被 nginx 代理的 webapp。以下是我如何创建证书并设置 tomcat 和 nginx.
Nginx
Create the private server key:
sudo openssl genrsa -des3 -out server.key 2048
Create a certificate signing request (common name set to localhost):
sudo openssl req -new -key server.key -out server.csr
Remove the password:
sudo cp server.key server.key.org
sudo openssl rsa -in server.key.org -out server.key
Sign your SSL Certificate:
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Edit nginx.conf to add this:
server {
listen 80;
listen 443 ssl;
server_name localhost;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_verify_client off;
ssl_trusted_certificate tomcat.crt;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_set_header Host $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_pass https://127.0.0.1:8443;
}
}
Tomcat
Create a local self-signed Certificate:
keytool -genkey -alias tomcat -keyalg RSA -keystore localhost.keystore
Edit server.xml config to add this:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="localhost.keystore"
keystorePass="password0" proxyPort="443" proxyHost="localhost"/>
这是在 Mac 上设置的
- apache-tomcat-8.0.18
- nginx/1.7.10
- 达尔文内核版本 13.4.0:8 月 17 日星期日 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64
- java1.8.0_31
在 Windows 8.1 上进行相同的设置工作得很好。
有几处错误:
首先,当我使用最新的 ssl 模块从源代码重建并纠正了一些错误时,我的 nginx 构建似乎有问题。
其次,尝试使用 localhost 作为 nginx 和 tomcat 上的主机名是个坏主意,如果您为每个证书创建了两个不同的证书。相反,我为 tomcat 和 nginx 添加了一些 FQDN 到 /private/etc/hosts(在 Mac 上)
127.0.0.1 nginx.localhost.com tomcat.localhost.com
然后我为 nginx 和 tomcat 重新创建了证书,使用 nginx 证书的通用名称 'nginx.localhost.com' 和 tomcat 证书的 'tomcat.localhost.com'。记住在 tomcat 步骤中当提示输入名字和姓氏时使用 'tomcat.localhost.com'(因为这实际上是 Common Name 字段,应该是主机或 IP 地址)。
我从 JRE cacerts 和 Mac 的钥匙链中删除了所有旧的本地主机证书。然后启动nginx和tomcat。然后使用 safari 访问 urls https://nginx.localhost.com and https://tomcat.localhost.com。 Safari弹出一个证书对话框,然后点击show certificate,然后展开证书的Trust部分,然后select "Always Trust" for "When using this certificate"选项。然后单击信任证书按钮。这会在 'login' 链下的 Macs Keychain 中添加浏览器信任的两个证书。
现在浏览器很高兴,但我有两个 tomcat 网络应用程序通过 nginx 相互通信,它们需要创建两个证书来验证它们连接到的 ssl 主机名,所以我将它们添加到 Java cacerts 文件通过这样做:
通过 运行 这些命令获取 tomcat 和 nginx 服务器证书
openssl s_client -connect tomcat.localhost.com:8443
openssl s_client -connect nginx.localhost.com:443
并复制写入屏幕的证书,以此标签“-----BEGIN CERTIFICATE-----”开始并以此标签“-----END CERTIFICATE-----”结束
然后使用以下命令将这些服务器证书导入 java cacerts 文件:
sudo keytool -import -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/security/cacerts -file tomcat.localhost.com -alias tomcat.localhost.com
sudo keytool -import -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/security/cacerts -file nginx.localhost.com -alias nginx.localhost.com
重新启动 nginx 和 tomcat 现在一切正常。