1 前言
这里做集群,nginx做负载均衡,tomcat做server进行服务;在nginx上面做https双向认证;
2 nginx安装
在此忽略nginx的安装步骤,安装目录:/usr/local/nginx;
3 ssl双向证书生成
首先自己造ssl证书,用于双向认证使用;
在 nginx 安装目录下新建 ca 文件夹,进入 ca,创建几个子文件夹:
# mkdir ca
# cd ca
# mkdir newcerts private conf server
newcerts 子目录将用于存放 CA 签署过的数字证书(证书备份目录);private 用于存放 CA 的私钥;conf 目录用于存放一些简化参数用的配置文件;server 存放服务器证书文件。
编辑其内容如下:vi /usr/local/nginx/ca/conf/openssl.conf
[ ca ]
default_ca = foo # The default ca section
[ foo ]
dir = /usr/local/nginx/ca # top dir
database = /usr/local/nginx/ca/index.txt # index file.
new_certs_dir = /usr/local/nginx/ca/newcerts # new certs dir
certificate = /usr/local/nginx/ca/private/ca.crt # The CA cert
serial = /usr/local/nginx/ca/serial # serial no file
private_key = /usr/local/nginx/ca/private/ca.key # CA private key
RANDFILE = /usr/local/nginx/ca/private/.rand # random number file
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # message digest method to use
unique_subject = no # Set to ‘no’ to allow creation of
# several ctificates with same subject.
policy = policy_any # default policy
[ policy_any ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = match
localityName = optional
commonName = supplied
emailAddress = optional
# cd /usr/local/nginx/ca
# openssl genrsa -out private/ca.key
输出
Generating RSA private key, 512 bit long modulus
..++++++++++++
.++++++++++++
e is 65537 (0x10001)
private 目录下有 ca.key 文件生成。
# openssl req -new -key private/ca.key -out private/ca.csr
输入内容示例:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:SinoCache
Organizational Unit Name (eg, section) []:DevOpt
Common Name (eg, your name or your server’s hostname) []:*.zhoufengjie.cn
Email Address []:tyumen@zhoufengjie.cn
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# openssl x509 -req -days 365 -in private/ca.csr -signkey private/ca.key -out private/ca.crt
控制台输出
Signature ok
subject=/C=cn/ST=BeiJing/L=BeiJing/O=SinoCache/OU=DevOpt/CN=*.zhoufengjie.cn/emailAddress=tyumen@zhoufengjie.cn
Getting Private key
private 目录下有 ca.crt 文件生成。
# echo FACE > serial
可以是任意四个字符
# touch index.txt
#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 文件生成。
# openssl genrsa -out server/server.key
输出
Generating RSA private key, 512 bit long modulus
………………………++++++++++++
……………..++++++++++++
e is 65537 (0x10001)
server 目录下有 server.key 文件生成。
#openssl req -new -key server/server.key -out server/server.csr
这时会要求你输入和上面一样的那些问题,所有输入需要和那一步一致。但 A challenge password 是服务器证书口令,可以与根证书口令一致。这里:
输入示例:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:SinoCache
Organizational Unit Name (eg, section) []:DevOpt
Common Name (eg, your name or your server’s hostname) []:*.zhoufengjie.cn
Email Address []:tyumen@zhoufengjie.cn
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
server 目录下有 server.csr 文件生成。
# 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”
输出
两次都输入 y,server 目录下有 server.crt 文件生成。
# mkdir users
位置 /usr/local/nginx/ca/users。
# openssl genrsa -des3 -out /usr/local/nginx/ca/users/client.key 1024
要求输入 pass phrase,这个是当前 key 的口令,以防止本密钥泄漏后被人盗用。两次输入同一个密码(比如我这里输入 Password),users 目录下有 client.key 文件生成。
#openssl req -new -key /usr/local/nginx/ca/users/client.key -out /usr/local/nginx/ca/users/client.csr
提示输入 pass phrase,即 client.key 的口令。将pass phrase 口令输入后并回车:
要求你输入和 前面一样的那些问题。输入需要和那一步一致。但 A challenge password 是客户端证书口令(请注意将它和 client.key 的口令区分开!),可以与服务器端证书或者根证书口令一致:
输入示例:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:SinoCache
Organizational Unit Name (eg, section) []:DevOpt
Common Name (eg, your name or your server’s hostname) []:*.zhoufengjie.cn
Email Address []:tyumen@zhoufengjie.cn
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
users 目录下有 client.csr 文件生成。
# 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 :ASN.1 12:’BeiJing’
localityName :ASN.1 12:’BeiJing’
organizationName :ASN.1 12:’SinoCache’
organizationalUnitName:ASN.1 12:’DevOpt’
commonName :ASN.1 12:’*.zhoufengjie.cn’
emailAddress :IA5STRING:’tyumen@zhoufengjie.cn’
Certificate is to be certified until Mar 24 23:37:35 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 文件
#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
要求输入 client.key 的 pass phrase,输入 2.3.2 步输入的 pass phrase 并回车后:
要求输入 Export Password,这个是客户端证书的保护密码,在客户端安装证书的时候需要输入这个密码。我还是输入 Password。users 目录下有 client.p12 文件生成。
4 Nginx 配置
SSL 的目的是为了保证网络通信的安全以及数据完整性。所以,如果 tomcat 前面有了 nginx 作为反向代理,那就没有理由再在 nginx 和 tomcat 之间进行加密传输,毕竟二者处于同一内网。
如上图所示,客户端通过 SSL 请求过来的访问被反向代理 nginx 接收,nginx 结束了 SSL 并将请求以纯 HTTP 提交 tomcat。nginx 配置 nginx.conf增加如下内容:
upstream https_proxy {
#server 42.96.138.56:443 max_fails=0;
#server 42.96.138.56:80 max_fails=0;
server 192.168.231.224:8080 max_fails=0;
}
server {
listen 443 ssl;
server_name www.zhoufengjie.cn zhoufengjie.cn;
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;
location / {
proxy_redirect off;
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 $scheme;
#proxy_set_header Accept-Encoding “”;
add_header Power-By-Tyumen “$upstream_cache_status from $hostname”;
proxy_pass http://https_proxy;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0;
proxy_connect_timeout 30;
proxy_read_timeout 600;
}
access_log /data/logs/https_proxy.log custom_log;
}
5 Tomcat 配置
Nginx 反向代理 HTTP 不需要更改 Tomcat 配置。与 HTTP 代理不同的是,这里需要通过更改 tomcat 的配置文件来告诉它前面的 HTTPS 代理。将 %tomcat%/conf/ 以下部分:
<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=”www.zhoufengjie.cn”
proxyPort=”443″ />
6 配置验证
重启 tomcat,后台日志没问题,也可以看到小猫界面。
先关闭运行中的 nginx,如果你已经开启了的话。
谷歌浏览器使用 https 访问原有项目 https://www.zhoufengjie.cn,通过host固定是 Nginx 所在服务器,提示 400 Bad Request(No required SSL certificate was sent):
这是因为 https 双向验证需要客户端安装证书。windows os 下拿到生成的证书 client.p12,直接双击它,进入 “证书导入向导”:
一步一步下一步,最后直接点击 “完成” 按钮完成证书导入。
重启谷歌浏览器,再次访问 https://www.zhoufengjie.cn,浏览器要求我们选择证书:
选中刚才安装好的那个证书(www.zhoufengjie.cn),点击 “确定”,提示 “隐私设置错误”:
这是因为我们服务器用的是自己签发的证书。选择继续访问,守得云开见月明,终于看到久违了的项目登录页面,成功了:
可以点击浏览器输入框左侧的小锁图标查看我们导入的客户端证书相关信息:
7 双向 SSL 验证的集群配置
Nginx 做负载均衡器,多台 Tomcat 进行集群,在双向 SSL 验证的环境下的配置,和纯 HTTP 没有多少差异。只需注意以下细节即可。
调整upstreame即可。具体负载算法以及服务器列表依照实际情况自行调整。
所有设备,一样CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证,至此结束。
为了方便大家保存,www.zhoufengjie.cn上面的文章尽量都会做成pdf文档形式方便大家留存,尽最大方便给大家提供服务,本文文档(word原始文档)下载地址:点击下载
老大写的文章不错,学习了
Tremendous issues here. I’m very glad to peer your post. Thanks so much and I’m taking a look ahead to contact you. Will you kindly drop me a mail?