`

nginx 配置ssl双向证书验证

阅读更多

1. 安装 nginx

1.1 nginx 包及其依赖包下载

出于模块的依赖性,Nginx 依赖以下三个包:

分别下载它们的最新稳定版(截至本文最新稳定版分别是 zlib-1.2.8.tar.gz、pcre-8.36.tar.gz、openssl-fips-2.0.9.tar.gz),最后下载 Nginx 最新(http://nginx.org/en/download.html)稳定版(截至本文最新稳定版是 nginx-1.7.10.tar.gz)。
依赖包安装次序为:openssl、zlib、pcre,最后安装 Nginx 包。

1.2 nginx 包及其依赖包安装

1.2.1 安装 openssl

$ tar -zxvf openssl-fips-2.0.9.tar.gz
$ cd openssl-fips-2.0.9
$ ./config
$ make
$ sudo make install

1.2.2 安装 zlib

$ tar -zxvf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure
$ make
$ sudo make install

1.2.3 安装 pcre

$ tar -zxvf pcre-8.36.tar.gz
$ cd pcre-8.36
$ ./configure
$ make
$ sudo make install

1.2.4 安装 nginx

$ tar -zxvf nginx-1.7.10.tar.gz
$ cd nginx-1.7.10
$ ./configure --with-pcre=../pcre-8.36 --with-zlib=../zlib-1.2.8 --with-openssl=../openssl-fips-2.0.9
$ make
$ sudo make install

nginx 被默认安装在 /usr/local/nginx 目录。

1.3 验证 Nginx 是否安装成功

$ sudo /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

证明 Nginx 安装成功。

 

2. SSL 服务器 / 客户端双向验证证书的生成

2.1 创建一个新的 CA 根证书

在 nginx 安装目录下新建 ca 文件夹,进入 ca,创建几个子文件夹:
$ sudo mkdir ca
$ cd ca
$ sudo mkdir newcerts private conf server

newcerts 子目录将用于存放 CA 签署过的数字证书(证书备份目录);private 用于存放 CA 的私钥;conf 目录用于存放一些简化参数用的配置文件;server 存放服务器证书文件。

2.1.1 conf 目录新建 openssl.conf 文件

编辑其内容如下:

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
 
  1. [ ca ]  
  2. default_ca      = foo                   # The default ca section  
  3.    
  4. [ foo ]  
  5. dir            = /usr/local/nginx/ca         # top dir  
  6. database       = /usr/local/nginx/ca/index.txt          # index file.  
  7. new_certs_dir  = /usr/local/nginx/ca/newcerts           # new certs dir  
  8.    
  9. certificate    = /usr/local/nginx/ca/private/ca.crt         # The CA cert  
  10. serial         = /usr/local/nginx/ca/serial             # serial no file  
  11. private_key    = /usr/local/nginx/ca/private/ca.key  # CA private key  
  12. RANDFILE       = /usr/local/nginx/ca/private/.rand      # random number file  
  13.    
  14. default_days   = 365                     # how long to certify for  
  15. default_crl_days= 30                     # how long before next CRL  
  16. default_md     = md5                     # message digest method to use  
  17. unique_subject = no                      # Set to 'no' to allow creation of  
  18.                                          # several ctificates with same subject.  
  19. policy         = policy_any              # default policy  
  20.    
  21. [ policy_any ]  
  22. countryName = match  
  23. stateOrProvinceName = match  
  24. organizationName = match  
  25. organizationalUnitName = match  
  26. localityName            = optional  
  27. commonName              = supplied  
  28. emailAddress            = optional  

 

2.1.2 生成私钥 key 文件

$ cd /usr/local/nginx/ca
$ sudo openssl genrsa -out private/ca.key

输出
Generating RSA private key, 512 bit long modulus
..++++++++++++
.++++++++++++
e is 65537 (0x10001)

private 目录下有 ca.key 文件生成。

博主 20150520 加注:openssl 默认生成 512 位的。一般是用 2048 位的。

2.1.3 生成证书请求 csr 文件

$ sudo openssl req -new -key private/ca.key -out private/ca.csr
Country Name
提示输入 Country Name,输入 CN 并回车后:
State or Province Name
提示输入 State or Province Name (full name),输入 Shanghai 并回车后:
Locality Name
提示输入 Locality Name,输入 Shanghai 并回车后:
Organization Name
提示输入 Organization Name,输入 Defonds 并回车后:
Organizational Unit Name
提示输入 Organizational Unit Name,输入 Dev 并回车后:
Common Name
提示输入 Common Name,如果没有域名的话,输入 localhost 并回车后:
Email Address

提示输入 Email Address,输入 defonds@163.com 并回车后:

CA口令

提示输入 A challenge password,这个是根证书口令。输入 defonds 并回车后:

An optional company name
提示输入 An optional company name,输入 df 并回车。private 目录下有 ca.csr 文件生成。

2.1.4 生成凭证 crt 文件

$ sudo openssl x509 -req -days 365 -in private/ca.csr -signkey private/ca.key -out private/ca.crt
控制台输出
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=Defonds/OU=Dev/CN=localhost/emailAddress=defonds@163.com
Getting Private key

private 目录下有 ca.crt 文件生成。

2.1.5 为我们的 key 设置起始序列号

$ sudo echo FACE > serial
可以是任意四个字符

2.1.6 创建 CA 键库

$ sudo touch index.txt

2.1.7 为 "用户证书" 的移除创建一个证书撤销列表

$ sudo openssl ca -gencrl -out /usr/local/nginx/ca/private/ca.crl -crldays 7 -config "/usr/local/nginx/ca/conf/openssl.conf"
输出
Using configuration from /usr/local/nginx/ca/conf/openssl.conf
private 目录下有 ca.crl 文件生成。

2.2 服务器证书的生成

2.2.1 创建一个 key

$ sudo openssl genrsa -out server/server.key
输出
Generating RSA private key, 512 bit long modulus
...........................++++++++++++
.................++++++++++++
e is 65537 (0x10001)

server 目录下有 server.key 文件生成。

博主 20150520 加注:openssl 默认生成 512 位的。一般是用 2048 位的:sudo openssl genrsa -out server/server.key 2048

2.2.2 为我们的 key 创建一个证书签名请求 csr 文件

$ sudo openssl req -new -key server/server.key -out server/server.csr
这时会要求你输入和 2.1.2.2 步一样的那些问题,所有输入需要和那一步一致。但 A challenge password 是服务器证书口令,可以与根证书口令一致。这里:
服务器csr的创建
server 目录下有 server.csr 文件生成。

2.2.3 使用我们私有的 CA key 为刚才的 key 签名

$ sudo openssl ca -in server/server.csr -cert private/ca.crt -keyfile private/ca.key -out server/server.crt -config "/usr/local/nginx/ca/conf/openssl.conf"
输出
服务器key签名
两次都输入 y,server 目录下有 server.crt 文件生成。

2.3 客户端证书的生成

2.3.1 创建存放 key 的目录 users

$ sudo mkdir users
位置 /usr/local/nginx/ca/users。

2.3.2 为用户创建一个 key

$ sudo openssl genrsa -des3 -out /usr/local/nginx/ca/users/client.key 1024
为用户创建一个 key
要求输入 pass phrase,这个是当前 key 的口令,以防止本密钥泄漏后被人盗用。两次输入同一个密码(比如我这里输入 defonds),users 目录下有 client.key 文件生成。

2.3.3 为 key 创建一个证书签名请求 csr 文件

$ sudo openssl req -new -key /usr/local/nginx/ca/users/client.key -out /usr/local/nginx/ca/users/client.csr
Enter pass phrase
提示输入 pass phrase,即 client.key 的口令。将 2.3.2 步保存的 pass phrase 输入后并回车:
将 2.3.2 步输入的密码输入后并回车
要求你输入和 2.1.3 步一样的那些问题。输入需要和那一步一致。但 A challenge password 是客户端证书口令(请注意将它和 client.key 的口令区分开!),可以与服务器端证书或者根证书口令一致:
为 key 创建一个证书签名请求 csr 文件
users 目录下有 client.csr 文件生成。

2.3.4 使用我们私有的 CA key 为刚才的 key 签名

$ sudo openssl ca -in /usr/local/nginx/ca/users/client.csr -cert /usr/local/nginx/ca/private/ca.crt -keyfile /usr/local/nginx/ca/private/ca.key -out /usr/local/nginx/ca/users/client.crt -config "/usr/local/nginx/ca/conf/openssl.conf"
输出
Using configuration from /usr/local/nginx/ca/conf/openssl.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :PRINTABLE:'Shanghai'
localityName          :PRINTABLE:'Shanghai'
organizationName      :PRINTABLE:'Defonds'
organizationalUnitName:PRINTABLE:'Dev'
commonName            :PRINTABLE:'localhost'
emailAddress          :IA5STRING:'defonds@163.com'
Certificate is to be certified until Mar 16 11:47:48 2016 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

两次都输入 y,users 目录下有 client.crt 文件生成。

2.3.5 将证书转换为大多数浏览器都能识别的 PKCS12 文件

$ sudo openssl pkcs12 -export -clcerts -in /usr/local/nginx/ca/users/client.crt -inkey /usr/local/nginx/ca/users/client.key -out /usr/local/nginx/ca/users/client.p12
Enter pass phrase for
要求输入 client.key 的 pass phrase,输入 2.3.2 步输入的 pass phrase 并回车后:
Enter Export Password

要求输入 Export Password,这个是客户端证书的保护密码(其作用类似于 2.3.3 保存的口令),在客户端安装证书的时候需要输入这个密码。我还是输入 defonds。users 目录下有 client.p12 文件生成。

 

3. Nginx 配置

SSL 的目的是为了保证网络通信的安全以及数据完整性。所以,如果 tomcat 前面有了 nginx 作为反向代理,那就没有理由再在 nginx 和 tomcat 之间进行加密传输,毕竟二者处于同一内网。
tt
如上图所示,客户端通过 SSL 请求过来的访问被反向代理 nginx 接收,nginx 结束了 SSL 并将请求以纯 HTTP 提交 tomcat。nginx 配置 nginx.conf 如下:

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
 
  1. worker_processes  1;  
  2.   
  3. error_log  logs/error.log;  
  4. #error_log  logs/error.log  notice;  
  5. #error_log  logs/error.log  info;  
  6.   
  7. #pid        logs/nginx.pid;  
  8.   
  9.   
  10. events {  
  11.     worker_connections  1024;  
  12. }  
  13.   
  14.   
  15. http {  
  16.     include       mime.types;  
  17.     default_type  application/octet-stream;  
  18.   
  19.     log_format  main  '[$time_local] $remote_addr - "$request" '  
  20.                       '$status "$http_user_agent" '  
  21.                       '"$args"';  
  22.   
  23.     access_log  logs/access.log  main;  
  24.   
  25.     sendfile        on;  
  26.     #tcp_nopush     on;  
  27.   
  28.     #keepalive_timeout  0;  
  29.     keepalive_timeout  120;  
  30.     client_max_body_size    120m;  
  31.     client_body_buffer_size 128k;  
  32.     server_names_hash_bucket_size 128;  
  33.     large_client_header_buffers 4 4k;  
  34.     open_file_cache max=8192 inactive=20s;  
  35.     open_file_cache_min_uses 1;  
  36.     open_file_cache_valid 30s;  
  37.   
  38.     upstream tomcat_server {  
  39.     # Tomcat is listening on default 8080 port  
  40.         server 192.168.1.177:8080 fail_timeout=0;  
  41.     }  
  42.   
  43.     server {  
  44.         listen       443;  
  45.         server_name  localhost;  
  46.         ssi on;  
  47.         ssi_silent_errors on;  
  48.         ssi_types text/shtml;  
  49.   
  50.         ssl                  on;  
  51.         ssl_certificate      /usr/local/nginx/ca/server/server.crt;  
  52.         ssl_certificate_key  /usr/local/nginx/ca/server/server.key;  
  53.         ssl_client_certificate /usr/local/nginx/ca/private/ca.crt;  
  54.   
  55.         ssl_session_timeout  5m;  
  56.         ssl_verify_client on;  #开户客户端证书验证  
  57.   
  58.         ssl_protocols  SSLv2 SSLv3 TLSv1;  
  59.         ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;  
  60.         ssl_prefer_server_ciphers   on;  
  61.           
  62.         charset utf-8;  
  63.         access_log  logs/host.access.log  main;  
  64.   
  65.         #error_page  404              /404.html;  
  66.   
  67.         # redirect server error pages to the static page /50x.html  
  68.         #  
  69.   
  70.         error_page   500 502 503 504  /50x.html;  
  71.         location = /50x.html {  
  72.                 root   html;  
  73.         }  
  74.         location = /favicon.ico {  
  75.                 log_not_found off;  
  76.                 access_log off;  
  77.                 expires      90d;  
  78.         }  
  79.         location /swifton/ {  
  80.                 proxy_pass http://tomcat_server;  
  81.                 include proxy.conf;  
  82.         }        
  83.   
  84.     }  
  85. }  

 

其中,tomcat(本例中和 nginx 部署同台机器) 是 nginx 同一局域网段的,swifton 是测试 tomcat 项目。proxy.conf 内容:

 

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
 
  1. proxy_redirect   off;  
  2. proxy_set_header   Host             $host;  
  3. proxy_set_header   X-Real-IP        $remote_addr;  
  4. proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;  
  5. proxy_connect_timeout 60;  
  6. proxy_read_timeout 600;  
  7. proxy_set_header   X-Forwarded-Proto $scheme;  

 

 

 

4. Tomcat 配置

Nginx 反向代理 HTTP 不需要更改 Tomcat 配置。与 HTTP 代理不同的是,这里需要通过更改 tomcat 的配置文件来告诉它前面的 HTTPS 代理。将 %tomcat%/conf/ 以下部分:

  1. <Connector port="8080" protocol="HTTP/1.1"   
  2.            connectionTimeout="20000"   
  3.            redirectPort="8443" />  


修改为

  1. <Connector port="8080" protocol="HTTP/1.1"   
  2.            connectionTimeout="20000"   
  3.            redirectPort="8443"  
  4.   scheme="https"  
  5.   proxyName="localhost"  
  6.   proxyPort="443" />  

 

 

5. 配置验证

5.1 Tomcat 重启验证

重启 tomcat,后台日志没问题,也可以看到小猫界面。

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):
400 Bad Request
这是因为 https 双向验证需要客户端安装证书。windows os 下拿到步骤 2.3.5 生成的证书 client.p12,直接双击它,进入 "证书导入向导":
欢迎使用证书导入向导
点击 "下一步":
指定要导入的文件
"要导入的文件" 已经为我们选好了,点击 "下一步":
私钥保护
"私钥保护" 对话框输入 2.3.5 步的 Export Password,点击 "下一步":
证书存储
"证书存储" 对话框,我们使用 Windows 自动存储,点击 "下一步":
正在完成证书导入向导
直接点击 "完成" 按钮完成证书导入。
重启谷歌浏览器,再次访问 https://192.168.1.177/swifton,浏览器要求我们选择证书:
选择证书
选中刚才安装好的那个证书(localhost(localhost)),点击 "确定",提示 "隐私设置错误":
隐私设置错误
这是因为我们服务器用的是自己签发的证书。选择继续访问,守得云开见月明,终于看到久违了的项目登录页面,成功了:
项目登录页面
可以点击浏览器输入框左侧的小锁图标查看我们导入的客户端证书相关信息:

证书信息

 

 

6. 双向 SSL 验证的集群配置

Nginx 做负载均衡器,多台 Tomcat 进行集群,在双向 SSL 验证的环境下的配置,和纯 HTTP 没有多少差异。只需注意以下细节即可。

6.1 Nginx 配置

将步骤 3 所述 SSL 配置的以下部分

 

 

  1. upstream tomcat_server {  
  2. # Tomcat is listening on default 8080 port  
  3.        server 192.168.1.177:8080 fail_timeout=0;  
  4.    }  

 

 

修改为

 

  1. upstream tomcat_server {  
  2. # Tomcat is listening on default 8080 port  
  3.        ip_hash;  
  4.        server 192.168.1.176:8081;  
  5.        server 192.168.1.177:8080 fail_timeout=0;  
  6.    }  

 

 

即可。具体负载算法以及服务器列表依照实际情况自行调整。

6.2 Tomcat 配置

同步骤 4 所述配置。

 

 

CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证,至此结束。本文示例所涉及安装包 openssl-fips-2.0.9.tar.gz、pcre-8.36.tar.gz、zlib-1.2.8.tar.gz、nginx-1.7.10.tar.gz,Nginx 配置文件 nginx.conf、proxy.conf,以及 Tomcat 配置文件 server.xml 都已打包作为博客附件上传到 CSDN 资源,有兴趣的朋友可以去下载下来参考,下载地址:http://download.csdn.net/detail/defonds/8512071

 

参考资料

 
分享到:
评论

相关推荐

    nginx配置ssl双向验证的方法

    1、安装nginx略 ...2、使用openssl实现证书中心 由于是使用openssl架设私有证书中心,因此要保证以下字段在证书中心的证书、...编辑证书中心配置文件 vim /etc/pki/tls/openssl.cnf [ CA_default ] dir = /etc/pki/CA cert

    详解Nginx SSL快速双向认证配置(脚本)

    本文将详细介绍如何在Nginx服务器上配置SSL双向认证,以提高服务器的安全性,允许只有经过验证的客户端才能进行访问。SSL双向认证是一种高级的安全策略,它不仅要求服务器验证客户端的身份,同时也要求客户端验证...

    Nginx双向SSL认证配置详解

    完成证书的准备工作后,接下来配置Nginx支持双向SSL认证。 ##### 4.1 配置示例 ```nginx http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server {...

    Nginx+Tomcat配置SSL双向验证示例

    本资源是一个 CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证配置示例。详细如何配置请参考博客《图文:CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证》,地址是:...

    nginx实现http双向验证.docx

    总之,Nginx 实现 HTTP 双向验证是通过配置 SSL/TLS 扩展,使用自签名或受信任的 CA 签名的服务器和客户端证书来增强安全性的。此过程涉及证书的生成、验证和配置,以及客户端的信任设置,对于保护敏感数据传输和...

    信息技术_nginx双活+双向SSL认证+高并发+安全加固+会话共享+主被动健康探测

    - 需要在Nginx服务器上配置SSL证书,包括服务器端证书和客户端证书。 - 通过自签名证书或第三方CA机构签发的证书进行配置。 **2. 配置示例** - 在Nginx的配置文件中,定义HTTPS服务器块,并配置`ssl_certificate`和...

    nginx环境下配置ssl加密(单双向认证、部分https)

    在Nginx环境下配置SSL加密主要涉及单向认证、双向认证以及部分HTTPS页面加密。SSL(Secure Sockets Layer,安全套接层)和TLS(Transport Layer Security,传输层安全)是用于在网络上提供加密和数据完整性校验的...

    Nginx+SSL实现双向认证的示例代码

    以下将详细介绍Nginx配置SSL双向认证的全过程,包括相关命令的使用和配置文件的编写。 首先,需要创建一个工作目录用于存放证书文件。命令如下: ``` cd /etc/nginx mkdir ssl cd ssl ``` 接下来,需要创建证书...

    linux nginx双向认证服务搭建

    - 为了支持双向认证,还需要配置客户端证书验证的相关参数。 4. **Tomcat SSL配置**: - 在Tomcat的`server.xml`文件中,配置SSL Connector以启用HTTPS。 - 设置密钥库、证书密码等相关属性。 5. **Nginx反向...

    CentOS+Nginx配置详解

    配置 SSL 证书及私钥,以及客户端证书验证。在 `server` 块中添加: ```nginx ssl_certificate /path/to/your/server.crt; ssl_certificate_key /path/to/your/server.key; ssl_client_certificate /path/to/ca.crt...

    使用Nginx实现HTTPS双向验证的方法

    在Nginx中开启SSL/TLS支持并设置双向验证,需要在配置文件中指定服务器端证书和私钥的路径,同时启用SSL/TLS的客户端证书验证功能,配置服务器信任的CA证书文件,以验证客户端证书的合法性。 关于HTTPS握手过程,...

    一种基于Python+Nginx架构的双向CA系统设计与实现.zip

    5. **配置Nginx**:在Nginx服务器上,配置TLS监听端口,并设置需要客户端证书的验证规则。这通常涉及到在Nginx配置文件中指定CA的公钥,以便服务器可以验证收到的客户端证书。 6. **部署和测试**:将签发的客户端...

    nginx双向认证配置proxy_ssl_verify_depth详解

    当待验证的客户端证书是由intermediate-CA签发,而非有root-CA签发时,需要在proxy_ssl_trusted_certificate中配置intermediate-CA和root-CA组成的证书链文件 也就是说,直接尝试使用中级 CA 来验证客户端是无法通过...

    opesnssl证书配置和使用1

    4. **SSL双向/单向认证**:双向认证要求客户端和服务器都需验证对方的身份,而单向认证只需服务器验证客户端。openssl可以通过不同的命令行选项来实现这两种认证模式。 5. **导入证书**:生成的证书需要导入到...

    Tomcat 开启基于https的SSL配置

    * clientAuth:设置是否双向验证,默认为 false,设置为 true 代表双向验证 * keystoreFile:keystore 证书的路径 * keystorePass:生成 keystore 时的口令 五、启动 Tomcat 启动 Tomcat,然后就可以使用 HTTPS 和...

    自签署根证书、服务器证书、客户端证书

    对于服务器证书,还需要配置Web服务器以正确使用证书,例如在Apache或Nginx中配置SSL/TLS设置。 总结来说,自签署根证书、服务器证书和客户端证书在不同场景下各有作用,虽然自签署过程相对简单,但在公开互联网上...

    Gmssl两种证书demo

    2. EV(扩展验证)证书:EV证书是更高级别的证书,除了提供标准证书的安全功能外,还通过更严格的验证过程来增强用户信任。在浏览器中,拥有EV证书的网站的URL栏通常会显示为绿色,并显示发行证书的权威机构名称,...

    NGINX 宣布支持 gRPC,可在下个版本 1.13.10 中使用1

    配置自签名证书后,修改客户端以使用TLS连接并禁用证书验证。在实际部署中,应该使用受信任的CA颁发的证书。 6. **内部加密的gRPC服务**: 若要在内部网络中也加密gRPC通信,服务器应用需要配置为监听加密(grpcs...

Global site tag (gtag.js) - Google Analytics