nginx配置https双向认证

4,317 阅读5分钟

基础知识

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

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

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

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

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

  1. 客户端证书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 downloads.sourceforge.net/project/pcr…

  1. 解压安装包

tar zxvf pcre-8.35.tar.gz

  1. 进入安装包目录

cd pcre-8.35

  1. 编译安装

./configure make && make install

  1. 查看pcre版本

pcre-config --version

安装nginx

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

wget nginx.org/download/ng…

  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

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

  1. 查看nginx原有模块
[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

  1. 在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,否则就是覆盖安装

  1. 然后备份原有已安装好的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