如上图所示,客户端通过 SSL 请求过来的访问被反向代理 nginx 接收,nginx 结束了 SSL 并将请求以纯 HTTP 提交 tomcat。nginx 配置 nginx.conf 如下:
worker_processes 1; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main \'[$time_local] $remote_addr - "$request" \' \'$status "$http_user_agent" \' \'"$args"\'; access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 120; client_max_body_size 120m; client_body_buffer_size 128k; server_names_hash_bucket_size 128; large_client_header_buffers 4 4k; open_file_cache max=8192 inactive=20s; open_file_cache_min_uses 1; open_file_cache_valid 30s; upstream tomcat_server { # Tomcat is listening on default 8080 port server 192.168.1.177:8080 fail_timeout=0; } server { listen 443; server_name localhost; ssi on; ssi_silent_errors on; ssi_types text/shtml; ssl on; ssl_certificate /usr/local/nginx/ca/server/server.crt; ssl_certificate_key /usr/local/nginx/ca/server/server.key; ssl_client_certificate /usr/local/nginx/ca/private/ca.crt; ssl_session_timeout 5m; ssl_verify_client on; #开户客户端证书验证 ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; charset utf-8; access_log logs/host.access.log main; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location = /favicon.ico { log_not_found off; access_log off; expires 90d; } location /swifton/ { proxy_pass ; include proxy.conf; } } }
其中,tomcat(本例中和 nginx 部署同台机器) 是 nginx 同一局域网段的,swifton 是测试 tomcat 项目。proxy.conf 内容:
proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_set_header X-Forwarded-Proto $scheme;<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改为
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" scheme="https" proxyName="localhost" proxyPort="443" />
5.2 Nginx 重启验证先关闭运行中的 nginx,如果你已经开启了的话。
$ sudo ./nginx -t
输出
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/nginx.conf:50
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
ssl 模块没有编译进来。
切换到步骤 1.2.4 里的 nginx 安装目录 nginx-1.7.10,
$ ./configure --with-pcre=../pcre-8.36 --with-zlib=../zlib-1.2.8 --with-http_ssl_module
$ sudo make
$ sudo make install
Nginx 重装成功。再次
$ sudo ./nginx -t
提示测试成功。
启动 nginx。
5.3 客户访问 ssl 验证谷歌浏览器使用 https 访问原有项目 https://192.168.1.177/swifton,177 是 Nginx 所在服务器,提示 400 Bad Request(No required SSL certificate was sent):
这是因为 https 双向验证需要客户端安装证书。windows os 下拿到步骤 2.3.5 生成的证书 client.p12,直接双击它,进入 "证书导入向导":
点击 "下一步":
"要导入的文件" 已经为我们选好了,点击 "下一步":
"私钥保护" 对话框输入 2.3.5 步的 Export Password,点击 "下一步":
"证书存储" 对话框,我们使用 Windows 自动存储,点击 "下一步":
直接点击 "完成" 按钮完成证书导入。
重启谷歌浏览器,再次访问 https://192.168.1.177/swifton,浏览器要求我们选择证书:
选中刚才安装好的那个证书(localhost(localhost)),点击 "确定",提示 "隐私设置错误":
这是因为我们服务器用的是自己签发的证书。选择继续访问,守得云开见月明,终于看到久违了的项目登录页面,成功了:
可以点击浏览器输入框左侧的小锁图标查看我们导入的客户端证书相关信息: