需求: 某些机密网站,仅允许特定电脑访问,能在运维方式解决,就不去麻烦开发!
安装或升级openssl
yum install -y openssl
安装nginx,这里已经安装,安装目录为/usr/local/nginx/
创建一个新的 CA 根证书,在nginx安装目录下新建 ca 文件夹并创建几个子文件夹
mkdir /usr/local/nginx/ca && cd /usr/local/nginx/ca
mkdir newcerts private conf server users
# newcerts 存放CA签署过的数字证书(证书备份目录);
# private 用于存放 CA 的私钥;
# conf 目录用于存放一些简化参数用的配置文件;
# server 存放服务器证书文件。
# users 客户端证书key的目录
以下的操作,确保在ca路径下操作
[root@localhost ca]# pwd
/usr/local/nginx/ca
在conf 目录新建 openssl.conf 配置文件
vi conf/openssl.conf
[ ca ]
default_ca = myserver
[ myserver ]
dir = /usr/local/nginx/ca
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/private/ca.crt
serial = $dir/serial
private_key = $dir/private/ca.key
RANDFILE = $dir/private/.rand
default_days = 3650
default_crl_days = 3650
default_md = sha256
unique_subject = no
policy = policy_any
[ policy_any ]
countryName = match
stateOrProvinceName = match
organizationName = match
localityName = optional
commonName = supplied
emailAddress = optional
创建自签CA
生成私钥key文件
openssl genrsa -out private/ca.key
生成证书请求csr文件
openssl req -new -key private/ca.key -out private/ca.csr -subj "/C=cn/ST=GuangDong/L=guangzhou/O=IBM/OU=ops/CN=MYCA"
生成凭证crt文件
openssl x509 -req -days 3650 -in private/ca.csr -signkey private/ca.key -out private/ca.crt
为key设置起始序列号,可以是任意四个字符
echo FACE > /usr/local/nginx/ca/serial
创建CA键库
touch /usr/local/nginx/ca/index.txt
为 "用户证书" 的移除创建一个证书撤销列表
openssl ca -gencrl -out private/ca.crl -crldays 3670 -config conf/openssl.conf
服务器证书的生成
生成一个key作server证书
openssl genrsa -out server/server.key 2048
为这key 创建一个证书签名请求csr文件
openssl req -new -key server/server.key -out server/server.csr -subj "/C=cn/ST=GuangDong/L=guangzhou/O=IBM/OU=ops/CN=123.com"
(这里CN是Common Name,也支持泛域名如*.123.com也可以是IP,自定义填写)
使用我们私有的CA key为刚才的key签名
openssl ca -in server/server.csr -cert private/ca.crt -keyfile private/ca.key -out server/server.crt -config conf/openssl.conf
client证书的生成
生成一个key作client证书
openssl genrsa -out users/client.key 2048
为这key 创建一个证书签名请求csr文件
openssl req -new -key users/client.key -out users/client.csr -subj "/C=cn/ST=GuangDong/L=guangzhou/O=IBM/OU=ops/CN=client"
(这里CN是Common Name是客户端证书名字,自定义填写)
使用我们私有的CA key为刚才的证书签名
openssl ca -in users/client.csr -cert private/ca.crt -keyfile private/ca.key -out users/client.crt -days 3670 -config conf/openssl.conf
将证书转换为大多数浏览器都能识别的 PKCS12 文件(过程可选填写应用证书密码)
openssl pkcs12 -export -clcerts -in users/client.crt -inkey users/client.key -out users/client.p12
下载客户端证书
sz /usr/local/nginx/ca/users/client.p12
nginx配置ssl
vi /usr/local/nginx/conf/nginx.conf
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 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
ssl_crl /usr/local/nginx/ca/private/ca.crl; #证书撤销列表
如何继续新建客户端用户证书
依然在ca路径下操作
[root@localhost ca]# pwd
/usr/local/nginx/ca
生成client证书
因之前已生成client.key文件,使用同一个即可,这里只需创建新用户client2的一个证书签名请求csr文件
openssl req -new -key users/client.key -out users/client2.csr -subj "/C=cn/ST=GuangDong/L=guangzhou/O=IBM/OU=ops/CN=client2"
使用我们私有的CA key为刚才的key签名
openssl ca -in users/client2.csr -cert private/ca.crt -keyfile private/ca.key -out users/client2.crt -days 3670 -config conf/openssl.conf
将证书转换为大多数浏览器都能识别的 PKCS12 文件
openssl pkcs12 -export -clcerts -in users/client2.crt -inkey users/client.key -out users/client2.p12
吊销证书
查看将要吊销的客户端私钥文件serial号
[root@localhost conf]# openssl x509 -in users/client.crt -noout -serial -subject
serial=FACF #查到serial号是FACF
subject= /C=cn/ST=GuangDong/O=IBM/L=guangzhou/CN=myclient
创建crlnumber并指定第一个吊销证书的编号
echo 01 > crlnumber
(第一次更新证书吊销列表前,才需要执行)
openssl.conf 增加吊销配置
vi conf/openssl.conf 增加下面配置
crlnumber= /usr/local/nginx/ca/crlnumber
(第一次吊销操作需要添加,完成后删除或注释掉,不然继续新建客户端用户证书 报错crlnumber:unknown)
执行吊销client证书(根据serial号)
openssl ca -revoke newcerts/FACF.pem -config conf/openssl.conf
重新刷新crl吊销列表
openssl ca -gencrl -out private/ca.crl -config conf/openssl.conf
查看吊销是否成功
openssl crl -in private/ca.crl -noout -text
在index.txt文件中可以看到被注销的证书前面已标记为R
cat index.txt
重启nginx
不然nginx不知道更新了吊销文件
客户端的使用
浏览器:
1. 下载客户端证书client.p12,直接全下一步安装,即可部署证书到个人项,重启浏览器即可访问。
2. IE,谷歌都可以正常访问,唯独旧版360类浏览器在谷歌内核模式下无法使用。
3. Firefox浏览器需在设置“隐私与安全”将证书中导入到“您的证书”,可解决,并不再弹警告。
4. IE,谷歌访问过程要点击选择确认证书1-2次,为减少次数,可添加网址到“受信任的站点”,
5. 为彻底解决IE浏览器"证书错误"警告,因自建CA,CA根证书不受信任,客户端得手动将根证书安装,生成p12格式根证书:
openssl pkcs12 -export -clcerts -in private/ca.crt -inkey private/ca.key -out MYCA.p12
客户端安装这p12格式根证书,添加到“受信任的根证书颁发机构”中即可。
6. 谷歌浏览器安全要求高,无法解除警报。
curl访问:
curl --insecure --key ./users/client.key --cert ./users/client2.crt 'https://123.com'
注意:
1. 服务器证书和客户端证书的省份、城市、域名信息等,需保持一致,commonName这个需要不同。
2. Win 版 openssl 未测试,但亲测,将所需的server.crt,server.key,ca.crt拿到win版nginx可以,在linux作吊销证书,再将吊销列表文件ca.crl放回win版nginx。
参考文献
nginx与ingress配置HTTPS双向认证-Linux@GNU-51CTO博客
SSL双向认证和SSL单向认证的流程和区别 - petercao - 博客园