OpenSSL自签发代码 邮件 域名 IP 数字证书

发布时间:2018/11/7 8:48:14 打印 字号:

近期有需求签发 IP 证书,纵观全网,几乎千篇一律都是抄来抄去的,如果能用就算了,偏偏还是错的,真不晓得为什么转发都不能去验证一下。

先看看网上搜到的,基本上是说在 commonName 填入 IP 地址,或者添加 [v3_req] 字段并写入 IP 地址来实现,按此方法也确实可以成功签发证书,直接打开证书也不会报错,但浏览器却会报如下错误:

NET::ERR_CERT_COMMON_NAME_INVALID
此服务器无法证实它就是 x.x.x.x - 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。

可见此方式是有缺陷的,下面说说我是如何签发 IP 证书。

依赖

利用 OpenSSL 签发自然是需要 OpenSSL 软件及库,一般情况下 CentOS、Ubuntu 等系统均已内置,可执行 openssl 确认,如果出现 oepnssl: command not found 说明没有内置,需要手动安装,以 CentOS 为例,安装命令如下:

# yum install openssl openssl-devel -y

创建证书保存目录和记录文件,方便后续查找,比如放在用户目录的 demoCA 下:

# cd ~# mkdir demoCA && cd demoCA# mkdir private newcerts# touch index.txt# echo '01' >serial

修改 OpenSSL 配置文件,使之识别 demoCA 目录

# vim /etc/pki/tls/openssl.cnf......
[ CA_default ]#dir            = /etc/pki/CA           # Where everything is keptdir             = /root/demoCA
......

在 openssl.cnf 文件中还有很多实用的配置,比如生成证书请求文件(csr)用到的 countryName_default(默认国家)、stateOrProvinceName_default(默认省份)、localityName_default(默认城市)等等,在文件中设置好后续自签证书可以省去输入的步骤,视需求修改。

自建 CA

生成根密钥

# cd private/# openssl genrsa -out cakey.pem 2048Generating RSA private key, 2048 bit long modulus
...................................................+++
...............................................................................+++
e is 65537 (0x10001)

生成根 CA 证书

# openssl req -new -x509 -days 3650 -key cakey.pem -out cacert.pemYou are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [California]:
Locality Name (eg, city) [Mountain View]:
organization Name (eg, company) [VirCloud, LLC.]:
organizational Unit Name (eg, section) [Technical Support Dept.]:
Common Name (eg, your name or your server's hostname) []:VirCloud, LLC. Global Root CA
# cd ../ && mv private/cacert.pem ./

最终 cakey.pem 应存放于 demoCA/private/ 目录下,cacert.pem 存放于 demoCA/ 目录下,需注意。

添加信任

由于证书是自建的,所以要把根证书添加到受信任的根证书颁发机构,后续利用此 CA 签发的证书才会受信任,否则仍然会提示不可信。

# cat cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt

Firefox 火狐浏览器是自带证书系统的,通过上述导入安装根证书无法解决报错,所以应该再将证书其导入到 Firefox 浏览器(如有安装)中,将证书拖到地址栏回车确定按提示操作,或者在 选项 - 隐私与安全 - 查看证书 - 证书机构 - 导入,或者在浏览器报错时添加例外即可。

颁发证书

创建请求

# cd ..# openssl genrsa -out 127.0.0.1.key 2048Generating RSA private key, 2048 bit long modulus
...................................................................................................................................................................+++
................+++
e is 65537 (0x10001)# openssl req -new -key 127.0.0.1.key -out 127.0.0.1.csrYou are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [California]:
Locality Name (eg, city) [Mountain View]:
organization Name (eg, company) [VirCloud, LLC.]:
organizational Unit Name (eg, section) [Technical Support Dept.]:
Common Name (eg, your name or your server's hostname) []:local.domain       
Email Address [support@vircloud.net]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

附加用途

# vim 127.0.0.1.extkeyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName=@SubjectAlternativeName

[ SubjectAlternativeName ]
IP.1 = 127.0.0.1

与签发域名证书的区别(也是与其他教程的区别)就在于此步骤,在 不改 openssl.cnf 的情况 (方便签发不同证书)下如果是要签发 IP 证书必须参照上述格式执行此步骤。

如果要通过 修改 openssl.cnf 来签发证书,除将上述配置直接改到 openssl.cnf 相应位置外,必须将配置中的 basicConstraints = CA:FLASE 改为 basicConstraints = CA:TRUE,否则修改不生效,这是其他教程没有提到的。

如果是域名证书,也可以在此可以添加多域名,如:

......
subjectAltName=@SubjectAlternativeName

[ SubjectAlternativeName ]
DNS.1 = www.local.domain
DNS.2 = localdomain
IP.1 = 1.1.1.1

extendedKeyUsage 可以指定证书目的,即用途,一般有:
serverAuth:保证远程计算机的身份
clientAuth:向远程计算机证明你的身份
codeSigning:确保软件来自软件发布者,保护软件在发行后不被更改
emailProtection:保护电子邮件消息
timeStamping:允许用当前时间签名数据
如果不指定,则默认为 所有应用程序策略

签发证书

# openssl ca -in 127.0.0.1.csr -extfile 127.0.0.1.ext -days 365 -out 127.0.0.1.crtUsing configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep 26 05:16:18 2018 GMT
            Not After : Sep 23 05:16:18 2028 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = California
            organizationName          = VirCloud, LLC.
            organizationalUnitName    = Technical Support Dept.
            commonName                = local.domain
            emailAddress              = support@vircloud.net
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                IP Address:127.0.0.1
Certificate is to be certified until Sep 23 05:16:18 2028 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

使用 openssl.cnf 配置来签发,则命令是:

# openssl ca -in 127.0.0.1.csr -extensions v3_req -days 365 -out 127.0.0.1.crt

证书签发后即可更根据需要给网站或 APP 或代码使用了。

问题排查

  1. 问题:TXT_DB error number 2
    解决:原因是已经生成了同名证书,将 common name 设置成不同,或修改 demoCA 下的 index.txt.attr,将 unique_subject = yes 改为 unique_subject = no



参考文章:
1、《OPENSSL 制作 Ikev2证书
2、《証明書に x509v3 拡張属性を追加する
3、《附录 A. SSL/TLS 证书配置

正版原文来自欧文斯:https://vircloud.net/operations/sign-ip-crt.html