nginx配置https双向认证

基础知识

SSL: Secure Socket Layer, 安全套接字层,它位于TCP层与Application层之间。提供对Application数据的加密保护(密文),完整性保护(不被篡改)等安全服务,它缺省工作在TCP 443端口,一般对HTTP加密,即HTTPS。

SSL双向认证具体过程

  1. 浏览器发送一个连接请求给安全服务器。
  2. 服务器将自己的证书以及同证书相关的信息发送给客户端浏览器。
  3. 客户端浏览器检查服务器发送过来的证书是否是由自己信赖的CA机构所签发;如果是,就继续执行协议;如果不是,客户浏览器就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。
  4. 接着客户浏览器比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果一致的,客户浏览器认可这个服务器的合法身份。
  5. 服务器要求客户发送自己的证书。收到后,服务器验证客户的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得用户的公钥。
  6. 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。
  7. 服务器从客户发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户的公钥加密后通知浏览器。
  8. 浏览器针对这个密码方案,选择一个童话密钥,接着用服务器的公钥加密后发送给服务器。
  9. 服务器接收到浏览器发送过来的消息,用自己的私钥解密,获得童话密钥。
  10. 服务器、浏览器接下来的通讯都是用对称密码方案,对称密钥是加密过的。

制作根证书

  1. 生成CA私钥:ca.key (这个是信任的起点,所有其他的证书都要经过CA的私钥签名)

openssl genrsa -des3 -out ca.key 2048

  1. 生成CA根证书的公钥:ca.crt

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

制作服务端证书

  1. 生成证服务端书私钥:server.pem

openssl genrsa -des3 -out server.pem 2048

  1. 生成无密码的服务端私钥:server.key

openssl rsa -in server.pem -out server.key

  1. 生成服务端签发请求:server.csr

openssl req -new -key server.pem -out server.csr

  1. 最后用CA证书给服务端证书进行签名

openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt

把ca.crt的内容追加到server.crt后面,因为有些浏览器似乎不支持

cat ca.crt >> server.crt

制作客户端证书 (和制作服务端证书步骤一样)

  1. 生成客户端证书私钥

    openssl genrsa -des3 -out client.pem 2048

  2. 生成客户端证书签发请求

    openssl req -new -key client.pem -out client-req.csr

  3. 用CA证书给客户端证书进行签名

    openssl x509 -req -sha256 -in client-req.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out client.crt

  4. 客户端证书crt转换为PKCS #12格式(全称应该叫做 Personal Information Exchange,通常以 p12作为后缀)

openssl pkcs12 -export -clcerts -in client.crt -inkey client.pem -out crh.p12

  1. 将crh.p12安装到浏览器的可信任的根证书里

nginx配置

一、 Nginx安装

1. 安装编译工具及库文件

yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel

2. 首先要安装PCRE

PCRE 作用是让 Nginx 支持 Rewrite 功能。

  1. 下载PCRE安装包

    wget https://netix.dl.sourceforge.net/project/pcre/pcre/8.40/pcre-8.40.tar.gz

  2. 解压安装包

    tar zxvf pcre-8.40.tar.gz

  3. 进入安装包目录

    cd pcre-8.40

  4. 编译安装

./configure
make && make install

  1. 查看pcre版本

pcre-config –version

安装nginx

  1. 下载 Nginx,下载地址:https://nginx.org/en/download.html

wget http://nginx.org/download/nginx-1.18.0.tar.gz

  1. 解压安装包

tar zxvf nginx-1.18.0.tar.gz

  1. 进入安装包目录

cd nginx-1.18.0

  1. 编译安装

./configure –prefix=/usr/local/webserver/nginx –with-http_stub_status_module –with-http_ssl_module –with-pcre=/usr/local/src/pcre-8.35

注意:–with-pcre的值为刚刚你安装pcre的地址

make && make install

  1. 查看nginx版本

/usr/local/webserver/nginx/sbin/nginx -V

注意:此命令必须在nginx源码路径下执行

二、配置nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 server {
listen 9443 ssl; # 开启ssl
server_name 113.31.117.241; # 域名或者本机ip
ssl_certificate /usr/local/webserver/nginx/conf/cert/server.crt; # 服务端证书
ssl_certificate_key /usr/local/webserver/nginx/conf/cert/server.key; # 服务端私钥

ssl_session_cache shared:SSL:1m; # 配置共享会话缓存大小
ssl_session_timeout 5m; # session有效期5分钟
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2; #启用指定的协议
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL; #加密算法
ssl_prefer_server_ciphers on; # 优先采取服务器算法
ssl_verify_client optional_no_ca;# 开启客户端证书校验
ssl_client_certificate /usr/local/webserver/nginx/conf/cert/ca.crt; # CA证书用于验证客户端证书的合法性
ssl_verify_depth 6; # 校验深度
ssl_trusted_certificate /usr/local/webserver/nginx/conf/cert/ca.crt; # 将CA证书设为受信任的证书
# 减少点击劫持
add_header X-Frame-Options DENY;
# 禁止服务器自动解析资源类型
add_header X-Content-Type-Options nosniff;
# 防止XSS攻击
add_header X-Xss-Protection 1;

location / {
# start 防止跨域问题
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

if ($request_method = 'OPTIONS') {
return 204;
}
# end
root /home/ljcw/micro/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}

....

}

问题记录

1. 配置ssl后启动nginx报the "ssl" parameter requires ngx_http_ssl_module

原因:安装nginx时,没有安装http_ssl_module模块,现在我的nginx已经安装过了,怎么添加模块呢?

解决:

  1. 切换到源码包:

    cd /root/nginx-1.18.0

  2. 查看nginx原有模块

    1
    2
    3
    4
     [root@10-23-54-102 nginx-1.18.0]# /usr/local/webserver/nginx/sbin/nginx -V
    nginx version: nginx/1.18.0
    built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)
    configure arguments: --prefix=/usr/local/webserver/nginx
  3. 在configure arguments:后面显示的原有的configure参数如下

    configure arguments: –prefix=/usr/local/webserver/nginx

    那么我们的新配置信息应该这样写:

    ./configure –prefix=/usr/local/webserver/nginx –with-http_stub_status_module –with-http_ssl_module

  1. 配置完成后,运行命令make

    这里不要进行make install,否则就是覆盖安装

  2. 然后备份原有已安装好的nginx

cp /usr/local/webserver/nginx/sbin/nginx /usr/local/webserver/nginx/sbin/nginx.bak

  1. 将刚刚编译好的nginx覆盖掉原有的nginx(这个时候nginx要停止状态)

cp ./objs/nginx /usr/local/webserver/nginx/sbin/

  1. 然后启动nginx,仍可以通过命令查看是否已经加入成功

/usr/local/nginx/sbin/nginx -V