在OpenConnect VPN服务器(ocserv)中设置证书身份验证

本教程将向您展示如何在Debian / Ubuntu / CentOS / RHEL上的OpenConnect VPN服务器(ocserv)中设置证书认证。 OpenConnect(ocserv)是Cisco AnyConnect VPN协议的开源实现。

在上一篇文章中,我解释了使用“让我们加密TLS服务器”证书设置OpenConnect VPN服务器的步骤。 让我们加密不颁发客户端证书,因此在那篇文章中,我们使用了密码身份验证。 每次输入用户名和密码都会很麻烦,尤其是如果客户端软件(例如iOS上的Cisco AnyConnect应用程序)没有提供记住密码的选项时,尤其如此。 许多OpenConnect客户端软件都可以导入用户证书,这将使用户免于输入用户名和密码。 证书身份验证也比密码身份验证更安全。

先决条件

为了遵循本教程,假定您已经使用“让我们加密TLS”服务器证书设置了OpenConnect VPN服务器。 如果没有,请按照以下教程之一进行操作。

  • 使用Let’s Encrypt在Ubuntu 16.04 / 18.04上设置OpenConnect VPN服务器(ocserv)
  • 让我们加密在Debian 10 Buster上设置OpenConnect VPN服务器(ocserv)
  • 使用“让我们加密”在CentOS 8 / RHEL 8上设置OpenConnect VPN服务器(ocserv)

我们将建立自己的CA(证书颁发机构)来签署客户证书。 的 ocserv 守护程序应继续使用Let’s Encrypt颁发的TLS服务器证书,因此客户端软件不会显示安全警告。

设置自己的CA(证书颁发机构)

我们想使用证书身份验证,但是“让我们加密”不会颁发客户端证书,因此我们需要创建自己的CA。 您可以 openssl 做这项工作,但是ocserv建议使用GnuTLS,因此我将向您展示如何使用GnuTLS。

安装 gnutls-bin 在Debian / Ubuntu服务器上的软件包。

sudo apt install gnutls-bin

安装 gnutls-utils CentOS / RHEL上的软件包。

sudo dnf install gnutls-utils

在以下位置创建一个子目录 /etc/ocserv/ 持有私钥和证书。

sudo mkdir /etc/ocserv/ssl/

更改您的工作目录。

cd /etc/ocserv/ssl/

使用以下命令为CA生成私钥: certtool 命令,由 gnutls-bin 要么 gnutls-utils 包。 默认情况下,它将生成3072位RSA密钥,足够了。

sudo certtool --generate-privkey --outfile ca-privkey.pem

在生成CA证书之前,让我们创建CA证书模板文件。 模板文件格式可以在certtool手册中​​找到(man certtool)。

sudo nano ca-cert.cfg

将以下行添加到文件中。 用适当的值替换占位符。

# X.509 Certificate options

# The organization of the subject.
organization = "vpn.example.com"

# The common name of the certificate owner.
cn = "Example CA"

# The serial number of the certificate.
serial = 001

# In how many days, counting from today, this certificate will expire. Use -1 if there is no expiration date.
expiration_days = -1

# Whether this is a CA certificate or not
ca

# Whether this certificate will be used to sign data
signing_key

# Whether this key will be used to sign other certificates.
cert_signing_key

# Whether this key will be used to sign CRLs.
crl_signing_key

保存并关闭文件。 现在,使用模板文件中的配置生成CA证书。

sudo certtool --generate-self-signed --load-privkey ca-privkey.pem --template ca-cert.cfg --outfile ca-cert.pem

现在我们有了一个CA证书文件(ca-cert.pem)。

生成客户证书

现在运行以下命令以生成客户端私钥。

sudo certtool --generate-privkey --outfile client-privkey.pem

创建客户端证书模板文件。

sudo nano client-cert.cfg

将以下行添加到文件中。 uid必须是 /etc/ocserv/ocpasswd 文件。

# X.509 Certificate options
# The organization of the subject.
organization = "vpn.example.com"

# The common name of the certificate owner.
cn = "John Doe"

# A user id of the certificate owner.
uid = "username"

# In how many days, counting from today, this certificate will expire. Use -1 if there is no expiration date.
expiration_days = 3650

# Whether this certificate will be used for a TLS server
tls_www_client

# Whether this certificate will be used to sign data
signing_key

# Whether this certificate will be used to encrypt data (needed
# in TLS RSA ciphersuites). Note that it is preferred to use different
# keys for encryption and signing.
encryption_key

保存并关闭文件。 然后运行以下命令来生成客户端证书,该证书将由CA私钥签名。

sudo certtool --generate-certificate --load-privkey client-privkey.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --template client-cert.cfg --outfile client-cert.pem

将客户端私钥和证书合并到受PIN保护的PKCS#12文件中。

sudo certtool --to-p12 --load-privkey client-privkey.pem --load-certificate client-cert.pem --pkcs-cipher aes-256 --outfile client.p12 --outder

现在,我们将客户端私钥和证书合并到一个文件中 client.p12

请注意,iOS上的Ciso AnyConnect应用程序不支持AES-256密码,因此,如果用户使用的是iOS设备,则可以使用 3des-pkcs12密码。

sudo certtool --to-p12 --load-privkey client-privkey.pem --load-certificate client-cert.pem --pkcs-cipher 3des-pkcs12 --outfile ios-client.p12 --outder

客户端私钥和证书合并为一个文件 ios-client.p12

证书签名请求

为了使最终用户的私钥保密,用户可以使用自己的私钥生成证书签名请求(CSR),然后将证书请求发送给admin,然后由admin向用户颁发客户端证书。 首先,他们必须使用上述命令生成私钥和客户端证书模板。 然后使用以下命令生成CSR。 的 request.pem 文件由用户的私钥签名。

certtool --generate-request --load-privkey client-privkey.pem --template client-cert.cfg --outfile request.pem

接下来,用户发送 request.pemclient-cert.cfg 文件发送给管理员,管理员运行以下命令来生成客户端证书。

sudo certtool --generate-certificate --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --load-request request.pem --template client-cert.cfg --outfile client-cert.pem

之后,管理员发送 client-cert.pem 证书文件提供给用户。

在ocserv守护程序中启用证书认证

编辑ocserv配置文件。

sudo nano /etc/ocserv/ocserv.conf

在上一教程中,我们添加了以下行以启用密码身份验证。

auth = "plain[passwd=/etc/ocserv/ocpasswd]"

要启用证书身份验证,请取消注释以下行。

auth = "certificate"

如果以上两行均未注释,则意味着用户必须同时通过密码验证和证书验证。 因此,如果证书身份验证足以证明身份,则注释掉第一行。

如果允许用户选择证书身份验证或密码身份验证,则应改用以下几行。

enable-auth = "plain[passwd=/etc/ocserv/ocpasswd]"
auth = "certificate"

现在找到ca-cert参数。 在Debian / Ubuntu上,它设置为

ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem

在CentOS 8 / RHEL 8上,它设置为

ca-cert = /etc/ocserv/ca.pem

我们需要使用自己的CA证书来验证客户端证书,因此请将此行更改为

ca-cert = /etc/ocserv/ssl/ca-cert.pem

接下来,找到以下行。

cert-user-oid = 0.9.2342.19200300.100.1.1

您不需要更改它。 我只想告诉你 0.9.2342.19200300.100.1.1 代表客户端证书中归档的UID。 上面的线告诉 ocserv 守护程序,可从客户端证书的UID字段中找到用户名。 如果客户端证书已通过CA证书成功验证,并且 ocserv 守护程序可以在中找到匹配的用户名 /etc/ocserv/ocpasswd 文件,然后客户端可以登录。

保存并关闭文件。 然后重新启动ocserv。

sudo systemctl restart ocserv

在Debian / Ubuntu / CentOS / RHEL桌面上使用证书认证

使用 scp 命令下载 client.p12 文件到您的Debian / Ubuntu / CentOS / RHEL桌面。

scp [email protected]:/etc/ocserv/ssl/client.p12 ~

然后安装 openconnect 客户端软件。

Debian / Ubuntu:

sudo apt install openconnect

CentOS / RHEL:

sudo dnf install epel-release
sudo dnf install openconnect

要使用证书身份验证,请运行

sudo openconnect -b vpn.example.com -c client.p12

系统将要求您使用在本教程中设置的密码来解锁客户端私钥。

ocserv客户端证书ubuntu

如果密码输入正确,则您现在应该已连接到VPN服务器。

在Windows和MacOS桌面上使用证书身份验证

从OpenConnect GUI Github页面下载适用于Window或MacOS的OpenConnect GUI客户端。 然后创建一个新的VPN连接配置文件,并将PKCS#12文件导入到用户证书字段。 单击保存按钮。 您需要输入PIN才能解锁私钥。 导入后,您无需再输入用户名和密码。

openconnect GUI客户端证书认证

在iOS设备上使用证书身份验证

iOS用户可以使用Cisco AnyConnect应用程序。 要在AnyConnect应用程序中导入客户端证书,您可以先将PKCS#12文件发送到附件中的电子邮件地址。 然后在iOS上打开邮件应用。 点击附件几秒钟,然后与AnyConnect共享。 然后输入PIN码以导入文件。

ios anyconenct导入客户端证书

导入后,在AnyConnect中编辑您的VPN连接。 去 Advanced -> Certificate 并选择客户端证书。 保存设置。

iOS AnyConnect客户端证书认证

现在,您不再需要在iOS设备上输入用户名和密码。 Cisco AnyConnect应用程序不会记住用户名和密码,因此在密码身份验证模式下,不使用电话时VPN连接将断开。 在证书身份验证模式下,如果断开连接,该应用程序将自动重新连接到VPN服务器。

iOS上的AnyConnect客户端问题

在TLS 1.3协议中使用证书身份验证时,iOS上的AnyConnect客户端的最新版本存在问题。 您需要使用密码验证或在ocserv配置文件中禁用TLS 1.3。

包起来

我希望本教程可以帮助您在OpenConnect VPN服务器中设置证书身份验证。 与往常一样,如果您发现这篇文章很有用,请订阅我们的免费新闻通讯以获取更多提示和技巧。 保重🙂

Sidebar