背景:
一般的网址都是采用单向认证的方式,即只有web服务器提供证书,保证服务器的签名准确性和安全性。
但是对于企业来说,也需要对客户端(或者浏览器端)进行认证,限定可访问服务器的机器,保证安全性。
基本知识:
X.509是证书标准,定义了证书需要包含哪些东西。
证书的编码主要有:PEM和DER两种。
相关文件后缀名:
KEY:用来存放私钥或者公钥的文件。
CSR:表示证书签名请求,即向认证中心(CA)提交的请求,由认证中心签发CRT或者CER证书。
CRT和CER:表示证书,linux下一般用CRT,以PEM编码为主;windows下一般用CER,以DER编码为主。
创建单向认证过程(linux环境):
1. 安装nginx,运行./configure需要用到--with-http_ssl_module参数,使其支持SSL
2. 进入你想创建证书和私钥的目录,例如:$ cd /usr/local/nginx.conf
3. 创建服务器私钥,命令会让你输入一个口令,生成key文件:$ openssl genrsa -des3 -out server.key 1024
4. 创建证书签名请求,生成CSR文件:$ openssl req -new -key server.key -out server.csr
5. 去除生成key文件时的口令,避免每次使用都要输入:
$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key
6. 根据创建证书签名请求和私钥,自己创建证书,当然也可以把csr文件发给CA,让他们整一个证书: openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
7. 配置nginx.conf,在server块下面添加以下配置:
ssl on;
ssl_certificate /usr/local/nginx/conf/server.crt; //证书
ssl_certificate_key /usr/local/nginx/conf/server.key; //私钥
8. 重新加载配置: /usr/local/nginx/sbin/nginx -s reload
以上步骤完成之后,即实现单向认证,可以用https访问nginx。
创建客户端证书过程(即实现双向认证):
双向认证其实就是在单向认证的基础上,添加了服务器对客户端(浏览器)的认证,如果服务端和客户端是一对一关系的话,只要像上面单向认证一样,生成一个证书(client.crt),然后生成可被浏览器导入的格式p12,当然可能还有其他的导入格式。
$ openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
在nginx.conf中需要添加以下配置:
ssl_client_certificate /usr/local/nginx/conf/client.crt; #客户的证书
ssl_verify_client on; #打开验证客户
实质就是弄一对证书和私钥出来,私钥给客户端加密,公钥留在nginx端,这样nginx就能识别客户了。
但如果是一对多关系的话,就需要用到证书链,即先生成一个根证书,然后通过根证书生成多个客户端证书,这样只要nginx信任根证书,所有从根证书签发的证书都会认可。
首先,得有一个CA,生成一个KEY文件ca.key 和根证书ca.crt:
$ openssl req -new -x509 -keyout ca.key -out ca.crt
配置openssl.conf,文件的路径可能不一样,可以locate命令查找,然后也需要生成一些文件:
$ vim /etc/pki/tls/openssl.cnf,主要是配置dir,这个dir是保存一些中间文件如pem文件的地方
$ touch /etc/pki/CA/{index.txt,serial}
$ echo 01 > /etc/pki/CA/serial
用根证书为之前生成的csr文件签名,生成由CA认证的证书:
$ openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
同理,可以对client的csr文件也生成由根证书签名的证书:
$ openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
然后就可以像上面一对一的一样,生成可被浏览器导入的文件:
$ openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
同时,在Nginx.cnf中的配置则变成这样,所有由根证书签名的证书都会被信任:
ssl_client_certificate /usr/local/nginx/conf/ca.crt; #根证书
我查找了很多博客,根据自己的配置过程,总结了这篇文章。基本上根据上面的配置,可以成功配置单向或者双向认证。