按照网上教程折腾一翻,发现签发的证书无法在IOS设备上信任,本篇总结了折腾的经过。

背景

随着nas兴起,在搭建了plex,zerotier众多服务后,需要一个nginx代理整体内网流量。虽然有三个月免费的泛域名,但是来来回回挺麻烦的,不如直接自签一个

之前研究过自签证书,出现过ios这边证书有问题,但是其他环境没问题的情况。

这里也是想给nginx创建一个,踩坑整理一下。

信息及需求梳理

结构

1
2
3
# 根证书(发给手机等电脑信任一下)  ->  中继证书(一般负责一整块业务)  ->  业务证书 (具体服务,我这里是nginx)

# rootCA -> cloudCA -> nginx service

有效期

  • 根证书:100年
  • 中继证书:10年
  • 业务证书:824天

因为给nginx签的,太长浏览器会报错,如果是后端服务用长一点应该没事

签发证书

1.创建工作目录

1
2
# 老样子,创建本次工作目录,防止与其他文件冲突
cd ~ && mkdir ssl && cd ssl

2.生成各级配置文件

注意改组织名和最后业务证书的IP地址,域名

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 根证书配置文件
cat > rootCA.cnf <<EOF
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = SAN
extensions = SAN
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
0.organizationName = LiYao's House
organizationalUnitName = LiYao's Private Service

[SAN]
extendedKeyUsage = serverAuth
basicConstraints=CA:TRUE,pathlen:2
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
EOF

# 中继证书配置文件
cat > cloud.cnf <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName=@alt_names

[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = SAN
extensions = SAN

[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
0.organizationName = LiYao's Private Service
organizationalUnitName = LiYao's Cloud Dept

[SAN]
extendedKeyUsage = serverAuth
basicConstraints=CA:TRUE,pathlen:0

[v3_new]
extendedKeyUsage = serverAuth
EOF

# 业务证书
cat > nginx.cnf <<EOF
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = SAN
extensions = SAN
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
0.organizationName = LiYao's Cloud Dept
organizationalUnitName = LiYao's Nginx Service
[ alternate_names ]
DNS.1 = localhost
IP.1 = 192.168.1.1


[SAN]
subjectAltName = @alternate_names
extendedKeyUsage = serverAuth
basicConstraints=CA:FALSE,pathlen:0
subjectKeyIdentifier=hash
EOF

3.生成key文件

1
2
3
4
# openssl生成key,2048已经不安全,改为4096
openssl genrsa -out rootCA.key 4096
openssl genrsa -out cloud.key 4096
openssl genrsa -out nginx.key 4096

4.生成根证书

subj内容改成自己的

1
2
3
4
5
6
7
8
9
10
11
12
13
openssl req \
-newkey rsa:4096 \
-x509 \
-nodes \
-keyout rootCA.key \
-new \
-out rootCA.pem \
-subj "/emailAddress=liyao@lucat.fun/CN=LiYao's Root CA./C=CN/ST=Beijing/L=Beijing/O=LiYao's House/OU=LiYao's Private Service" \
-config ./rootCA.cnf \
-reqexts SAN \
-extensions SAN \
-sha256 \
-days 36500

5.生成中继证书csr及签发中继证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
openssl req -new -sha256 \
-key cloud.key \
-subj "/emailAddress=liyao@lucat.fun/CN=LiYao's Cloud CA./C=CN/ST=Beijing/L=Beijing/O=LiYao's Private Service/OU=LiYao's Cloud Dept" \
-config ./cloud.cnf \
-reqexts SAN \
-extensions SAN \
-sha256 \
-out cloud.csr


openssl x509 -req \
-in cloud.csr -CA rootCA.pem -CAkey rootCA.key \
-out cloud.pem \
-CAcreateserial \
-days 3650 \
-sha256 \
-extensions SAN \
-extfile cloud.cnf

6.生成业务证书csr及签发业务证书

这里,如果是给web使用的话,证书签发的时间不能超过825天,否则chrome或safari会提示证书不信任:NET::ERR_CERT_VALIDITY_TOO_LONG,意思证书时间过长。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
openssl req -new -sha256 \
-key nginx.key \
-subj "/emailAddress=liyao@lucat.fun/CN=LiYao's Nginx Service./C=CN/ST=Beijing/L=Beijing/O=LiYao's Cloud Dept/OU=LiYao's Nginx Service" \
-config ./nginx.cnf \
-reqexts SAN \
-extensions SAN \
-sha256 \
-out nginx.csr

openssl x509 -req \
-in nginx.csr -CA cloud.pem -CAkey cloud.key \
-out nginx.pem \
-CAcreateserial \
-days 824 \
-sha256 \
-extensions SAN \
-extfile nginx.cnf

MacOS配置

执行open . 打开ssl目录,双击rootCA.pem安装根证书,双击修改证书信任策略为始终信任

退出浏览器重新打开,锁则变为绿色

Iphone设置

使用隔空投送,将rootCA.pem推送至手机,用QQ,微信好像不行,不支持打开。

  1. 打开系统设置,点击添加提示,信任描述文件。
  2. 通用,关于本机下滑到底,证书信任设置中开启对证书的信任。