原理
通常情况下网站申请证书的步骤是网站管理员在自己的服务器上生成一个私钥,并生成一个证书签署请求(Certificate Signing Request简称CSR),网站管理员将这个CSR上传到CA的网站,CA根据这个CSR签署一个证书发回给网站管理员,网站管理员将这个发回的证书装到自己的nginx服务器上就OK了,用户再访问这个网站的时候就会看到网站地址栏的绿锁,因为用户的浏览器里或者操作系统里已经预装了世界上各大CA的根证书,所以用户访问的时候可以调本地的根证书来验证访问的网站的证书是否合法。
那么我们的内部测试域名显然CA是不会给我们签署证书的,因为CA签署证书的时候一般流程是给申请的网站对应的域名邮箱发一封邮件,而我们内网的测试域名没有暴露到公网,这个流程显然走不通,所以要给我们的网站申请证书只能我们自己冒充CA,自己给自己颁发一个证书,同时让测试的用户装上我们自己CA的根证书(因为显然我们伪造的CA不像那些知名的CA机构已经把根证书预装到用户的系统上了,所以要用户手动装一下)
PS:12306需要装证书的原理也是这样,12306并没有使用知名的CA机构颁发的证书,而是自己搞了个CA,然后自己给12306的网站颁发了个证书,12306的CA根证书没有预装在任何系统或浏览器中,用户打开12306的网站,浏览器会发现这个网站的证书是一个并不认识的CA机构颁发的,因此,我们访问12306会提示不安全。为什么大家批评12306的这个做法?因为CA机构的安全性要求是非常高的,CA上最重要的私钥一旦泄露,那么其他人就可以伪造这个CA任意颁发证书,假如有黑客拿到了这个私钥,伪造了证书装到钓鱼网站上,而用户恰恰又安装了12306的根证书,那么这时候用户访问钓鱼网站,浏览器会提示网站是安全的!这就是为什么大家不愿意装12306根证书的原因,12306的CA安全性无法获得大家的信任。至于12306为什么不使用知名机构的CA颁发证书,原因就不得而知了。
生成CA根证书
在CA目录下创建两个初始文件
cd /etc/pki/CA
touch index.txt serial
echo 01 > serial
生成根密钥
openssl genrsa -out private/cakey.pem 2048
生成根证书
openssl req -days 3650 -sha256 -new -x509 -key private/cakey.pem -out cacert.pem
生成客户证书
生成私钥
cd ~
openssl genrsa -out nginx.key 2048
生成证书签署请求
openssl req -new -sha256 -key nginx.key -out nginx.csr
签署证书
openssl ca -days 3650 -md sha256 -in nginx.csr -out nginx.crt
多域证书
普通证书只能保护一个域名,通配符证书能保护多个子域,但这两种证书对于我们来说都不是最好的,先看看我们的域名
hotel.hoteldev.abc.cn (线下环境)
hotel.hoteltest.abc.cn (staging环境)
还有诸如
pmc.hoteldev.abc.com
pmc.hoteltest.abc.com
等等
所以多域证书对我们来说会更方便,一个证书能够保护N个域名
生成多域证书的CSR
修改配置
# 不存在openssl.cnf的话可以参考附件
vim /etc/ssl/openssl.cnf
# 取消掉[req]节下面这一行的注释
req_extensions = v3_req
# 在[v3_req]一节添加下面一行
subjectAltName = @alt_names
# 在文件最后新增一节[alt_names]
[ alt_names ]
DNS.1 = domain1.com
DNS.2 = domain2.com
DNS.3 = sub.domain2.com
...
生成私钥
openssl genrsa -out nginx.key 2048
生成CSR
openssl req -sha256 -new -key nginx.key -out domain1.com.csr -config /etc/ssl/openssl.cnf
验证CSR
openssl req -in domain1.com.csr -noout -text
## 输出结果应该包含如下
X509v3 Subject Alternative Name:
DNS:domain1.com, DNS:domain2.com, DNS:sub.domain2.com
提交CA签署证书
# 要把openssl.cnf连同CSR一块传到CA的服务器上
openssl ca -config /etc/ssl/openssl.cnf -extensions v3_req -days 3650 -md sha256 -in hotel-test.csr -out hotel-test.crt
其他
在CA上签署了一个证书后,如果签署的证书有问题,我们会删掉重新签署,但这时候会报错,提示已经存在了,解决方法是把/etc/pki/CA/index.txt中对应的记录删除,然后重新签署这个证书
备注
注意sha256参数,表示加密算法使用sha256,如果不指定的话,默认是sha1,浏览器对于使用sha1签名算法的证书会报警告,只有sha256才是正常的绿锁
参考资料
http://seanlook.com/2015/01/18/openssl-self-sign-ca/
https://derekkwok.net/blog/2/generate-multi-domain-csr-with-openssl/