本文非原创,系浏览各博客后结合自身使用的一个总结,方便回顾。
前情提要
什么是x509证书链
- x509证书一般会用到三类文件,key,csr,crt。
- key是私用密钥,openssl格式,通常是rsa算法。
- csr是证书请求文件,用于申请证书。在制作csr文件的时候,必须使用自己的私钥来签署申请,还可以设定一个密钥。
- crt是CA认证后的证书文件(windows下面的csr,其实是crt),签署人用自己的key给你签署的凭证。
概念
- 根证书 生成服务器证书,客户端证书的基础。自签名。
- 服务器证书 由根证书签发。配置在服务器上。
- 客户端证书 由根证书签发。配置在服务器上,并发送给客户,让客户安装在浏览器里。
(把根证书安装到浏览器的受信CA中,访问服务器时就不会出警告了。)
首先要有一个CA根证书,然后用CA根证书来签发用户证书。用户进行证书申请:一般先生成一个私钥,然后用私钥生成证书请求(证书请求里应含有公钥信息),再利用证书服务器的CA根证书来签发证书。
步骤
自签名CA根证书
1、/root/ca目录下创建4个子目录:
- newcerts:存放CA签署过的数字证书。
- private:存放CA的私钥。
- conf:存放一些简化参数用的配置文件。
- server:存放服务器证书文件。
2、制作ca.key 私钥
openssl genrsa -out /root/ca/private/ca.key 2048
3、生成pem格式的根证书
openssl req -x509 -new -nodes \
-key /root/ca/private/ca.key \
-sha256 -days 1024 \
-out /root/ca/private/ca.pem
接下来提示将如下显示:
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GuangDong
Locality Name (eg, city) [Default City]:ShenZhen
Organization Name (eg, company) [Default Company Ltd]:Fatri
Organizational Unit Name (eg, section) []:Test
Common Name (eg, your name or your server's hostname) []:*.fatri.cn
Email Address []:a@fatri.cn
4、.pem转化为.crt(用于浏览器信任)
openssl x509 -outform der -in /root/ca/private/ca.pem -out /root/ca/private/ca.crt
签发服务器证书(客户端证书同理)
1、创建文件ca.conf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C = CN
ST = GuangDong
L = ShenZhen
O = Fatri
OU = Test
emailAddress = a@fatri.cn
CN = *.fatri.cn
2、创建文件v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.fatri.cn
DNS.2 = localhost
IP.1 = 172.28.2.105
IP.2 = 172.28.2.107
3、生成服务端证书签名请求,同时生成服务端私钥(nginx用)
openssl req -new -sha256 -nodes \
-out /root/ca/server/server.csr \
-newkey rsa:2048 -keyout /root/ca/server/server.key \
-config /root/ca/conf/ca.cnf
4、用ca私钥以ca的名义(ca.pem)给网站证书签名,加上v3.ext中的配置
openssl x509 -req -in /root/ca/server/server.csr \
-CA /root/ca/private/ca.pem \
-CAkey /root/ca/private/ca.key \
-CAcreateserial -out /root/ca/server/server.crt -days 1800 -sha256 -extfile /root/ca/conf/v3.ext
至此证书生成完毕!
接下来是使用流程。
服务端Nginx配置SSL
1、启动Nginx容器
docker run -d --name nginx-test --restart always\
-p 81:8080 -p 444:443 \
-v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /root/ca:/root/ca \
nginx:1.17.3
解释:
-d:后台运行 --name:容器名 --restart:重启设置
-p:端口映射(宿主机端口:容器内端口)
-v:数据挂载(容器内目录挂载到宿主机, ro将容器内配置文件设为只读模式, 只能在宿主机修改nginx配置)
2、打开防火墙端口81、444
firewall-cmd --add-port 81/tcp --permanent --zone=public
firewall-cmd --add-port 444/tcp --permanent --zone=public
firewal-cmd --reload
3、配置nginx.conf, 为了开发方便同时开启了http和https的访问,如果局域网统一配置了域名,不需要更改主机host就可以关闭8080端口或者将其重定向至443。
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
# 请求主机头字段,否则为服务器名称
proxy_set_header Host $host;
# 客户端ip地址
proxy_set_header X-Real-IP $remote_addr;
# 包含请求参数的原始URI,不包含主机名
proxy_set_header Request-Url $request_uri;
# 配置共享会话缓存大小,视站点访问情况设定
ssl_session_cache shared:SSL:10m;
# 配置会话超时时间
ssl_session_timeout 10m;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream shadow {
server 172.20.0.104:8080 weight=1;
}
upstream web {
server 172.20.0.109:8080 weight=1;
}
server {
listen 8080;
listen 443 ssl;
server_name *.fatri.cn;
ssl_certificate /root/ca/server/server.crt;
ssl_certificate_key /root/ca/server/server.key;
# 设置长连接
keepalive_timeout 70;
# 以下两项不建议显示设定
# ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
# 定义算法
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# 优先采取服务器算法
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://web;
}
location /api/v1/ws {
proxy_pass http://shadow;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
nginx重定向http请求配置(未测试)
server {
listen 80;
server_name *.fatri.cn;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.org;
root /etc/nginx/wwwroot/;
charset utf-8;
ssl_certificate /etc/nginx/ssl/example.org.bundle.crt;
ssl_certificate_key /etc/nginx/ssl/example.org.key;
# ...
}
4、修改Nginx配置文件nginx.conf, 修改后重启容器使配置生效
docker restart nginx-test
由于不是买的官方CA证书,所以需要让浏览器信任CA。
客户端添加信任证书
双击根ca.crt
导入证书(也可从控制面板搜索管理系统证书导入)
选择受信任的根证书颁发机构
配置主机映射
# 1、修改host
win10到C:\Windows\System32\drivers\etc目录下修改host(可先用文本编辑保存到桌面,在修改后缀名拖回文件夹覆盖原文件)
mac直接命令行`sodo vi /etc/hosts`
# 2、添加映射
172.28.2.105 dev.fatri.cn
# 3、刷新配置
win10还需进入终端输入`ipconfig/flushdns`刷新配置
mac应该直接修改后就生效