介绍使用OpenVPN的easy-rsa管理AWS Client VPN的客户端证书的方法。客户端认证中认证局(CA)的根证书是关键。

AWS Client VPN提供以下2种客户端身份验证方法。

  • 使用相互身份验证(该博客,介绍服务器及客户端的证书创建)
  • 使用用基于用户的身份验证

介绍「使用相互身份验证」时,使用OpenVPN easyrsa进行证书的基本管理方法。

概要

  • 创建 客户端VPN终端节点(Client VPN Endpoints) 指定证书
  • 创建 客户端VPN终端节点(Client VPN Endpoints)时,指定服务器证书ARN及客户端证书ARN
  • 如果服务器证书和客户端证书由同一个CA颁发,客户端证书ARN可指定为服务器证书ARN。而无需导入客户端证书
  • 可发布客户端证书
  • 可给每个用户创建各自的证书
  • 创建的证书无需关联至VPN Endpoints和ACM(AWSCertificationMangaer)
  • 客户端证书失效
  • 在CA进行失效,并更新客户端CRL(Certificate Revocation List)
  • 将CRL导入至Client VPN Endpoints

创建服务器端及客户端证书

参照 客户端身份验证和授权 的 生成服务器和客户端证书和密钥并将其上传到 ACM 进行操作。

在这里创建的主要文件有以下5个。

文件名 注释
ca.crt 证书链(Certificate Chain))
server.crt 服务器证书正文(certificate file)
server.key 服务器证书私有秘钥(private-key)
client1.domain.tld.crt 客户端证书
client1.domain.tld.key 客户端秘钥

安装可构筑CA认证中心的OpenVPN easy-rsa。可以在Git获取源代码,但也可以在EasyRSA 3.0.8下载 归档(tar.gz)文件。

[root@sysblog tmp]# wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz
[root@sysblog tmp]# tar zxvf EasyRSA-3.0.8.tgz
[root@sysblog tmp]# cd EasyRSA-3.0.8

初始化一个新的 PKI 环境。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /tmp/EasyRSA-3.0.8/pki

构建新的CA认证中心。CN(Common Name)指定ACM上创建的域名。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa build-ca nopass
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating RSA private key, 2048 bit long modulus
.................+++
..+++
e is 65537 (0x10001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:<Enter>

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/tmp/EasyRSA-3.0.8/pki/ca.crt

生成服务器证书和秘钥。在这里 server 是在ACM上导入证书后的域名

[root@sysblog EasyRSA-3.0.8]# ./easyrsa build-server-full server nopass
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
.+++
...............................+++
writing new private key to '/tmp/EasyRSA-3.0.8/pki/easy-rsa-14166.PyYVVr/tmp.GxBIT4'
-----
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-14166.PyYVVr/tmp.CjDe7C
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Dec 29 01:12:30 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

生成客户端证书及秘钥。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa build-client-full client1.domain.tld
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
...+++
............................................................................+++
writing new private key to '/tmp/EasyRSA-3.0.8/pki/easy-rsa-14601.cTL6gr/tmp.9k22Fh'
Enter PEM pass phrase:<输入pass phrase>
Verifying - Enter PEM pass phrase:<再次pass phrase>
-----
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-14601.cTL6gr/tmp.U7WMVS
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client1.domain.tld'
Certificate is to be certified until Dec 29 01:20:03 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

在这里生成的户端证书和客户端秘钥,设定VPN客户端时会使用。为每个用户创建VPN客户端证书和秘钥,重复该操作。
pass phrase可输入任意的字符窜,使用该证书连接VPN时需输入pass phrase。如果不想让用户输入pass phrase使用nopass选项。

# ./easyrsa build-client-full client1.domain.tld nopass

将服务器证书和密钥以及客户端证书和密钥复制到自定义文件夹。

[root@sysblog EasyRSA-3.0.8]# mkdir ~/custom_folder/
[root@sysblog EasyRSA-3.0.8]# cp pki/ca.crt ~/custom_folder/
[root@sysblog EasyRSA-3.0.8]# cp pki/issued/server.crt ~/custom_folder/
[root@sysblog EasyRSA-3.0.8]# cp pki/private/server.key ~/custom_folder/
[root@sysblog EasyRSA-3.0.8]# cp pki/issued/client1.domain.tld.crt ~/custom_folder
[root@sysblog EasyRSA-3.0.8]# cp pki/private/client1.domain.tld.key ~/custom_folder/
[root@sysblog EasyRSA-3.0.8]# cd ~/custom_folder/
[root@sysblog custom_folder]# ll
total 28
-rw------- 1 root root 1216 Sep 25 09:28 ca.crt
-rw------- 1 root root 4511 Sep 25 09:28 client1.domain.tld.crt
-rw------- 1 root root 1834 Sep 25 09:28 client1.domain.tld.key
-rw------- 1 root root 4602 Sep 25 09:28 server.crt
-rw------- 1 root root 1704 Sep 25 09:28 server.key

到这里为止为AWS官方文档。

ACM上导入证书

在创建客户VPN端点(AWS Client Endpoints)之前,在ACM注册证书。

如官方文档中所述,“只有在客户端证书AC认证中心与服务器证书CA认证中心不同时,才需要将客户端证书上传到ACM上。”

因为客户证书和服务器证书使用的是同一个CA认证中心,所以只在ACM上仅注册服务器证书。

使用AWS CLI导入证书的命令如下。

[root@sysblog ~]# aws acm import-certificate \
  --certificate file://server.crt \
  --private-key file://server.key \
  --certificate-chain file://ca.crt \
  --region region
{
    "CertificateArn": "arn:aws:acm:..."
}

在AWS管理页面导入证书的方法如下。选择 证书管理(CertificationManager)服务后,选择该域名后点击导入证书。

输入以下信息后,点击 下一步。

  • 证书正文:server.crt
  • 证书私有秘钥:server.key
  • 证书链:ca.crt

不设定标签,直接点击 审核并导入。

确认内容后点击 导入。

创建客户端证书

所有人可使用同一个客户端证书,也可以给每个客户端(用户)创建客户端证书后进行访问控制。

给客户端创建证书使用 easyrsa build-client-full 命令,并指定唯一的Entity。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa build-client-full client2.domain.tld nopass
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
..............................+++
............+++
writing new private key to '/tmp/EasyRSA-3.0.8/pki/easy-rsa-17632.Q2WjQS/tmp.QDDlrL'
-----
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-17632.Q2WjQS/tmp.nT3VwR
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client2.domain.tld'
Certificate is to be certified until Dec 29 02:16:45 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

将生成的以下2个文件,发送给用户。

  • 客户端证书:pki/issued/client2.domain.tld.crt
  • 客户端秘钥:pki/private/client2.domain.tld.key

创建的客户端证书无需关联至VPN Endpoints和ACM(AWSCertificationMangaer)。

更新客户端证书

在证书有效期限到期之前,需更新证书。更新证书,执行 easyrsa renew entity 命令。

更新 client1.domain.tld 证书的步骤如下。

证书有效期(EASYRSA CERT EXPIRE)默认为825天,默认为期限前30天开始可以更新证书(EASYRSA CERT RENEW)。EASYRSA_CERT_RENEW在30天以上有效状态下更新证书时发生的错误。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa renew client1.domain.tld
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017


Please confirm you wish to renew the certificate with the following subject:

subject=
    commonName                = client1.domain.tld


Type the word 'yes' to continue, or any other input to abort.
  Continue with renew: <输入yes>

Easy-RSA error:

Certificate expires in more than 30 days.
Renewal not allowed.

通过配置文件可控制,EASYRSA_CERT_EXPIRE及EASYRSA_CERT_RENEW参数。

[root@sysblog EasyRSA-3.0.8]# cp -p vars.example vars
[root@sysblog EasyRSA-3.0.8]# vi vars
<省略>
# In how many days should certificates expire?
#set_var EASYRSA_CERT_EXPIRE    825
<省略>
# How many days before its expiration date a certificate is allowed to be
# renewed?
#set_var EASYRSA_CERT_RENEW     30    # 修改前
set_var EASYRSA_CERT_RENEW      1000  # 修改后
<省略>

再次执行 easyrsa renew 命令,可确认成功更新。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa renew client1.domain.tld

Note: using Easy-RSA configuration from: /tmp/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017


Please confirm you wish to renew the certificate with the following subject:

subject=
    commonName                = client1.domain.tld


Type the word 'yes' to continue, or any other input to abort.
  Continue with renew: <输入yes>
Generating a 2048 bit RSA private key
.........+++
................................................................+++
writing new private key to '/tmp/EasyRSA-3.0.8/pki/easy-rsa-18839.L1p4Ra/tmp.0vEfj9'
Enter PEM pass phrase:<输入pass phrase>
Verifying - Enter PEM pass phrase:<再次输入pass phrase>
-----
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-18839.L1p4Ra/tmp.Sl7mAN
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client1.domain.tld'
Certificate is to be certified until Dec 29 02:38:11 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

使客户端证书失效

当客户端密钥泄漏或停止使用Client VPN Endpoints时,可使该证书失效。更新CA证书失效列表,并关联至Client VPN Points及CRL。

介绍使 client1.domain.tld 失效的步骤。

在CA上让使client1.domain.tld证明书失效。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa revoke client1.domain.tld

Note: using Easy-RSA configuration from: /tmp/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017


Please confirm you wish to revoke the certificate with the following subject:

subject=
    commonName                = client1.domain.tld


Type the word 'yes' to continue, or any other input to abort.
  Continue with revocation: <输入yes>
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-19354.nhS0ER/tmp.6jrIx1
Revoking Certificate 2F5FBE5ADD528BACB8649FCE98AF9129.
Data Base Updated

IMPORTANT!!!

Revocation was successful. You must run gen-crl and upload a CRL to your
infrastructure in order to prevent the revoked cert from being accepted.

将失效的 client1.domain.tld 证书,更新至CRL。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa gen-crl

Note: using Easy-RSA configuration from: /tmp/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Using configuration from /tmp/EasyRSA-3.0.8/pki/easy-rsa-19521.K80X2y/tmp.d0X7O1

An updated CRL has been created.
CRL file: /tmp/EasyRSA-3.0.8/pki/crl.pem

已失效(过期)证书,已无法在CA也找不到。

[root@sysblog EasyRSA-3.0.8]# ./easyrsa show-cert client1.domain.tld

Note: using Easy-RSA configuration from: /tmp/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017

Easy-RSA error:

No such cert file with a basename of 'client1.domain.tld' is present.
Expected to find this file at:
/tmp/EasyRSA-3.0.8/pki/issued/client1.domain.tld.crt

[root@sysblog EasyRSA-3.0.8]# cat pki/index.txt
V       231229011230Z           12413C52B11C88C99297CEB73E8A4C1A        unknown /CN=server
V       231229012003Z           0EAFF0348337DC350888ACCF444B7CDA        unknown /CN=client1.domain.tld
V       231229021645Z           D035B23FF2E545EFC00772DC96037C86        unknown /CN=client2.domain.tld
R       231229023811Z   210925024601Z   2F5FBE5ADD528BACB8649FCE98AF9129        unknown /CN=client1.domain.tld

将更新的CRL关联至Client VPN Endpoints。

aws ec2 import-client-vpn-client-certificate-revocation-list \
  --certificate-revocation-list file:///tmp/EasyRSA-3.0.8/pki/crl.pem  \
  --client-vpn-endpoint-id cvpn-endpoint-XXX
{
    "Return": true
}

确认已失效(过期)证书无法连接到该Client VPN Endpoints。