数字生活畅想家 为了更安全的网络环境 自建 CA 并自签发 SSL 证书

AndroidOL 20-04-26 关注

创作立场声明:希望大家能重视网络安全,不给犯罪分子可趁之机,互相学习。

Image by skylarvision from Pixabay
封面图片来自 skylarvision 托管于 Pixabay

为全力普及 HTTPS 各个浏览器厂商可谓是费尽心思、想方设法地让内容提供商摆脱 HTTP。由最先不显示到传输混合内容时显示不安全提示,再进一步到输入信息时显示不安全网页提示,最后干脆将所有 HTTP 页面标记为不安全。但目前还是随处可见各种 HTTP 网站不愿意切换,至于原因可能涉及到站长不理解 HTTPS 或不知道如何申请 SSL 证书,也可能是该站点已无人维护。

有很多人会说这个简单,直接用 Let's Encrypt 不就好了,网上各种全自动脚本一大把。Let's Encrypt 非常好,但有一些情况导致无法使用。第一是对站点没有管理权的情况(例如只是购买了一个空间,实际不能修改任何配置选项),其次就是该域名并不属于你本人所有。对于一些不使用或无法使用 80 端口的域名,Let's Encrypt 提供 DNS 验证,但也仅限于公网 DNS 发布的内容,对于内网 DNS 服务器所添加的条目自然不能认可。

好了,既然免费的 SSL 证书不能给自己用,那我自己给自己签证书总行了吧。当然可以,我们现在先创建一个最简单的证书并添加到 HTTP 配置中。

不安全的 HTTPS不安全的 HTTPS

嗯?怎么还是提示不安全呢,服务器和浏览器之间通信已经被加密了,这是为什么?哦,原来操作系统并不信任这张证书,毕竟谁都不承认也没办法。那怎么解决呢,反正已经加密通信了。好,继续访问吧。

这时候问题就来了,第一次,第两次没问题。但有一天,家里某台电脑中毒,被某些别用用心的人控制了。他没事儿再翻你的上网记录时发现了这些自签发证书的网址,心机一动,用同样的信息,同样的内容给你新建了一张证书。待你晚上回家乖乖上套。等你辛辛苦苦忙了一天回到家里访问站点时,与往常一样的不安全提示,此时你已经习惯性的点了继续访问,殊不知你和服务器之间的所有交流都已经被人监控。

当然以上情景都是危言耸听,而且实际操作也没那么简单,但自签发的 SSL 证书确实有这个问题,不被任何人信任,当你有一大堆域名(ESXi、Firewall、Switch、NVR 还有一些 Web 服务器)需要签发证书时,一个个设备添加信任一张张证书实在是浪费时间。原因也很简单,每一张证书都是完全独立,而没有人进行证书的统一管理。

认证机构认证机构

既然没有,我们自己造一个出来就是了,这就是 Catificate Authority 要做的事情了。我们所有签发的证书都属于自建的 Catificate Authority 管理,而我们只需要信任自己的 Catificate Authority 所签发的根证书即可。


第一步:建立 Catificate Authority

Windows 版:

cd && md myCAsignedcerts && md myCAprivate && cd myCA
echo '01'>serial && type nul > index.txt
notepad .myCAcaconfig.cnf

Linux 版:

cd && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCA
echo '01'>serial && touch index.txt
vim ~/myCA/caconfig.cnf

第二步:写入 Catificate Authority 配置文件并命名为 caconfig.cnf(本例仅供参考,详见 openssl.cnf)

[ ca ]
# 默认 CA 配置名称,可随意修改
default_ca = best_ca
# 第一节 [ CA 配置名称 ]
[ best_ca ]
# 指定 CA 根目录相对路径,这里需绝对路径,此处以 Linux 为例,Windows 请注意下面所有路径格式
dir = /home/tianhao/myCA
# 指定证书存放路径
certificate = $dir/cacert.pem
# 指定证书数据库路径
database = $dir/index.txt
# 指定新建签名证书存放路径
new_certs_dir = $dir/signedcerts
# 指定私钥存放路径
private_key = $dir/private/cakey.pem
# 指定证书序列号路径
serial = $dir/serial
# 指定默认证书吊销列表更新时间(个人用户可选无需更新吊销时间)
default_crl_days = 90
# 指定默认证书签发有效时间(根证书建议 3650 天,其他证书 365 - 1095 天)
default_days = 3650
# 指定默认证书加密方式(请勿使用 SHA256 以下算法)
default_md = SHA512
# 指定套用规则
policy = base_ca_policy
# 指定 X509 扩展信息
x509_extensions = best_ca_extensions
# 拷贝扩展信息
copy_extensions = copy

# 第二节 [ 规则名称 ]
[ base_ca_policy ]
# supplied 表示必填即可
# match 表示必须完全匹配
# optional 表示可选填写
commonName = supplied
stateOrProvinceName = match
countryName = match
localityName = optional
emailAddress = match
organizationName = match
organizationalUnitName = match

# 第三节 [ X509 扩展信息 ]
[ best_ca_extensions ]
basicConstraints = CA:true
nsCertType = server
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

# 第四节 [ req ]
[ req ]
default_bits = 4096
# 请注意文件路径是否存在
default_keyfile = $dir/private/cakey.pem
default_md = SHA512
# 是否显示询问对话框
prompt = no
# 指定构成字段,无需多次填写
distinguished_name = root_ca_distinguished_name

# 第五节 [ 构成字段 ]
[ root_ca_distinguished_name ]
# 这里指定 CA 机构显示名称
commonName = MyBestHome Root Certificate Authority
stateOrProvinceName = Shanghai
countryName = CN
localityName = Shanghai
emailAddress = my@example.com
organizationName = MyName
organizationalUnitName = MyBestHome

第三步:根据上一步创建的配置文件签发 CA 根证书(十年有效期)

Windows 版:

set OPENSSL_CONF=.myCAcaconfig.cnf
openssl req -x509 -newkey rsa:4096 -out cacert.pem -outform PEM -days 3650

Linux 版:

export OPENSSL_CONF=~/myCA/caconfig.cnf
openssl req -x509 -newkey rsa:4096 -out cacert.pem -outform PEM -days 3650

上述代码输入完成后将生成 cacert.pem 文件用户认证 CA 签发证书,只需将这个文件导入设备证书信任列表即可。

手动导入 Windows 信任证书手动导入 Windows 信任证书

第四步:为其他域名签发 SSL 证书(新建配置文件为某域名签发证书,单独建立目录并保存文件为 域名.cnf

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
# 是否显示询问对话框
prompt = no
[req_distinguished_name]
# 请务必注意必须满足 CA 规则要求(一致、必填、可选)
0.commonName = <替换为签发域名>
stateOrProvinceName = Shanghai
countryName = CN
localityName = Shanghai
emailAddress = my@example.com
organizationName = MyName
organizationalUnitName = MyBestHome
[v3_req]
basicConstraints = CA:FALSE
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth

第五步:依据上述各个域名的配置签发证书

Linux 版:

export OPENSSL_CONF=~/myCA/domain/<域名>.cnf
openssl req -out wap_csr.pem -newkey rsa:2048 -nodes -keyout wap_key.pem
-reqexts SAN -extensions SAN
-config <(cat ~/myCA/domain/<域名>.cnf
<(printf '[SAN]nsubjectAltName=DNS:<域名>,DNS:localhost'))
-sha512

第六步:批准

Windows 版:

set OPENSSL_CONF=.myCAcaconfig.cnf
openssl ca -in <域名>_csr.pem -out <域名>_crt.pem

Linux 版:

export OPENSSL_CONF=~/myCA/caconfig.cnf
openssl ca -in <域名>_csr.pem -out <域名>_crt.pem

已经显示绿色小锁已经显示绿色小锁

!!!证书签发到此为止已经完成!!!

第七步:吊销证书(请必须保留签发后的证书文件,比直接通过序号吊销来得简单)

openssl ca -revoke wap_crt.pem

第八步:生成吊销证书列表(一般情况无需理会,需提供 HTTP 访问该文件并在配置文件中加入该地址)

openssl ca -gencrl -out crl.pem openssl crl -in crl.pem

吊销证书列表用于防止因 CA 密钥或证书失密导致的无效证书可被继续使用的问题,但需要一个长期可供访问的 HTTP 站点比较麻烦,本章没有配置 CRL。

签发二级证书签发二级证书

自建 CA 的唯一优点是不担心自签名证书被人替换,但缺点是没有任何人会通过 SSL 去取你数据!!!

没有任何人会通过 SSL 去取你数据!!!

没有任何人会通过 SSL 去取你数据!!!

全部评论(28)
俞富源
1
2020-04-27

要不要考虑搞个一年免费的DV证书

AndroidOL
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
wlhwlh 1 连接是安全的 证书(有效)绿锁 2 您与此网站连接不安全 ⚠️(红色)3 工具浏览器chrome 15

不是,你看我头像右边不是有一串英文么,搜索一下这个试试看

wlhwlh
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
AndroidOL zdm不能发的吧,你要么就看看我头像右边 14

1 连接是安全的 证书(有效)绿锁 2 您与此网站连接不安全 ⚠️(红色)3 工具浏览器chrome

AndroidOL
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
wlhwlh 怎么传 我不懂 最近才学网络知识.加个微信 13

zdm不能发的吧,你要么就看看我头像右边

wlhwlh
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
AndroidOL 穿图床上看看 12

怎么传 我不懂 最近才学网络知识.加个微信

AndroidOL
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
wlhwlh 回复里面贴不了图? 11

复制文字告诉我也可以

AndroidOL
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
wlhwlh 回复里面贴不了图? 11

穿图床上看看

wlhwlh
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
AndroidOL 能不能贴个图,你看一下不安全原因是什么,点击锁图标可以看见。 10

回复里面贴不了图?

AndroidOL
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
wlhwlh 一样的域名 9

能不能贴个图,你看一下不安全原因是什么,点击锁图标可以看见。

wlhwlh
0
2020-05-11
wlhwlh @AndroidOL 您好:我有个树莓派4就自己用用.华硕路由器,有ddns,现在通过http://ddns:端口号. 想通过外网https访问内网webui.不知道怎么部署证书自建ca,进行https. 现在又申请let'encrypt 可这是在路由器上的IP,内网可以用吗?如果能用ca是部署在Apache或nginx且其他应用不需要部署?其他下载,kod,同步等webui需要部署吗?还有docker上怎么部署?啰嗦半天.望解惑!非常感激! 1
AndroidOL 第一个问题,我不知道你是通过你的路由器拨号还是光猫拨号,如果是路由器拨号,只需要在路由器上添加一条端口转发,比如内部地址127.0.0.1或者LAN地址(比如192.168.1.1)到WAN侧的8080,就可以通过DDNS:8080访问了,光猫拨号的话需要两边都做一下端口转发。第二个问题,自建CA只需要在树莓派上(openssl 1.1.0 以上)直接输入文章里的代码就行了。你用Let's Encrypt也不能对IP申请SSL证书,至少需要购买一个域名,然后DDNS更新域名的a记录。第三个问题,CA是openssl生成的,不需要Web服务器。第四个,如果域名不同需要为每个服务签发SSL,如果都是挂在一个域名下的则不需要,或者直接签发泛域名。第五个,无关服务种类和运行访问,只要能配置SSL证书就行。你的问题太零散,需要具体的内容一些我给你答复。 2
展开隐藏评论
AndroidOL 网址一样么 8

一样的域名