本文将向你展示如何在Ubuntu操作系统上的OpenConnect VPN服务器(ocserv)中设置证书身份验证。许多OpenConnect客户端软件都可以导入用户证书,这将使用户无需输入用户名和密码,证书身份验证也比密码身份验证更安全。我们假设你已经使用Let的加密TLS服务器证书设置了OpenConnect VPN服务器,我们将建立自己的CA(证书颁发机构)来签署客户证书。
设置你自己的CA(证书颁发机构) 我们想要使用证书身份验证,但Let's Encrypt不会发出客户端证书,因此我们需要创建自己的CA,你可以openssl来完成这项工作,但是ocserv建议使用GnuTLS,所以我将向你展示如何使用GnuTLS,安装gnutls-bin包: sudo apt install gnutls-bin 在/etc/ocserv/中创建子目录以保存私钥和证书: sudo mkdir /etc/ocserv/ssl/ 更改你的工作目录: cd /etc/ocserv/ssl/ 使用certtool命令为CA生成私钥,该命令由gnutls-bin包提供,默认情况下,它会生成一个3072位的RSA密钥,这就足够了: sudo certtool --generate-privkey --outfile ca-privkey.pem 在生成CA证书之前,让我们创建CA证书模板文件,模板文件格式可以在certtool手册(man certtool)中找到: sudo nano ca-cert.cfg 将以下行添加到该文件中,Example Org、Example CA,用适当的值替换占位符: # X.509 Certificate options # The organization of the subject. organization = "Example Org" # 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文件中的用户名,请注意替换My Org、John Doe、username: # X.509 Certificate options # The organization of the subject. organization = "My Org" # 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
请注意,iOS上的Ciso AnyConnect应用程序不支持AES-256密码,因此如果用户使用的是iOS设备,则可以使用3des-pkcs12cipher: sudo certtool --to-p12 --load-privkey client-privkey.pem --load-certificate client-cert.pem --pkcs-cipher 3des-pkcs12 --outfile client.p12 --outder 现在我们将客户端私钥和证书合并到一个文件client.p12中。
证书签名请求 为了使最终用户的私钥保密,用户可以使用自己的私钥生成证书签名请求(CSR),然后将证书请求发送给管理员,然后管理员向用户颁发客户端证书,首先,他们必须使用上面提到的命令生成私钥和客户端证书模板,然后使用以下命令生成CSR,request.pem文件由用户的私钥签名: certtool --generate-request --load-privkey client-privkey.pem --template client-cert.cfg --outfile request.pem 接下来,用户将request.pem和client-cert.cfg文件发送给admin,admin运行以下命令以生成客户端证书: 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 = "certificate" 如果还取消注释以下行,则表示用户还必须输入用户名和密码,因此,如果证书身份验证足以证明身份,则注释掉以下行: auth = "plain[passwd=/etc/ocserv/ocpasswd]" 如果允许用户选择证书身份验证或密码身份验证,请添加以下行: enable-auth = "plain[passwd=/etc/ocserv/ocpasswd]" 现在找到以下行: ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.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
在Ubuntu桌面上使用证书身份验证 使用scp命令将client.p12文件下载到Ubuntu桌面(请替换user@vpn.example.com): scp user@vpn.example.com:/etc/ocserv/ssl/client.p12 ~ 然后安装openconnect客户端软件: sudo apt install openconnect 要使用证书身份验证,请运行(请替换vpn.example.com): sudo openconnect -b vpn.example.com -c client.p12 系统将要求你使用密码解锁客户端私钥:
如果输入的密码正确,现在应该连接到VPN服务器了,可看一下蒲公英VPN客户端 for Linux(路由器软件),附安装教程。
在Windows和MacOS桌面上使用证书身份验证 从OpenConnect GUI下载页面下载适用于Window或MacOS的OpenConnect GUI客户端,然后创建一个新的VPN连接配置文件并将PKCS #12文件导入用户证书字段,单击“保存”按钮,需要输入PIN才能解锁私钥,导入后,你不必再输入用户名和密码:
在iOS设备上使用证书身份验证 iOS用户可以使用Cisco AnyConnect应用,要在AnyConnect应用程序中导入客户端证书,你可以先将PKCS #12文件发送到附件中的电子邮件地址,然后在iOS上打开邮件应用程序,点击附件几秒钟,然后与AnyConnect共享,然后输入PIN以导入文件:
导入后,在AnyConnect中编辑VPN连接,转到高级->证书,然后选择客户端证书,保存你的设置:
现在你不必再在iOS设备上输入用户名和密码了,Cisco AnyConnect应用程序不记用户名和密码,因此在密码验证模式下,当手机不使用时,VPN连接将丢失,在证书身份验证模式下,如果连接断开,应用程序将自动重新连接到VPN服务器。
相关主题 |