系统相关
首页 > 系统相关> > Linux随笔14-私有CA搭建并签发证书、ssh客户端和服务器端常用参数

Linux随笔14-私有CA搭建并签发证书、ssh客户端和服务器端常用参数

作者:互联网

Contents

1. 私有CA搭建

搭建私有CA,并用私有CA实现证书签发。那么就需要了解证书的一些基础术语。

1.1. 公钥加密方法

在上一篇博客中已经介绍过对称加密和非对称加密,详见2. TLS密钥交换过程部分的介绍。
非对称加密解决的是通信双方无需交换共有密钥(对称加密的时候,加密和解密双方使用的是相同的密码,所以加密一方将数据发送给另一方之后,另一方需要拥有相同的密码才能解开并抽取加密的内容,即共有密钥)的前提下实现安全通信,而这是通过双方互换公钥实现的。每一方都有自己的公私密钥对,使用公钥加密的数据,需要使用与公钥对应的私钥才能解密。A,B双方建立通信的时候,会互换公钥,A使用B的公钥将数据加密之后发送给B,B接收到A发送过来的加密内容之后,使用B的私钥将加密的内容解密。同理,B使用A的公钥将数据加密之后发送给A,A接收到B发送过来的数据之后,使用A的私钥将加密数据解密。
公私密钥对除了可以实现数据加密之外,还可以用于签名以及验证签名。使用私钥进行签名,然后使用公钥对私钥的签名进行验证,如果验证通过,说明是一对公司密钥。

如果在通信双方还未建立互信的时候,是如何完成公钥互换的呢?此时通过发送公钥给对方,然后让对方使用公钥加密之后,将数据返回,正常解密之后,即说明这个公私密钥对是匹配的。比如A要与B通信,B将自己的公钥发送给A,告诉A用这个公钥加密数据与B进行通信。而这个过程,需要借助PKI(Public Key Infrastructure,即公钥基础架构)来实现。

1.2. PKI - 公钥基础架构

PKI是通过CA(Certificate Authority,即证书权威)实现的绑定公钥协议,CA是其公钥已经预知的集中化受信的第三方。通过CA的方式,当A与B通信的时候,B会给A发送一个经过C签署的证书文件,而A是知道C并且信任C的,并且告诉A这个是B的公钥。这个被签发的信息就是证书,其中也会包含一些其他的信息,A是可以验证C签发的证书的,因为A事先已经有了C的公钥,所以此时可以通过这个证书与B建立互信的通信过程。

C为什么可信呢?因为C被根CA - D签署了证书,而互联网上的每个主机都知道D,而D在给C签发证书的时候,在其中包含了证书链文件,即证明C是由D签发的,是可信的。所以当A与B通信的时候,B将C签发的证书和证书链文件发给A,A通过证书链文件验证证书可信,之后建立正常通信过程。

1.3. x509 - 定义了公钥证书的结构

x509演化到现在,分为3个版本:

x509v3版本的数字证书中,包含如下内容:

其中,Issuer签发者和Subject证书主体包含的内容如下:

比如C=CN, ST=Beijing, L=beijing, O=Example Ltd, OU=IT, CN=www.example.com

另外一个重要的部分就是证书主体的公钥信息,其中包括如下内容:

1.4. 构建私有CA并签发证书

清楚了上述的这些基本术语,接下来就可以着手搭建私有CA,并给服务器签发证书了。实际的CA中,通常分为根CA和中间CA(也叫代理CA),根CA只负责给中间CA签发证书,不对互联网上的其他主机进行证书签发操作,这样可以确保根CA的私钥安全性,如果某个中间CA不安全了,那么只需要在根CA上将其证书吊销即可,那么所有由这个中间CA签发的服务器证书就全部不可信了。中间CA则是面对最终服务器进行证书签发处理。

为了模拟这个架构,我们将会使用3台虚拟机来完成本实验:c7u6s1用作根CA,c7u6s2用于中间CA(Intermediate CA),c7u6s3用作发起证书签属请求的服务器。

构建私有CA需要频繁使用到openssl这个命令。在开始构建之前,先简单介绍下这个命令。

1.4.1. openssl命令

这个命令支持两种操作模式:交互式和非交互式,下面的操作中,将在非交互模式完成。
其支持三种子命令形式:

要查看某个子命令的具体用法,在命令行中执行如下命令即可:

[root@LiuXianQiE ~]# openssl rsa --help
Usage: rsa [options]
Valid options are:
 -help              Display this summary
 -inform format     Input format, one of DER PEM
 -outform format    Output format, one of DER PEM PVK
 -in val            Input file
 -out outfile       Output file
 -pubin             Expect a public key in input file
 -pubout            Output a public key
 -passout val       Output file pass phrase source
 -passin val        Input file pass phrase source
 -RSAPublicKey_in   Input is an RSAPublicKey
 -RSAPublicKey_out  Output is an RSAPublicKey
 -noout             Don't print key out
 -text              Print the key in text
 -modulus           Print the RSA key modulus
 -check             Verify key consistency
 -*                 Any supported cipher
 -pvk-strong        Enable 'Strong' PVK encoding level (default)
 -pvk-weak          Enable 'Weak' PVK encoding level
 -pvk-none          Don't enforce PVK encoding
 -engine val        Use engine, possibly a hardware device
[root@LiuXianQiE ~]# 

上述即列出了openssl rsa这个子命令所支持的具体选项和含义。

1.4.2. 根CA设置

创建根CA需要用到加密的私钥和可公开的证书,即证书密钥对。根密钥文件 ca.key.pem 和 根证书文件 ca.cert.pem
根CA通常不会直接对服务器进行证书签署,它负责对可信的中间CA(Intermediate CA)进行证书签署,这样即便根CA离线也没有大问题,也可以最大限度的确保根CA安全。

由于用到PKI体系,系统将相关的文件都放在/etc/pki/这个目录中,包括我们这里作为CA角色的相关配置文件,在/etc/pki/CA/这个目录下面。

1.4.2.1. 创建所需目录和文件

根CA的角色定义,在名为openssl.cnf的配置文件中,其中包含了私钥文件的存放路径等信息。另外为了签署中间CA的证书,还需要一个index.txt的文件(用于记录已经签署的证书和后期吊销的证书信息)以及一个serial文件(记录证书序列号)。将这些文件都放置在/etc/pki/CA/这个目录中,具体如下所示:

[root@c7u6s1 ~]# cd /etc/pki/CA/
[root@c7u6s1 CA]# touch index.txt
[root@c7u6s1 CA]# echo 10 > serial
[root@c7u6s1 CA]# vim openssl.cnf
[root@c7u6s1 CA]# ls -lFh
total 24K
drwxr-xr-x. 2 root root   54 Jun 20 16:45 certs/
drwxr-xr-x. 2 root root    6 Oct 31  2018 crl/
-rw-r--r--  1 root root   99 Jun 20 16:45 index.txt
drwxr-xr-x. 2 root root   20 Jun 20 16:45 newcerts/
-rw-r--r--  1 root root 4.2K Jun 20 16:44 openssl.cnf
drwx------. 2 root root   24 Jun 20 16:21 private/
-rw-r--r--  1 root root    3 Jun 20 16:45 serial
[root@c7u6s1 CA]#

openssl.cnf这个配置文件的内容如下所示:

# OpenSSL root CA configuration file.
# Copy to `/root/ca/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /etc/pki/CA
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca.key.pem
certificate       = $dir/certs/ca.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = CN
stateOrProvinceName_default     = Beijing
localityName_default            =
0.organizationName_default      = LiuXianQiE Intermediate Ltd
organizationalUnitName_default  = Intermediate CA
emailAddress_default            =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

上述配置文件中,定义了私钥的位置、证书的存放路径以及吊销列表的相关设置等信息。同时包含了证书主体的一些默认设置。

有了上述这些文件,就可以准备根CA的私钥文件了。具体如下所示:

[root@c7u6s1 CA]# openssl genrsa -aes256 -out private/ca.key.pem 4096                                                                            
Generating RSA private key, 4096 bit long modulus                                                                                                
.................................................................................................++                                              
......................................................................................................................++                         
e is 65537 (0x10001)
Enter pass phrase for private/ca.key.pem:
Verifying - Enter pass phrase for private/ca.key.pem:
[root@c7u6s1 CA]# ls
certs/    crl/      newcerts/ private/
[root@c7u6s1 CA]# ls private/
ca.key.pem
[root@c7u6s1 CA]# ls -lh private/
total 4.0K
-rw-r--r-- 1 root root 3.3K Jun 20 16:21 ca.key.pem

上述证书签发时使用的对称密钥长度位4096,实际上,互联网证书通常采用2048位长度进行加密。

1.4.2.2. 使用私钥文件生成证书文件

openssl的配置文件和私钥文件准备好之后,就可以用这两个文件生成对应的证书文件了。具体如下所示:

[root@c7u6s1 ca]# openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 365 -sha256 -out certs/ca.cert.pem
Enter pass phrase for private/ca.key.pem:
You 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) [CN]:
State or Province Name [Beijing]:
Locality Name []:beijing
Organization Name [LiuXianQiE ltd]:
Organizational Unit Name []:Linux ^H
Common Name []:LiuXianQiE ltd Root CA
Email Address []:liuxianqie@localhost.com
[root@c7u6s1 ca]# 

当执行openssl req命令的时候,需要通过命令-config openssl.cnf指定所用的配置文件,如果不指定,那么这条命令执行的时候,将会使用默认的配置文件/etc/pki/tls/openssl.cnf

1.4.2.3. 验证根证书

验证根证书可以查看其中的证书信息,比如证书签发者、证书主体、签名算法等。具体如下所示:

[root@c7u6s1 CA]# openssl x509 -noout -text -in certs/ca.cert.pem
Certificate: 
    Data: 
        Version: 3 (0x2)
        Serial Number: 
            db:b6:c9:15:ad:0e:4e:a7
    Signature Algorithm: sha256WithRSAEncryption 
        Issuer: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA
        Validity 
            Not Before: Jun 20 08:23:50 2021 GMT 
            Not After : Jun 20 08:23:50 2022 GMT
        Subject: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA 
        Subject Public Key Info: 
            Public Key Algorithm: rsaEncryption 
                Public-Key: (4096 bit) 
                Modulus: 
                    00:e5:f3:e9:02:db:13:9e:5b:de:5d:7e:c4:c0:16:
                    56:21:9e:ab:d3:c1:b1:49:d4:61:c6:b2:40:5e:eb:
                    0a:5e:2a:ad:d5:92:3b:80:99:03:4b:6f:f7:fb:b0:
                    00:af:e1:fc:60:fa:81:9b:45:97:31:4a:c8:f0:b5:
                    a3:21:8a:74:6e:f7:6f:ba:0c:29:60:4a:e4:66:e3:
                    f4:39:66:65:2a:6f:c9:d1:d6:93:41:5d:73:fe:4d:
                    0b:3c:53:87:c8:4c:86:61:87:a1:88:69:c3:19:16:
                    e5:43:3a:e5:a0:72:c8:23:fa:a2:e6:aa:48:df:f3:
                    47:98:32:49:b2:01:b6:90:ec:85:b6:c0:d3:4a:39:
                    44:b7:c9:08:7f:91:95:8e:59:82:d6:65:c0:46:a5:
                    7e:51:71:92:f3:46:98:53:b9:18:67:4c:39:e8:2c:
                    c8:bb:a9:b8:a1:ce:03:be:8b:d2:91:90:65:11:5e:
                    04:96:1e:86:37:5d:62:4f:f5:93:8e:07:56:8a:53:
                    83:3d:73:78:84:cc:b9:fc:66:6e:14:c7:86:1b:1f: 
                    fc:40:05:35:27:3d:5d:f4:58:4e:09:35:85:33:90:
                    a6:0c:aa:9c:68:a9:4b:2f:23:70:a4:ac:54:30:8f:  
                    44:2f:46:47:76:51:d8:d8:88:2c:5a:aa:a4:96:b6:
                    94:23:9d:d8:2c:24:cc:6f:7b:72:48:d0:f2:b7:fd:
                    01:fe:6f:76:cb:b3:52:49:7d:fc:b7:76:32:c2:ab:
                    9d:1e:2b:a6:e7:dc:a0:e0:59:84:49:98:22:ef:a0:
                    52:f5:24:d2:90:c2:92:7b:48:d4:ff:98:f5:7c:42:
                    fb:8a:0b:94:b1:2d:3b:79:6c:8f:14:fa:02:00:12:
                    4e:66:6d:31:e8:fa:e5:0a:e6:7c:30:a1:ff:9c:c1:
                    8c:5a:9a:77:1d:5c:1d:9c:91:53:1d:85:40:3f:46:
                    c5:21:e1:c1:22:8e:a9:60:32:23:31:c1:74:8d:9a:
                    07:73:cf
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                0F:93:C4:54:6A:9F:8D:0F:2E:C3:A0:9B:BB:8F:ED:81:43:ED:64:B8
            X509v3 Authority Key Identifier: 
                keyid:0F:93:C4:54:6A:9F:8D:0F:2E:C3:A0:9B:BB:8F:ED:81:43:ED:64:B8

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         1a:c7:a1:3d:d5:cf:23:c7:30:a9:b0:7f:69:ea:72:20:93:b8:
         7e:f0:11:9d:81:e4:74:a1:cf:98:2d:36:a0:df:76:bd:9b:56:
         66:68:5e:00:aa:fc:34:2b:d3:84:17:68:a8:5e:8f:45:bd:2a:
         3b:fd:03:60:b2:85:e3:c2:eb:04:6c:0e:53:5a:c9:bb:49:46:
         17:f8:fb:8d:0d:9b:5d:a0:82:12:b5:75:55:41:5b:8d:90:88:
         b8:d9:9c:1d:f4:0e:3b:fa:e0:55:b3:22:63:0d:88:c0:ab:e8:
         ea:15:de:d5:83:6a:46:48:5a:99:7e:e9:34:a4:06:cd:af:0b:
         ec:5a:f8:23:f8:cb:80:a2:56:af:43:5d:9f:71:53:4c:d9:af:
         8f:1a:e2:8b:b1:f6:92:83:ce:87:00:dc:bb:1f:a1:75:fd:4a:
         cf:14:7b:dc:de:6b:e7:f1:43:d6:d4:a4:45:07:f6:d9:a5:d2:
         00:4b:55:34:d6:30:b0:5d:0d:45:3d:96:52:cd:78:50:b7:12:
         ce:4b:f8:f6:cd:be:7f:86:06:1b:cd:6f:0c:40:fa:ee:ce:d9:
         d4:f4:e4:c6:8f:41:be:92:da:67:dc:52:42:de:0a:bc:20:d0:
         07:f3:b1:69:7a:97:e1:58:eb:ec:97:4c:11:4e:23:9e:5b:3b:
         3a:a8:39:4c:38:97:fa:63:1a:ee:95:1a:72:d9:36:a1:30:dc:
         d5:9c:8b:96:ad:fa:9e:8e:7b:6d:55:72:a4:84:6b:bb:2e:f9:
         30:40:43:e3:43:f0:02:1b:25:d2:92:97:7c:50:9e:4b:dd:87:
         4e:de:d2:f1:93:15:4a:11:d3:ca:5a:6d:70:bf:a9:db:62:12:
         44:d8:a1:95:0e:9f:0b:1f:91:9f:f2:90:7c:44:93:24:c1:72:
         27:d0:5c:69:cf:cd:e7:3e:64:c9:d5:aa:3e:b8:5a:2c:b8:19:
         19:9e:f8:ad:38:64:d5:20:2d:64:15:88:82:e2:e7:58:6f:42:
         c9:38:26:8b:8e:59:e2:c1:8f:6d:bb:d5:47:4d:59:15:c3:70:
         ae:33:d3:27:aa:71:3a:9f:5e:76:4f:fd:ab:d4:b3:78:4e:19:
         49:44:18:af:30:b1:47:74:a4:34:96:36:64:0c:c4:87:fa:e7:
         e6:af:be:c0:9d:00:a1:e2:ec:5d:d7:bd:3e:61:b0:41:68:13:
         0f:1d:8f:e0:d6:bf:96:6a:be:68:2f:02:f1:ae:e7:e7:83:92:
         1f:3b:75:7d:55:85:1a:f5:b9:55:8e:57:48:e5:c0:63:54:9c:
         96:d0:aa:43:fb:1e:cf:f7:10:99:af:dd:d5:b2:a0:56:cb:3a:
         a7:54:90:2e:5b:ba:f1:8b
[root@c7u6s1 CA]#
[root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -issuer
issuer= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -subject
subject= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -dates
notBefore=Jun 20 08:23:50 2021 GMT
notAfter=Jun 20 08:23:50 2022 GMT
[root@c7u6s1 CA]#

1.4.3. 中间代理CA设置

中间CA代表根CA形式对终端服务器的证书签署操作,根CA只负责签署中间CA,从而形成信任的证书链。使用中间CA的目的,主要还是出于安全的目的隔离风险。
中间CA的虚拟机为c7u6s2,准备相应的文件和目录,具体如下所示:

[root@c7u6s2 ~]# cd /etc/pki/CA/
[root@c7u6s2 ~]# vim openssl.cnf
[root@c7u6s2 ~]# mkdir csr
[root@c7u6s2 CA]# ls 
certs  crl  csr  newcerts  openssl.cnf  private

csr是证书签署请求目录,用于存放后面生成的证书签发请求文件。
配置文件openssl.cnf的内容具体如下所示:

# OpenSSL intermediate CA configuration file.
# Copy to `/root/ca/intermediate/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /etc/pki/CA
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcertsdatabase          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/intermediate.key.pem
certificate       = $dir/certs/intermediate.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/intermediate.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_loose

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = CN
stateOrProvinceName_default     = Beijing
localityName_default            =
0.organizationName_default      = LiuXianQiE Ltd
organizationalUnitName_default  = Root CA
emailAddress_default            =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

同根CA的配置文件类似,其中也指定了私钥的存放路径和位置,证书吊销列表等信息。

1.4.3.1. 生成私钥

使用openssl genrsa -sha256生成私钥文件,具体如下所示:

[root@c7u6s2 CA]# openssl genrsa -aes256 -out private/intermediate.key.pem 4096                                                                  
Generating RSA private key, 4096 bit long modulus 
...................................................................++       
................++  
e is 65537 (0x10001) 
Enter pass phrase for private/intermediate.key.pem: 
Verifying - Enter pass phrase for private/intermediate.key.pem: 
[root@c7u6s2 CA]# chmod 400 private/intermediate.key.pem  
[root@c7u6s2 CA]# ll -hh private/intermediate.key.pem           
-r-------- 1 root root 3.3K Jun 20 16:30 private/intermediate.key.pem

生成的私钥文件如下所示:

[root@c7u6s2 CA]# ls private/ -lh
total 4.0K
-rw-r--r-- 1 root root 3.3K Nov 12 03:50 intermediate.key.pem
[root@c7u6s2 CA]# chmod 0400 private/intermediate.key.pem 
[root@c7u6s2 CA]# ls -lhF private/intermediate.key.pem 
-r-------- 1 root root 3.3K Jun 20 16:30 private/intermediate.key.pem
[root@c7u6s2 CA]#

1.4.3.2. 生成CSR证书签发请求文件

使用前面生成的私钥文件生成对应的证书签发请求文件,具体如下所示:

[root@c7u6s2 CA]# openssl req -config openssl.cnf -new -sha256 -key private/intermediate.key.pem -out csr/intermediate.csr.pem
Enter pass phrase for private/intermediate.key.pem:
You 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) [CN]:
State or Province Name [Beijing]:
Locality Name []:Beijing
Organization Name [LiuXianQiE Ltd]:
Organizational Unit Name [Root CA]:
Common Name []:LiuXianQiE Ltd Root CA
Email Address []:
[root@c7u6s2 CA]# ls
certs  crl  csr  newcerts  openssl.cnf  private
[root@c7u6s2 CA]# cd csr/
[root@c7u6s2 csr]# ls
intermediate.csr.pem
[root@c7u6s2 csr]# ll -h
total 4.0K
-rw-r--r-- 1 root root 1.7K Jun 20 16:34 intermediate.csr.pem
[root@c7u6s2 csr]# 

1.4.3.3. 使用证书请求文件申请根CA签发证书

将上一步操作中生成的证书签发请求文件发送给根CA,并在根CA上完成证书签署操作。具体如下所示:

[root@c7u6s2 csr]# rsync -av --progress -e 'ssh -p 22 -l root' intermediate.csr.pem c7u6s1:~  
root@c7u6s1's password: 
sending incremental file list
intermediate.csr.pem
          1,728 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/1)
sent 1,834 bytes  received 35 bytes  415.33 bytes/sec 
total size is 1,728  speedup is 0.92
[root@c7u6s2 csr]# 

接下来在根CA上使用中间CA的证书签发请求给其签发证书,注意,此处需要使用根前面使用过的根CA的配置文件。
下面是在c7u6s1这台根CA上执行证书签署操作,具体如下:

[root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate.cert.pem       
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 16 (0x10)
        Validity
            Not Before: Jun 20 08:45:21 2021 GMT
            Not After : Jun 20 08:45:21 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            organizationName          = LiuXianQiE Ltd
            organizationalUnitName    = Root CA
            commonName                = LiuXianQiE Ltd Root CA
Certificate is to be certified until Jun 20 08:45:21 2022 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
[root@c7u6s1 CA]# ls
certs  crl  index.txt  index.txt.attr  index.txt.old  newcerts  openssl.cnf  private  serial  serial.old                                        
[root@c7u6s1 CA]# ls certs/
ca.cert.pem            intermediate.cert.pem
[root@c7u6s1 CA]# ls -lh certs/intermediate.cert.pem 
-rw-r--r-- 1 root root 1.9K Jun 20 16:45 certs/intermediate.cert.pem
[root@c7u6s1 CA]# chmod 444 certs/intermediate.cert.pem
[root@c7u6s1 CA]# ls -lh certs/intermediate.cert.pem
-r--r--r-- 1 root root 1.9K Jun 20 16:45 certs/intermediate.cert.pem
[root@c7u6s1 CA]# ls 
certs  crl  index.txt  index.txt.attr  index.txt.old  newcerts  openssl.cnf  private  serial  serial.old
[root@c7u6s1 CA]# 

在根CA上对签发的证书进行验证,具体如下所示:

[root@c7u6s1 CA]# openssl x509 -noout -text -in certs/intermediate.cert.pem
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 16 (0x10)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA
        Validity
            Not Before: Jun 20 08:45:21 2021 GMT
            Not After : Jun 20 08:45:21 2022 GMT
        Subject: C=CN, ST=Beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:b3:d2:da:6c:a0:c8:ec:47:2a:de:8c:98:92:24:
                    cd:d5:93:3a:97:e7:32:fd:12:3f:b8:1a:0f:ab:da:
                    5c:38:76:ee:c7:55:27:45:b5:0a:9c:a0:a9:7e:91:
                    33:7b:59:ad:ec:c2:20:c4:64:ae:8e:a2:9c:b2:94:
                    59:a5:69:d7:ee:e1:c5:9b:f2:29:4f:8c:d5:0d:23:
                    e8:71:e2:04:b2:70:71:51:cb:ae:8c:a1:1d:48:92:
                    c2:3e:df:34:f4:08:dd:fb:1c:db:e7:bd:f7:b8:d7:
                    45:3a:5b:35:eb:16:2e:29:d9:60:98:2f:96:87:6b:
                    8e:cf:1f:91:1c:10:1c:2d:c7:29:ad:bd:b5:00:2c:
                    76:3e:96:2f:f5:fe:96:ca:bf:59:35:25:7f:c1:1c:
                    6a:73:b6:71:aa:f7:86:0b:99:93:f8:6c:cb:ce:81:
                    43:98:1e:cf:78:79:8d:f7:47:60:5a:5e:2d:22:cb:
                    0b:0e:ac:a6:68:2c:65:c9:13:31:1f:63:72:1f:02:
                    42:e1:84:75:6a:cb:a1:70:8c:3a:ac:4b:81:ef:5d:
                    b2:a7:df:ea:c9:fd:21:2f:bb:1a:83:e8:91:20:22:
                    a2:bf:02:73:78:29:39:f7:71:92:b7:ae:cb:68:cd:
                    48:8f:5c:8c:cf:4f:83:91:92:d3:2c:bd:6f:d2:c2:
                                        f0:b6:c4:82:5f:fb:0e:9c:49:9a:77:26:bf:55:4a:
                    26:64:95:b9:7e:ad:26:0c:d0:96:f4:bb:e1:f4:57:
                    57:97:c8:78:30:45:14:da:d6:3b:3e:2c:23:ea:7f:
                    39:f1:42:7e:79:84:22:06:07:40:5c:e2:46:62:fe:
                    96:bf:61:4d:02:6b:d0:2b:19:bf:bd:d9:09:47:c7:
                    f7:01:71:5d:15:5e:ad:96:df:99:06:77:60:07:c6:
                    aa:e9:5e:1c:13:80:90:f0:d1:05:1f:4d:aa:9c:9d:
                    a8:1a:a5:f3:c6:3a:fe:52:71:9f:e2:f0:d9:9b:c3:
                    cf:86:a7:79:e0:53:8a:b6:0d:47:66:87:23:8a:af:
                    7b:99:ff:d8:05:77:b9:ac:66:8f:41:2a:45:0b:47:
                    53:46:e8:4d:bb:3d:c0:71:27:a8:df:5d:14:f8:53:
                    ad:fe:41:f6:47:1c:93:e9:0a:1b:a7:45:3e:fd:c6:
                    06:40:01:03:3a:2e:3c:71:3b:dc:ae:a9:5e:66:7d:
                    20:a3:aa:67:67:35:59:f6:fe:f8:54:73:a1:89:fc:
                    28:12:85:70:d1:d5:ec:2f:16:ee:21:77:64:6d:d7:
                    d6:76:e4:f6:52:97:a6:17:d0:a3:9c:2d:c3:48:49:
                    9c:30:35:e1:f6:3d:6a:f7:64:0f:e0:bc:27:3f:f5:
                    1d:de:05
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         50:a6:cb:62:55:a5:21:48:61:72:16:f3:89:2c:92:71:88:5a:
         6c:92:51:43:dc:b5:98:d8:89:2c:d0:af:b8:44:48:80:dd:8d:
         0d:db:74:a3:ae:90:6b:8e:5f:8f:03:de:ac:e5:7b:77:a3:ed:
         b0:21:48:18:5a:59:72:18:37:20:8b:a4:70:e4:dd:e8:92:fb:
         03:fd:50:2e:a7:6a:9d:57:5f:fe:a5:48:8c:6d:88:65:8f:14:
         bc:2a:fd:6b:b5:75:c0:4a:ad:c7:c8:27:2a:91:2a:10:b5:60:
         71:fa:44:fd:84:c2:f1:9a:3d:6e:97:15:8b:66:82:52:b8:03:
         b2:4a:58:a6:dd:4b:6c:f7:13:5c:57:75:7b:40:67:74:c1:61:
         d3:bc:90:16:39:8e:17:d6:32:09:1b:99:f6:63:4b:62:b5:22:
         cb:8f:9b:8e:b6:f3:44:66:07:7c:43:78:11:04:4e:86:91:51:
         c9:cb:44:c1:7d:e5:51:02:36:69:ab:34:18:b1:fc:08:95:79:
                  13:c3:48:cd:fd:72:ee:3a:81:2a:fa:a4:96:b7:86:62:48:0c:
         c5:bc:c9:f5:22:82:fb:d5:16:d9:3a:da:7e:54:6b:95:b5:76:
         c2:fd:0b:8b:25:67:af:70:6e:cf:43:69:76:5c:c4:fa:02:3d:
         3a:70:ae:a4:d1:70:a6:7d:b7:f0:93:76:cd:eb:72:ba:36:b2:
         71:26:38:4d:cb:d1:22:43:f6:f3:30:ce:c9:69:2c:61:64:88:
         96:13:2e:0f:7c:47:55:56:b7:66:ed:53:79:6b:ad:05:8c:42:
         db:27:0d:88:02:2d:93:a5:36:ce:ce:2d:1e:92:04:3d:04:76:
         fe:83:c6:54:72:d8:4c:83:16:9d:78:88:d5:80:e6:c3:63:ef:
         2e:71:93:f0:9d:8d:44:e2:cc:6d:3f:fe:b5:63:4e:55:0c:c6:
         c3:23:b6:b1:bf:49:d0:0e:42:3d:54:e2:ce:e0:5d:12:4c:55:
         04:a9:f4:0c:ba:40:bc:96:b3:ae:ed:35:b2:2b:5a:b8:e9:b8:
         dd:a0:16:3c:c7:b4:b9:b4:b9:9f:7c:e7:bd:a3:2b:f3:a9:15:
         ce:a7:90:1d:79:35:2f:d0:19:22:ee:ee:e4:30:ac:77:ec:9b:
         90:31:c5:4c:3d:05:d9:23:b2:67:95:78:18:1f:20:8c:50:20:
         90:7b:af:f6:9d:1d:26:82:1c:34:74:e7:ba:62:20:59:b9:6f:
         0b:00:91:5e:5c:ea:da:c2:b2:83:46:9e:5e:17:4f:6d:95:c6:
         15:8e:f1:a9:e2:c3:5e:3a
[root@c7u6s1 CA]# openssl x509 -noout -dates -in certs/intermediate.cert.pem 
notBefore=Jun 20 08:45:21 2021 GMT
notAfter=Jun 20 08:45:21 2022 GMT
[root@c7u6s1 CA]# openssl x509 -noout -issuer -in certs/intermediate.cert.pem 
issuer= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# openssl x509 -noout -subject -in certs/intermediate.cert.pem 
subject= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# ls certs/
ca.cert.pem  intermediate-1.cert.pem  intermediate.cert.pem
[root@c7u6s1 CA]# 
[root@c7u6s1 CA]# openssl verify -CAfile certs/ca.cert.pem certs/intermediate.cert.pem 
certs/intermediate.cert.pem: OK
[root@c7u6s1 CA]# 

上面签发完证书之后,可以看出,增加了一些文件:“index.txt.attr, index.txt.old, serial.old”。查看这几个文件以及变化之前的文件内容,如下所示:

# index.txt的变化情况如下所示:
[root@c7u6s1 CA]# cat index.txt
V       220620084521Z           10      unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# cat index.txt.attr 
unique_subject = yes
[root@c7u6s1 CA]# cat index.txt.old 
[root@c7u6s1 CA]# 
# serial文件的变化情况如下所示:
[root@c7u6s1 CA]# cat serial
11
[root@c7u6s1 CA]# cat serial.old 
10
[root@c7u6s1 CA]# 

可以看出,index.txt.old是最初我们手动创建的一个空文件,而新的index.txt这个文件中记录根CA签发过的证书信息,比如证书序号等。而index.txt.attr这个文件则记录了签发操作的基本属性,unique_subject = yes表示一个证书签发请求文件只能对应生成一个证书文件,不能使用一个证书签发请求文件生成两个证书,具体如下所示:

[root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate-1.cert.pem
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 17 (0x11)
        Validity
            Not Before: Jun 20 09:11:15 2021 GMT
            Not After : Jun 20 09:11:15 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            organizationName          = LiuXianQiE Ltd
            organizationalUnitName    = Root CA
            commonName                = LiuXianQiE Ltd Root CA
Certificate is to be certified until Jun 20 09:11:15 2022 GMT (365 days)
Sign the certificate? [y/n]:y
failed to update database
TXT_DB error number 2
[root@c7u6s1 CA]# 

上述提示更新数据库失败。证书签发失败。如果将上面的index.txt.attr中的对应属性unique_subject = yes修改为no,那么就会允许执行上述操作。具体如下所示:

[root@c7u6s1 CA]# vim index.txt.attr
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate-1.cert.pem
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 17 (0x11)
        Validity
            Not Before: Jun 20 09:12:53 2021 GMT
            Not After : Jun 20 09:12:53 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            organizationName          = LiuXianQiE Ltd
            organizationalUnitName    = Root CA
            commonName                = LiuXianQiE Ltd Root CA
Certificate is to be certified until Jun 20 09:12:53 2022 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
[root@c7u6s1 CA]# ls -lh certs/
total 12K
-rw-r--r-- 1 root root 2.1K Jun 20 16:23 ca.cert.pem
-rw-r--r-- 1 root root 1.9K Jun 20 17:12 intermediate-1.cert.pem
-rw-r--r-- 1 root root 1.9K Jun 20 16:45 intermediate.cert.pem
[root@c7u6s1 CA]#
[root@c7u6s1 CA]# cat index.txt.attr
unique_subject = no
[root@c7u6s1 CA]# 

将intermediate-1.cert.pem这个证书吊销,然后将index.txt.attr这个文件改回yes状态,执行如下命令即可:

[root@c7u6s1 CA]# openssl ca -config openssl.cnf -revoke certs/intermediate-1.cert.pem 
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
Revoking Certificate 11.
Data Base Updated
[root@c7u6s1 CA]# 
[root@c7u6s1 CA]# vim index.txt.attr
[root@c7u6s1 CA]# cat index.txt.attr
unique_subject = yes
[root@c7u6s1 CA]# 

如果先改回yes状态,然后执行吊销,此时就无法执行吊销操作,甚至无法执行创建吊销列表的操作,具体如下所示:

[root@c7u6s1 CA]# openssl ca -config openssl.cnf -revoke certs/intermediate-1.cert.pem  
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
error creating name index:(2,0,1)
[root@c7u6s1 CA]# 
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem                                                                    
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
error creating name index:(2,0,1)
[root@c7u6s1 CA]#

上面无论是执行证书吊销操作,还是执行创建吊销列表的操作,都无法执行,且报错相同,都是无法创建名称索引。这个问题就是由于先将index.txt.attr中的属性从yes该为no之后,使用相同的证书签发请求文件创建了第二个整数,然后就将index.txt.attr中的属性从no又改回了yes状态导致的。再次将yes改回no,然后就可以执行证书吊销操作就可以正常完成了。

要执行吊销列表创建操作,需要在当前目录创建一个名为crlnumber(这个文件名以及下面的吊销列表的名称,都是在openssl.cnf这个文件中记录的)的文件,其中可以随便指定一个吊销序号,具体如下所示:

[root@c7u6s1 CA]# touch crlnumber
[root@c7u6s1 CA]# ls 
certs  crl  crlnumber  index.txt  index.txt.attr  index.txt.attr.old  index.txt.old  newcerts  openssl.cnf  private  serial  serial.old
[root@c7u6s1 CA]# ls crl
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
unable to load number from /etc/pki/CA/crlnumber
error while loading CRL number
140282462922640:error:0D066096:asn1 encoding routines:a2i_ASN1_INTEGER:short line:f_int.c:210:
[root@c7u6s1 CA]# echo 10 > crlnumber
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/ca.key.pem:
[root@c7u6s1 CA]# ls crl
ca.crl.pem
[root@c7u6s1 CA]# cat crlnumber
11
[root@c7u6s1 CA]# 

上述就完成了证书吊销列表的创建操作。
虽然intermediate-1.cert.pem这个证书已经被吊销,但是其并不会被自动删除。
吊销证书之后,此时CA目录中文件的变化情况如下所示:

[root@c7u6s1 CA]# ls 
certs  crlnumber      index.txt       index.txt.attr.old  newcerts     private  serial.old
crl    crlnumber.old  index.txt.attr  index.txt.old       openssl.cnf  serial
[root@c7u6s1 CA]# cat index.txt
V       220620084521Z           10      unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
R       220620091253Z   210620093349Z   11      unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# cat index.txt.attr
unique_subject = yes
[root@c7u6s1 CA]# cat index.txt.attr.old 
unique_subject = no
[root@c7u6s1 CA]# cat index.txt.old 
V       220620084521Z           10      unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
V       220620091253Z           11      unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s1 CA]# 
[root@c7u6s1 CA]# cat serial
12
[root@c7u6s1 CA]# cat serial.old 
11
[root@c7u6s1 CA]# 

可以看出,index.txt文件中,将被吊销的证书前面从V改成了R(V表示Valid,有效的;R表示Revoked,被吊销的)。

1.4.3.4. 创建证书链文件

当应用程序尝试验证中间CA签发的证书的时候,必然也会对给中间CA签发整数的根CA进行验证。为了实现链式信任,所以需要创建一个证书链文件并传给应用程序。要创建证书链文件,需要将根CA的证书和中间CA的证书合并在一起生成一个证书链文件,具体过程如下所示:

[root@c7u6s1 CA]# cat certs/intermediate.cert.pem certs/ca.cert.pem > certs/intermediate-root.cert.pem
[root@c7u6s1 CA]# ls -lhF certs/intermediate-root.cert.pem
-rw-r--r-- 1 root root 4.0K Jun 20 18:33 certs/intermediate-root.cert.pem
[root@c7u6s1 CA]# 

至此,证书链文件就创建完成了。

1.4.3.5. 将根CA给中间CA签发的证书和证书链发送给中间CA

有了上述根CA签发的证书以及证书链文件,将这个文件部署到中间CA的/etc/pki/CA/certs/这个目录中,中间CA就可以代表根CA对服务器进行证书签署了。

[root@c7u6s1 CA]# rsync -av --progress -e 'ssh -p 22 -l root' certs/{intermediate.cert.pem,intermediate-root.cert.pem} c7u6s2:~
The authenticity of host 'c7u6s2 (192.168.122.12)' can't be established.
ECDSA key fingerprint is SHA256:haaw1q6jKB6Gijmwapks1oMX8hSqub7AusDLPhErXxQ.
ECDSA key fingerprint is MD5:c3:c6:39:87:37:52:b7:38:40:1c:78:a2:40:a4:9e:4d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7u6s2,192.168.122.12' (ECDSA) to the list of known hosts.
root@c7u6s2's password: 
sending incremental file list
intermediate-root.cert.pem
          4,017 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=1/2)
intermediate.cert.pem
          1,919 100%    1.83MB/s    0:00:00 (xfr#2, to-chk=0/2)

sent 6,118 bytes  received 54 bytes  1,122.18 bytes/sec
total size is 5,936  speedup is 0.96
[root@c7u6s1 CA]#

然后将这两个文件放在中间CA的对应证书目录中,具体如下所示:

[root@c7u6s2 CA]# ls -lhF ~/intermediate*
-r--r--r-- 1 root root 1.9K Jun 20 16:45 /root/intermediate.cert.pem
-rw-r--r-- 1 root root 4.0K Jun 20 18:33 /root/intermediate-root.cert.pem
[root@c7u6s2 CA]# cp ~/intermediate{.cert.pem,-root.cert.pem} ./certs/
[root@c7u6s2 CA]# ls ./certs/
intermediate.cert.pem  intermediate-root.cert.pem
[root@c7u6s2 CA]# ls private/
intermediate.key.pem
[root@c7u6s2 CA]# 

至此,根CA以及中间CA就部署完成了。

1.4.4. 使用中间CA为服务器签发证书

由于服务器向中间CA申请证书的时候,不可能将自己的私钥文件发送给中间CA,所以就需要在服务器上先生成自己的私钥文件,然后用私钥文件生成证书签发请求文件。最后将证书签发请求文件发送给中间CA,并由中间CA完成证书签署操作之后,将签署的证书和证书链文件发送给服务器。具体过程如下所示:

1.4.4.1. 在服务器端生成私钥文件

[root@c7u6s3 ~]# mkdir certificates
[root@c7u6s3 ~]# cd certificates
[root@c7u6s3 certificates]# ls 
[root@c7u6s3 certificates]# openssl genrsa -aes256 -out www.example.com.key.pem 2048
Generating RSA private key, 2048 bit long modulus
.......................................................................................................+++
......................................+++
e is 65537 (0x10001)
Enter pass phrase for www.example.com.key.pem:
Verifying - Enter pass phrase for www.example.com.key.pem:
[root@c7u6s3 certificates]# ls 
www.example.com.key.pem
[root@c7u6s3 certificates]# ls -lh www.example.com.key.pem 
-rw-r--r-- 1 root root 1.8K Jun 21 01:03 www.example.com.key.pem
[root@c7u6s3 certificates]# chmod 400 www.example.com.key.pem
[root@c7u6s3 certificates]# ls -lhF www.example.com.key.pem
-r-------- 1 root root 1.8K Jun 21 01:03 www.example.com.key.pem
[root@c7u6s3 certificates]# 

此处私钥的对称加密密钥长度设置为2048,这也是大多数互联网公司的证书密钥长度,对于证书有效期为1年的证书,这个长度足够了。如果使用4096位长度的密钥,那么在TLS握手阶段将会增加CPU的开销。
上述就完成了发起证书签发请求的服务器上的私钥生成。接下来生成证书签发请求文件,并发送给中间CA,让其进行证书签发操作。

1.4.4.2. 服务器端生成证书签发请求文件

在服务器上使用前面生成的私钥文件,生成对应的证书签发请求文件,具体如下所示:

[root@c7u6s3 certificates]# openssl req -key ./www.example.com.key.pem -new -sha256 -out www.example.com.csr.pem
Enter pass phrase for ./www.example.com.key.pem:
You 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) [XX]:CN
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:Example ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:www.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@c7u6s3 certificates]# ls 
www.example.com.csr.pem  www.example.com.key.pem
[root@c7u6s3 certificates]# ls -lhF ./*
-rw-r--r-- 1 root root 1013 Jun 21 01:07 ./www.example.com.csr.pem
-r-------- 1 root root 1.8K Jun 21 01:03 ./www.example.com.key.pem
[root@c7u6s3 certificates]# 

上述就完成了证书签发请求服务器上的证书签发请求文件生成操作,随后将这个证书签发请求文件发送给中间CA之后,中间CA就可以根据这个证书签发请求文件完成证书签发操作。

将上述文件拷贝到中间CA,即c7u6s2这台虚拟机上。具体如下所示:

[root@c7u6s3 certificates]# rsync -av --progress -e 'ssh -p 22 -l root' www.example.com.csr.pem c7u6s2:~
The authenticity of host 'c7u6s2 (192.168.122.12)' can't be established.
ECDSA key fingerprint is SHA256:haaw1q6jKB6Gijmwapks1oMX8hSqub7AusDLPhErXxQ.
ECDSA key fingerprint is MD5:c3:c6:39:87:37:52:b7:38:40:1c:78:a2:40:a4:9e:4d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7u6s2,192.168.122.12' (ECDSA) to the list of known hosts.
root@c7u6s2's password: 
sending incremental file list
www.example.com.csr.pem
          1,013 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/1)

sent 1,122 bytes  received 35 bytes  100.61 bytes/sec
total size is 1,013  speedup is 0.88
[root@c7u6s3 certificates]# 

服务器的证书签发请求文件生成完毕,并且传送到了中间CA上。

1.4.4.3. 在中间CA上完成服务器的证书签署操作

查看接收到的证书签发请求文件,具体如下所示:

[root@c7u6s2 ~]# ls -lhF www.example.com.csr.pem 
-rw-r--r-- 1 root root 1013 Jun 21 01:07 www.example.com.csr.pem
[root@c7u6s2 ~]# 

接下来使用中间CA的配置文件完成上述证书签发

[root@c7u6s2 ~]# cd /etc/pki/CA/
[root@c7u6s2 CA]# ls
certs  crl  csr  newcerts  openssl.cnf  private
[root@c7u6s2 CA]# touch index.txt
[root@c7u6s2 CA]# echo 10 > serial
[root@c7u6s2 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/www.example.com.csr.pem -out certs/www.example.com.cert.pem 
Using configuration from openssl.cnf
Error opening CA private key /root/intermediate-ca/ca/private/intermediate.key.pem                                                              
140280877381520:error:02001002:system library:fopen:No such file or directory:bss_file.c:402:fopen('/root/intermediate-ca/ca/private/intermediate.key.pem','r')
140280877381520:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:404:                                                                
unable to load CA private key
[root@c7u6s2 CA]# vim openssl.cnf
[root@c7u6s2 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/www.example.com.csr.pem -out certs/www.example.com.cert.pem
Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/intermediate.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 16 (0x10)
        Validity
            Not Before: Jun 20 17:16:20 2021 GMT
            Not After : Jun 20 17:16:20 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            localityName              = beijing
            organizationName          = Example ltd
            organizationalUnitName    = IT
            commonName                = www.example.com
Certificate is to be certified until Jun 20 17:16:20 2022 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
[root@c7u6s2 CA]# 

第一次执行签发命令openssl ca的时候报错,提示没找到中间CA的私钥文件,这是因为我们的中间CA的配置文件中记录了CA的路径与实际的私钥存放路径不一致导致的,修改配置文件openssl.cnf中的路径即可。具体如下所示:

[root@c7u6s2 CA]# cat openssl.cnf | head -n15
# OpenSSL intermediate CA configuration file.
# Copy to `/root/ca/intermediate/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /etc/pki/CA
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
[root@c7u6s2 CA]# 

上述的配置文件前15行中,[ ca ]指定了默认的CA操作,采用[ CA_default ]中的定义,而这其中dir = /etc/pki/CA就定义了CA的证书根路径,下面是对应的证书的具体路径、吊销列表路径、新证书路径、数据库以及序列号文件等的具体路径信息。

修改为正确的路径信息之后,就可以正常签发证书了。

1.4.4.4. 在中间CA上查看已经签署的证书

中间CA完成了服务器端的证书签署操作,查看签署完成的证书,如下所示:

[root@c7u6s2 CA]# openssl x509 -noout -text -in certs/www.example.com.cert.pem
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 16 (0x10)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA
        Validity
            Not Before: Jun 20 17:16:20 2021 GMT
            Not After : Jun 20 17:16:20 2022 GMT
        Subject: C=CN, ST=Beijing, L=beijing, O=Example ltd, OU=IT, CN=www.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c0:6f:fe:65:c5:2f:1b:d9:6c:5c:f5:cd:20:51:
                    e0:ca:a4:23:ca:d2:5a:df:58:60:e6:72:1a:e4:c9:
                    a2:7d:ec:5d:6a:94:5f:9a:fe:bb:6d:51:0b:6e:c0:
                    dc:90:cd:4d:95:6e:55:db:df:ad:9e:83:b4:14:34:
                    b1:4f:e9:61:9d:5d:54:1d:80:c6:94:11:e7:aa:8d:
                    7d:16:a6:ca:24:e9:67:1d:c2:3a:a6:2a:ef:88:ef:
                    11:9d:0e:c2:cd:42:04:21:ad:62:42:38:66:7f:4d:
                    72:f4:a6:ad:ce:89:08:8a:75:35:40:b8:47:e0:04:
                    25:e7:af:df:6e:03:5a:e7:d6:1b:55:48:23:1d:48:
                    08:7f:e3:be:54:6f:c5:ac:6f:20:52:4d:d5:23:a4:
                    19:b1:fb:b2:4c:e7:7f:9c:60:8a:56:68:ec:29:21:
                    26:37:a9:f8:13:ab:dc:3d:74:52:6d:4e:96:3d:6c:
                    40:00:83:38:ad:3b:a2:aa:63:ab:33:cf:c5:e6:1e:
                    7f:bd:01:22:f2:bf:4f:b4:07:db:e3:84:28:c6:a5:
                    4b:26:75:41:94:ff:fa:71:f7:f4:8b:ee:e1:b9:ce:
                    85:0e:1f:19:0e:42:8f:4b:3b:99:5f:7a:5e:78:ac:
                    27:88:54:db:f8:9f:6f:fa:c5:2f:03:bd:5a:1a:e8:
                                        f0:cd
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         89:c7:2f:90:5b:4f:67:61:bd:e7:68:7b:6a:4d:b3:df:4b:22:
         c4:98:87:c4:60:e6:39:3d:09:1a:23:96:be:de:51:59:b5:9e:
         1d:85:7a:7d:6d:fd:03:84:03:46:71:56:7b:0d:a4:5c:a7:97:
         53:60:58:d9:05:b1:f5:b8:17:cf:1d:42:7b:3d:1c:23:cd:be:
         76:5a:20:7e:3d:a7:cd:d7:12:c0:90:ac:89:40:f8:5e:74:d2:
         ad:32:5d:7a:67:97:bf:9b:0d:3a:58:b4:0b:a0:8c:d5:b1:56:
         f2:a7:e2:fd:54:04:f8:55:a7:df:ea:50:ba:88:c8:5f:44:ad:
         12:59:c2:40:0a:70:34:7a:b9:66:7a:cf:9a:6d:8d:1b:c5:09:
         fa:ef:59:14:4a:f5:b0:5f:7f:2a:02:19:ee:dc:81:48:3f:60:
         8b:bd:b3:57:4b:b1:5b:12:4d:fb:b4:5c:96:db:a3:ac:f1:8d:
         52:4c:ca:2a:3c:f0:e2:fe:2f:54:fa:2c:bf:ad:1b:cb:59:95:
         96:9f:d9:48:ec:53:55:82:b9:c6:3c:db:ef:54:38:2c:0b:e8:
         7e:53:5e:85:ee:e4:16:a4:af:9b:29:29:59:fe:f2:19:d8:51:
         67:0c:b0:a0:b2:4b:68:e7:4c:1a:15:cf:68:52:6e:e7:7e:a3:
         cf:50:34:26:32:15:a4:f9:20:09:73:cf:45:62:b9:c1:b8:47:
         ec:81:a2:18:4f:e2:76:2c:aa:38:e8:66:36:bc:56:a5:25:85:
         74:3a:bd:9b:b7:5a:df:68:bd:4d:c4:43:26:9a:1f:06:a4:7c:
         b5:3e:76:ba:b1:a7:71:0b:ca:b5:f8:63:d4:19:25:83:41:30:
         ad:ff:a4:4f:35:63:37:e2:a7:75:0b:28:61:ef:8a:cb:6c:d7:
         9d:7c:93:63:bd:15:08:5b:95:fb:94:59:f8:2c:c5:32:44:49:
         6e:0f:45:ed:ba:18:1d:90:35:8b:52:62:16:21:bf:ab:cc:d5:
         e8:9f:e6:fa:83:3b:42:be:c1:12:57:80:50:c2:bc:50:c0:1e:
         7b:95:09:b1:34:7e:d9:ac:e0:da:09:ef:e0:59:02:fa:42:c1:
         2f:07:5e:2e:c9:c6:a7:32:1f:38:ec:af:d5:a6:75:33:a2:a6:
         dc:20:35:26:34:22:cb:87:3d:6d:bd:3c:29:45:d7:4f:97:34:
         6e:54:e1:67:4a:3b:05:ce:96:8a:bb:84:00:39:98:38:9b:05:
         e4:cb:51:49:5a:9b:b9:f2:46:25:b9:f8:97:56:b8:98:10:81:
         0e:8f:5e:ba:fb:da:49:e6:bd:2b:5b:f1:f8:6b:ea:3a:09:a1:
         3c:2e:76:04:c7:71:77:a3
[root@c7u6s2 CA]# openssl x509 -noout -dates -in certs/www.example.com.cert.pem 
notBefore=Jun 20 17:16:20 2021 GMT
notAfter=Jun 20 17:16:20 2022 GMT
[root@c7u6s2 CA]# openssl x509 -noout -issuer -in certs/www.example.com.cert.pem 
issuer= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s2 CA]# openssl x509 -noout -subject -in certs/www.example.com.cert.pem 
subject= /C=CN/ST=Beijing/L=beijing/O=Example ltd/OU=IT/CN=www.example.com
[root@c7u6s2 CA]# 
[root@c7u6s2 CA]# openssl verify -CAfile certs/intermediate-root.cert.pem certs/www.example.com.cert.pem 
certs/www.example.com.cert.pem: OK
[root@c7u6s2 CA]# 

证书签发完成,状态OK。上述最后的openssl verify命令中通过-CAfile certs/intermediate-root.cert.pem选项指定的文件是证书链文件,即此前根CA给中间CA签发证书的时候,连同着签署的证书一起将证书链发送给中间CA,以便证明CA的签发关系和合法性。

1.4.4.5. 将中间CA签署好的证书和证书链文件一同发送给服务器端

接下来将中间CA签发好的证书连同证书链一并发送给发起证书签发请求的c7u6s3这个服务器,具体如下所示:

[root@c7u6s2 CA]# ls certs/
intermediate.cert.pem  intermediate-root.cert.pem  www.example.com.cert.pem
[root@c7u6s2 CA]# rsync -av --progress -e 'ssh -p 22 -l root' certs/{intermediate-root.cert.pem,www.example.com.cert.pem} c7u6s3:/root/certificates
The authenticity of host 'c7u6s3 (192.168.122.13)' can't be established.
ECDSA key fingerprint is SHA256:HEaDOd4KItgL244FPiBzYyqzb+Sg/RIpsNG/oNiQUvg.
ECDSA key fingerprint is MD5:75:f3:2c:e7:e3:f7:42:93:28:c7:aa:d9:0b:28:6a:37.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7u6s3,192.168.122.13' (ECDSA) to the list of known hosts.
root@c7u6s3's password: 
sending incremental file list
intermediate-root.cert.pem
          4,017 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=1/2)
www.example.com.cert.pem
          1,554 100%    1.48MB/s    0:00:00 (xfr#2, to-chk=0/2)

sent 5,764 bytes  received 54 bytes  1,057.82 bytes/sec
total size is 5,571  speedup is 0.96
[root@c7u6s2 CA]# 

在证书签发申请服务器上查看签发好的证书和证书链,具体如下所示:

[root@c7u6s3 certificates]# ls -lhF ./*
-rw-r--r-- 1 root root 4.0K Jun 20 18:37 ./intermediate-root.cert.pem
-rw-r--r-- 1 root root 1.6K Jun 21 01:16 ./www.example.com.cert.pem
-rw-r--r-- 1 root root 1013 Jun 21 01:07 ./www.example.com.csr.pem
-r-------- 1 root root 1.8K Jun 21 01:03 ./www.example.com.key.pem
[root@c7u6s3 certificates]# 
[root@c7u6s3 certificates]# openssl x509 -noout -dates -in www.example.com.cert.pem 
notBefore=Jun 20 17:16:20 2021 GMT
notAfter=Jun 20 17:16:20 2022 GMT
[root@c7u6s3 certificates]# openssl x509 -noout -issuer -in www.example.com.cert.pem 
issuer= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA
[root@c7u6s3 certificates]# openssl x509 -noout -subject -in www.example.com.cert.pem 
subject= /C=CN/ST=Beijing/L=beijing/O=Example ltd/OU=IT/CN=www.example.com
[root@c7u6s3 certificates]# openssl verify -CAfile intermediate-root.cert.pem www.example.com.cert.pem 
www.example.com.cert.pem: OK
[root@c7u6s3 certificates]#

上述就完成了在证书签发申请服务器上的证书验证和查看。现在就具有了4个文件:

至此,私有CA设置以及证书签署操作就完成了。

2. ssh客户端常用参数

ssh客户端常用的一个参数是StrickHostKeyChecking,这个参数的作用是在初次建立到某个主机的连接的时候,将对象主机的公钥添加到本地的.ssh/known_hsots这个文件中。初次建立连接的时候会有一个询问过程,这是因为这个参数StrictHostKeyChecking ask的缘故,如果不想要这个询问的交互过程,可以将这个参数的值修改为no即可。这个参数支持3个有效的值,分别为ask, yes, no

[root@c7u6s4 ~]# ls .ssh/
authorized_keys  id_rsa  id_rsa.pub
[root@c7u6s4 ~]# ssh c7u6s6
The authenticity of host 'c7u6s6 (192.168.122.16)' can't be established.                                                                        
ECDSA key fingerprint is SHA256:Rn3dya2SjkXHSugIk+//fvGGNkdRFTfnLbortO+5FOU.                                                                    
ECDSA key fingerprint is MD5:e5:7d:10:15:0e:52:a1:8b:bb:d1:3a:d8:c1:29:41:3c.                                                                   
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7u6s6,192.168.122.16' (ECDSA) to the list of known hosts.                                                          
root@c7u6s6's password:
Last login: Fri Jun 18 18:56:04 2021 from 192.168.122.1
[root@c7u6-ha1 ~]# cat .ssh/known_hosts
ubuntu20u04,192.168.122.30 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJS3FPX8mGgBeW/E9f//eoM9SZfTr1z5s7xkqBuzdD/LJw8v0WNcqBeLOwn7+/e9yEvgxhig4Ol9IjHhx8zZIKc=
[root@c7u6-ha1 ~]# exit
logout
Connection to c7u6s6 closed.
[root@c7u6s4 ~]# cat .ssh/known_hosts
c7u6s6,192.168.122.16 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbnlzdHAyNTYAAABBBFQpwM5m3BoID+u8HOY5a/IRpbIQxUEWlTDFTjsMnUrhtjZO8Wc9DQXG2bruO19EZHmg2g+XDCIjVfmsu4Gd1OE=
[root@c7u6s4 ~]# 

要改变这个命令参数,有两种方式:

客户端连接服务器的时候,基本这个选项参数是最常用的,尤其在新设置的主机上,初次建立连接的时候。更多的ssh客户端的参数解释,参见man ssh_config

3. ssh服务器端常用参数

ssh服务器端的配置文件位于/etc/ssh/sshd_config,这个文件中记录了服务器相关参数设置。
比如服务器的端口号设置、监听的IP地址、登录验证方式、验证重试次数等等。具体如下所示:

上述是一些比较常见的sshd服务的设置参数。更多的服务器相关的参数解释,参见man sshd_config

4. References

[1]. OpenSSL Certificate Authority
[2]. How to setup your own CA with OpenSSL

标签:服务器端,证书,CA,openssl,pem,intermediate,root,14
来源: https://blog.csdn.net/ikkyphoenix/article/details/118084857