秋明

  • 首页
  • 1、系统
    • 1.1、linux系统
      • 1.1.1、内核
      • 1.1.2、脚本
      • 1.1.3、命令
    • 1.2、windows系统
  • 2、网络
    • 2.1、交换机
    • 2.2、路由器
    • 2.3、vpn隧道
  • 3、软件
    • 3.1、监控
    • 3.2、集群管理
    • 3.3、web系统
    • 3.4、web服务器
    • 3.5、代理及负载均衡
  • 4、工具
    • 4.1、跳板机
    • 4.2、脚本工具
  • 5、安全
  • 关于我

CentOS下配置nginx负载均衡做双向https认证代理+tomcat后端集群

在 2015年3月26日 上公布 作者为 秋明 文章分类 3.4、web服务器, 3.5、代理及负载均衡 .

1      前言

这里做集群,nginx做负载均衡,tomcat做server进行服务;在nginx上面做https双向认证;

2      nginx安装

在此忽略nginx的安装步骤,安装目录:/usr/local/nginx;

3      ssl双向证书生成

首先自己造ssl证书,用于双向认证使用;

  • 创建一个新的CA根证书

在 nginx 安装目录下新建 ca 文件夹,进入 ca,创建几个子文件夹:
# mkdir ca
# cd ca
# mkdir newcerts private conf server
newcerts 子目录将用于存放 CA 签署过的数字证书(证书备份目录);private 用于存放 CA 的私钥;conf 目录用于存放一些简化参数用的配置文件;server 存放服务器证书文件。

  • 在conf 目录中新建conf 文件

编辑其内容如下: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

 

 

  • 生成私钥 key 文件

# 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 文件生成。

  • 生成证书请求 csr 文件

# 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 []:[email protected]

 

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

 

 

  • 生成凭证 crt 文件

# 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/[email protected]

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

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

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

  • 创建 CA 键库

# 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 文件生成。

  • 服务器证书的生成
    • 创建一个 key

# openssl genrsa -out server/server.key
输出
Generating RSA private key, 512 bit long modulus
………………………++++++++++++
……………..++++++++++++
e is 65537 (0x10001)
server 目录下有 server.key 文件生成。

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

#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 []:[email protected]

 

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

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

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

# 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 文件生成。

  • 客户端证书的生成
    • 创建存放 key 的目录 users

# mkdir users
位置 /usr/local/nginx/ca/users。

  • 为用户创建一个 key

# openssl genrsa -des3 -out /usr/local/nginx/ca/users/client.key 1024

要求输入 pass phrase,这个是当前 key 的口令,以防止本密钥泄漏后被人盗用。两次输入同一个密码(比如我这里输入 Password),users 目录下有 client.key 文件生成。

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

#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 []:[email protected]

 

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

users 目录下有 client.csr 文件生成。

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

# 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:’[email protected]’

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 重启验证

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

  • Nginx 重启验证

先关闭运行中的 nginx,如果你已经开启了的话。

  • 客户访问 ssl 验证

谷歌浏览器使用 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 没有多少差异。只需注意以下细节即可。

  • Nginx 配置

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

  • Tomcat 配置

所有设备,一样CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证,至此结束。

 

为了方便大家保存,www.zhoufengjie.cn上面的文章尽量都会做成pdf文档形式方便大家留存,尽最大方便给大家提供服务,本文文档(word原始文档)下载地址:点击下载

2 评论
标签: https, nginx, tomcat, 证书 .
« CentOS下配置tomcat的https双向连接认证
CentOS下配置apache双向https认证负载均衡代理+tomcat集群 »

2 Responses

  1. 刘丕水 says
    2016年3月18日于上午10:23

    老大写的文章不错,学习了

    回复
  2. free chat says
    2016年8月15日于下午9:23

    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?

    回复

发表评论

发表评论 取消回复

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">