第三章:PKIs和证书

首先,OpenVPN使用X.509证书进行客户端身份验证和VPN流量加密,尽管可以禁用此支持。

X.509证书的私钥基础设施(Private Key Infrastructure——PKI)的设置和维护是一个困难的概念,而且可能是一项繁琐的任务。

OpenSSL二进制文件具有手动管理PKI所需的所有工具,但命令选项很复杂,如果不自动化会很容易出错。建议组织或个人使用脚本或其他包来管理其PKI。这不仅有助于限制错误,而且可以更好地遵守规则和其他一般标准。

有两个开源项目是专门为与OpenVPN实现良好配合而编写的。Easy-RSA是一个长期项目,一直与OpenVPN项目密切相关。最初是与OpenVPN一起编写的,其最初目的是构建一个证书颁发机构(Certificate Authority——CA)及其必要的组件。今天,这个项目仍然与OpenVPN项目一起维护,尽管它们在技术上是分开的。

另一个项目,ssl-admin,是一个Perl脚本,用于填补Easy-RSA代码中的空白。这两个项目对PKI管理任务的处理方式不同,都有独特的解决方案。ssl-admin项目是一个提供菜单和用户反馈的交互式脚本,而Easy-RSA主要是一个批处理使用程序。

如今,Easy-RSA和ssl-admin项目都由Eric Crist维护。Josh Cepek加入了,并编写了大部分最初的v3.0 Easy-RSA代码。目标是最终合并这两个项目,并保留两者的所有功能。

PKI概述

PKI通常是机密证书和密钥对(key pairs)的分层组织。通常,与大多数网站一样,层次结构的顶部是CA。这是整个树的根,信任植根于此级别。如果根(root)是可信的,那么所有底层密钥对也将是可信的。从根级别CA,可以有客户端证书、服务器证书、子CA(sub_CAs)和证书吊销列表(Certificate Revocation Lists——CRLs)。在每个子CA下,重复此可能性列表。

【此处有图,略】

为了充分发挥PKI的潜力,用户和系统需要信任根CA以及链中的任何中间CA。对于大多数现代网络浏览器,浏览器作者或供应商默认情况下已经审查并批准了大量可信任的根级证书颁发机构(root-level certificate authorities)。这些机构通常是商业供应商,如VeriSign、Go Daddy、Comodo、Trend Micro、各种政府实体等。

由于这个预先批准的浏览器列表,绝大多数互联网用户完全不知道PKI是如何工作的。因此,OpenVPN的新用户以及任何需要PKI的软件都会在概念和技术上遇到配置和管理障碍。对于公共网站,需要由可信机构对第三方网站进行验证。然而,在OpenVPN的背景下,组织内通常有一个隐含信任的实体,即IT部门。OpenVPN通常在单个组织内使用,对这种信任是固有的。Easy-RSA和ssl-admin都是为了帮助新手和高级用户更好地管理他们的PKI而编写的。

对于单个点对点链路,使用PKI的复杂性来保护隧道通常没有意义;预共享密钥就足够了。然而,当涉及许多用户时,丢失和被盗密钥以及员工流失的可能性要大得多。使用正确配置的PKI,撤销丢失的证书或离职员工的证书相对简单。一个新证书的也很容易生成和重新部署。

使用Easy-RSA和ssl-admin,我们将创建一个简单的PKI,其中包含CA、服务器证书、一些客户端证书和证书吊销列表。此外,我们将使用这些使用程序生成DH(Diffie-Hellman)参数,这些参数将在后面的章节中使用和讨论。

OpenVPN PKI流程如下:

 

使用 Easy-RSA 的 PKI

在撰写本章时,Easy-RSA 2.2.2是最新版本,与V3.0.0-rc2一起发布。【我在看这本书的时候(2024/11/26),FreeBSD中安装的Easy-RSA版本是3.2.1】

由于v3.0系列即将发布,本节重点介绍该版本。

本练习将演示如何从头开始构建CA。此处不介绍从Easy-RSA2.2升级。下载Easy-RSA软件包后,解压缩文件:

提取后,将文件vars.example 复制到 vars 。建议设置Easy-RSA工作目录。vars的第45行默认将EASYRSA定义为$PWD(当前工作目录)。这可能会有问题,特别是如果你使用Easy-RSA来管理多个证书颁发机构。取消此行注释,并将其更改为适合你环境的内容,例如 /usr/local/etc/easy-rsa

【此处与FreeBSD上的最新版不同】

小贴士:初始化Easy-RSA后,EASYRSA目录中的所有内容都将被删除。小心你在这里自定义的东西。EASYRSA目录是证书存储所在的位置,而不是可执行文件和变量所在的位置。

你可能需要设置组织字段,这些字段是以下变量:

【对于FreeBSD14.1,这些变量有预设值(被注释掉了):】

这些值用于所有生成的证书请求的默认值,包括根CA。确保这些行在文件中没有被注释掉。不需要对变量进行其他更改。

如果你定义的EASYRSA目录不存在,请立即创建它,并将openssl-1.0.cnf文件从分发包复制到新目录。对于我们的示例,我们将EASYRSA证书存储放在/usr/local/etc/easy-rsa中:

接下来,我们准备初始化Easy-RSA PKI:

注意,我们使用的是来自./vars的Easy-RSA配置。

在这种情况下,初始化过程会清除pki目录中的内容,并创建privatereqs子目录。

你可以有多个vars文件来管理多个CA,并将所有这些文件嵌套在同一个EASYRSA根目录中。为此,你必须更改每个CA的EASYRSA_PKI变量。

构建 CA

build-ca 子命令首先生成证书签名请求(Certificate Signing Request——CSR),随后对该请求进行自签名。

要构建根证书颁发机构证书/密钥对,运行build-ca 命令:

你将被要求输入将纳入你的证书申请的信息。你要输入的是所谓的可分辨名称(Distinguished Name——DN)。有很多字段,但你可以留一些空白;某些字段将定义默认值,如果输入. ,该字段将留空。

小贴士:共用名称字段中不应使用空格。这将导致Easy-RSA出现问题,也可能导致CCD、用户名等常见名称出现问题。确保路径后有一个尾随的正斜杠 / ,否则一些子命令(gen-crl 和其他子命令)将无法运行。

自签名时,CA约束设置为true,并自定义密钥使用参数,允许此新证书对其他证书进行签名,包括证书吊销列表(CRL)。可以使用openssl命令行使用程序验证此信息:

在openssl输出中,我们可以看到x509v3 Basic Constraints 以及 x509v3 Key Usage 参数。你的CA现在已经准备好开始对客户端和服务器证书进行签名。

证书吊销列表

gen-crl 子命令生成一个CRL。虽然目前我们只有一个CA证书,但建议生成一个空的CRL。这允许你使用文件暂存OpenVPN配置,并且以后不需要重新启动。如果配置中列出了不存在的CRL,OpenVPN将记录错误,但该文件可以动态替换,因为它在每个客户端连接上都会被重新读取。

我们可以使用openssl crl命令验证CRL:

服务器证书

OpenVPN可以使用x509密钥使用的参数,确保客户端使用有效的客户端证书连接,并且客户端可以确保服务器被授权为服务器。这可以防止你的一个客户端证书在Man-in-The-Midle(MITM——中间人)攻击中被用作服务器。如果没有此约束,则可以使用VPN CA签名的任何证书来模拟客户端或服务器。因为流氓证书(rogue certifixage,行为失常的、离群的、暴戾的)驻留在同一个PKI中,所以证书本身仍然有效,并将通过通用PKI检查。

Easy-RSA支持使用 build-server-full 子命令使用服务器密钥使用的参数对证书进行签名。

我们可以使用 openssl 命令验证服务器证书:

注意,x509v3密钥使用部分,以及它们对 TLS Web Server Authentication 的标识。这就是当前版本的OpenVPN在指定远程证书类型时所寻找的。

客户端证书

就像服务器证书一样,可以使用特定于客户端的证书对客户端进行身份验证。通过这种方法,可以要求每个客户端都有一个唯一的证书。证书通用名(CN——Common Name)可用于确定通过 client-connect 脚本或 client=config-dir 选项在给定连接上推送的其他参数。从OpenVPN2.3.7开始,仍然支持 -client-cert-not-required 。有传言称从未来的版本中删除此支持。client-cert-not-required 允许客户端在没有唯一(或任何)预定义证书的情况下进行连接,就像网络浏览器连接到网络服务器一样。

easyrsa 命令用来建立客户端证书,方法与建立服务器端证书一样:

我们可以使用 openssl 命令检查密钥使用参数:

如服务器部分所述,我们检查 x509v3 Extend Key Usage。在客户端的情况下,我们寻找 TLS Web Client Authentication。 同样,这在验证远程客户端证书类型时使用。

PKI使用ssl-admin

ssl-admin项目是在Easy-RSA被认为被抛弃和崩溃的时候启动的。它是一个用Perl编写的菜单驱动的交互式实用程序。与Easy-RSA一样,ssl-admin是OpenSSL命令行实用程序的包装器。

要在FreeBSD上安装ssl-admin,可安装security/ssl-admin port。对于所有其他基于Unix的系统,包括OS X, svn export是最简单的方法。以下示例在Mac OS X上运行,但在其他操作系统上也会类似。

要在FreeBSD以外的操作系统上获取ssl-admin,请实用SVN命令行实用程序导出当前版本:

如果主服务器ftp.secure-computing.net脱机,则可以使用服务器ftp2.secure-computing.net作为替代。

导出后需要安装,更改目录到导出树中,运行 ./configure ,然后跟随 make install

bash是配置的唯一需求。这不是一个典型的配置规则集,它只是模仿了一个规则集的行为。

安装完成后,运行 ssl-admin 命令最初将显示一个错误:

某些版本的ssl-admin引用以下文件: ssl-admin.conf.default。

要开始实用该软件,你必须将默认文件复制到错误列出的位置。这将根据操作系统的标准文件系统层次结构而有所不同。在这里,我们将把ssl-admin.conf.sample复制到ssl-admin.conf,并修复新文件的权限。

ssl-admin要求所有操作系统都以root身份完成。这是一种已知的不良做法,将在即将发布的版本中得到修正。

操作的命令如下:

使用csh没有具体的原因,只是作者的偏好。

对于本例,我们编辑配置文件。通常,只需要更改底部变量:

变量KEY_COUNTRY 必须是两个字母。这是标准的限制/约束,而不是 ssl-admin 独有。这些值与Easy-RSA中的同名变量对齐。一旦生成CA,就不应更改这些值,因为openssl会为不匹配的值抛出错误。

如果你的组织没有有效的CRL分发URL,则应保留 $ENV{'KEY_CRL_LOC'} 。空置将导致openssl错误。

编辑完配置文件后,我们就可以启动程序了。在第一次执行时,ssl-admin将检查其证书存储。如果那里不存在有效的CA和结构,则用户可以导入现有的PKI或创建新的PKI。与Easy-RSA一样,我们正在生成一个新的CA。在某些操作系统上,需要将/etc/openssl.cnf文件手动复制到证书存储根目录。在MAC OS X上没有遇到此错误。在Linux系统上,只需将/etc/openssl.cnf复制到/etc/ssl-admin/openssl.cnf即可。这将在ssl-admin的后续版本中得到修复。

正如你所看到的,ssl-admin比Easy-RSA更冗长、更具有交互性。此外,ssl-admin会自动为你生成初始CRL。

在显示菜单之前,有一个关于OpenVPN配置的可选警告。如果你提供了client.ovpn配置,ssl-admin可以自动将配置文件与嵌入式证书或多文件ZIP文件打包在一起。配置文件的证书行应该是通用的:

这些值将自动替换为内联密钥,或根据OpenVPN证书、密钥和配置的分发方式重命名文件。现在我们通过创建根证书颁发机构密钥对(key pair)初始化了PKI,我们可以开始创建服务器和客户端证书了。

OpenVPN 服务器证书

首先,我们将创建在OpenVPN服务器上使用的证书。菜单选项 S 将生成一个CSR,一个密钥,并提示CA对证书进行签名:

为了节省空间,ssl-admin打印的菜单将被省略,取而代之的是MENU一词。

在前面的代码中,我们使用带有空格的证书CN来演示ssl-admin行为。在这里,它警告说,空格将被下划线字符替换,并在必要时为用户提供更改CN的机会。进一步地,我们选择用密码保护私钥。最后,询问用户是否可以存档CSR。

为了显示添加的服务器令牌,我们再次运行openssl命令以输出证书详细信息。为简介起见,以下输出省略了一些关键细节:

注意, x509v3 Extened Key Usage 包括 TLS Web Server Authentication。为了向后兼容,还包括了一个旧的标准,即 Netscape Cert Type 。这不仅与OpenVPN有关,而且ssl-admin是作为通用的 x509 CA管理实用程序编写的。

OpenVPN 客户端证书

客户端证书的生成方式与服务器证书非常相似。菜单上的选项4将创建证书签名请求(Certificate Signing Request——CSR),随后对CSR进行签名:

后面的练习将使用最多三个客户端证书,因此建议你对client2 和client3重复上述步骤。

使用 openssl 二进制文件检查证书,我们可以看到 client1 证书缺少我们之前创建的服务器证书中存在的服务器密钥使用扩展。

此证书的结构显然比服务器证书更简单,并且缺少服务器密钥使用参数。

在创建CA、服务器和三个客户端证书后,我们只剩下以下目录结构:

active目录包含所有尚未吊销的证书和密钥,包括CA证书和密钥。当证书被吊销时,它们会从acitve目录移动到revoked目录。为了使用OpenSSL使用程序吊销证书,证书必须存在。没有证书,需要手动对 index.txt 文件进行可能有问题的编辑。顾名思义,csr 目录包含所有CSRs。这些通常可以安全删除,并且仅用于故障排除或需要重新生成证书时保留。

建议管理员将证书存储的内容留给实用程序的管理层。这适用于ssl-admin和Easy-RSA。

prog 目录包含openssl的操作文件和最新的CRL。不建议干扰这些文件,因为如果出错,可能会导致PKI无法实用。

最后,packages 目录将包含你可以分发给最终用户的所有文件:不仅是OpenVPN客户端,还有web服务器管理员等。打包证书和密钥可确保最终用户收到所有必要的文件,并且这些文件的格式正确。

其他功能

ssl-admin实用程序还有一些其他功能,管理PKI的人可能会对此感兴趣。索引是可搜索的(选项8),它显示了给定证书的状态。也可以显示当前CRL(选项7)。ssl-admin能够将OpenVPN配置文件与用户证书打包成内联格式(选项i),以及单独的文件——所有文件都包含在zip文件中(选项z)。当我们生成服务器和客户端配置时,本书将进一步讨论最后两个选项。

多个 CAs 和 CRLs

Easy-RSA3.0相当容易地支持多个根CA。通过在EASYRSA 根目录下创建一个单独的CA目录,并为每个目录创建不同的vars文件,可以使用Easy-RSA管理每个单独的CA。

目前,ssl-admin不支持多个根CAs,但支持创建中间CA(intermediate CA)。

使用OpenVPN,单个服务器实例可以支持多个根CA,接受由任一CA签名的客户端连接。为了启用这种支持,每个授权CA的CA证书需要连接在一起,形成一个可以用 --ca OpenVPN选项调用的文件。证书吊销列表也可以做到这一点。

通常,不建议对单个OpenVPN实例使用多个CA证书;例外情况可能是服务器或证书颁发机构迁移、公司或组织收购等。

在任何情况下,为OpenVPN证书链使用web浏览器根证书颁发机构都不是理想的。无法确定谁拥有证书,属于CA层次结构的任何人都可能连接到你的VPN实例。

未来,计划将ssl-admin和Easy-RSA项目合并到一个功能齐全的PKI管理套件中。我们希望Easy-RSA4.0能够使用这两个实用程序的最佳功能来实现这些迁移。

额外的安全性 – 硬件令牌、智能卡和PKCS#11

在本节中,我们将提供一些关于加密硬件设备的背景信息。你将学到如何在硬件令牌上生成私钥,以及如何将相关的X.509证书复制到令牌。之后,我们将讨论OpenVPN如何找到并使用此证书/私钥对来建立VPN连接。

背景资料

从2.1版本开始,OpenVPN通过提供PKCS#11支持来支持双因素身份验证(two-factor authentication)。双因素身份验证基于这样的理念,即未来使用系统(如VPN),你需要提供两件事:

PKCS#11是与智能卡或硬件令牌通信的行业标准,有开源和商业驱动程序可供选择。PKCS#11标准最初由RSA实验室发布,有时也被称为 cryptoki 标准,代表 CRYPtographic TOKen Interface (密码令牌接口)。

除了硬件令牌和智能卡这两个术语外,硬件安全模块(Hardware Security Module——HSM)也经常用于双因素身份验证。在本节中,我们将主要使用术语硬件令牌。硬件令牌和智能卡之间的主要区别在于形状因素:硬件令牌通常以USB设备的形式出现,而智能卡看起来像ATM卡或信用卡。为了使用智能卡,需要一个特殊的读卡器,有时会集成到笔记本电脑甚至一些台式电脑中。一些国家发行国家电子身份证,通常被归类为智能卡。

HSM通常是一种可以安全存储和管理加密密钥的设备,通常还提供硬件加速以加快加密和解密。

硬件令牌、智能卡或HSM通常是一种带有嵌入芯片的小型设备。这种嵌入式芯片运行一个微型操作系统(通常称为Card OS),负责安全地生成、存储和管理SSL私钥。大多数硬件令牌还能够存储其他信息,如SSL证书,以便有效的证书/私钥对可以安全地存储在单个设备上。

支持的平台

使用双因素身份验证的主要困难是不同平台上的软件支持。虽然大多数硬件令牌和智能卡供应商为MS提供操作系统驱动程序,但Linux甚至Mac OS X上支持的卡和令牌要少得多。请注意,这与OpenVPN本书无关:如果你使用的操作系统支持特定的硬件令牌,并且提供了PKCS#11驱动程序,那么一般来说,OpenVPN可以使用该硬件令牌或智能卡。

本书使用了Aladdin eToken Pro 72K USB硬件令牌。此硬件令牌仅支持使用闭源SafeNet身份验证客户端,该客户端可用于MS Windows、Mac OS X和Linux。

这些令牌的旧版本的优点是,它们可以使用SafeNet的付费闭源驱动程序或OpenSC项目的免费开源驱动程序。不幸的是,这些旧的令牌已无法购买到,SafeNet的当前硬件令牌使用的是OpenSC不支持的不同卡操作系统。

一般过程和概念适用于你可能使用的大多数硬件令牌。这些旧设备仅用于测试和演示目的。许多供应商使用移动应用程序(通常在用户的智能手机上)作为硬件令牌。SafeNet也有这样的产品:MobilePASS。

此外,OpenSC项目的驱动程序和工具不如商业软件供应商的软件成熟。

其他智能卡和硬件代币的供应商是Aktiv Co和Feitian(支持开源)。

请注意,OpenVPN完全依赖于工作的PKCS#11驱动程序。在选择硬件令牌时,重要的是验证设备是否在所需的平台上受支持,而不是它是否可以与OpenVPN本身一起使用。此外,请注意,在OpenVPN服务器上不需要(甚至不建议!)使用硬件令牌。

初始化硬件令牌

假设已安装Aladdin的pkiclient 或 SafeNet的 AuthenticationClinet ,并且驱动程序能够识别硬件令牌。如果eToken已经初始化,请跳过此步骤。

首先,打开eToken客户端属性窗口,然后单击初始化eToken。这将打开一个对话框。

填写令牌密码和管理员密码,取消选中“Token Password must be changed on first logon(令牌密码必须在首次登录时更改)”复选标记,然后单击“Start”。

令牌上的所有内容现在都将被销毁,eToken将使用新的令牌和管理员密码进行初始化。

生成证书/私钥对

使用硬件令牌时,生成证书和私钥对的过程与使用ssl-admin或Easy RSA工具略有不同。使用ssl-admin或Easy工具,可以在一个步骤中生成私钥、证书请求和X.509证书。对于硬件令牌,我们首先需要在令牌上生成私钥。

使用这个私钥,我们需要创建CSR。然后,此CSR由CA签名,从而生成X.509证书。然后将此证书写回令牌。ssl-admin和Easy RSA工具实际上遵循相同的过程,但它们对用户隐藏了CSR文件。

在令牌上生成私钥

为了在eToken上生成私钥,我们需要pkcs11-tool命令,它是OpenSC包的一部分。OpenSC软件包可用于Microsoft Windows、Mac OS X和Linux。pkcs11-tool命令使用PKCS#11驱动程序提供硬件令牌的接口。Aladdin/SafeNet驱动程序软件附带的PKCS#11驱动程序是libeTPkcs11.so(Linux和Mac OS X)或eTPkcs11.dll(Windows)。以下命令是在64位Linux机器上发出的,它生成了一个2048位的RSA密钥,该密钥使用标签movpn和ID 20141001标识。当我们生成私钥时,必须登录令牌:

在硬件令牌上生成2048位密钥需要一些时间,在此期间,硬件令牌上的红灯熄灭。之后,红灯将再次亮起。 上面命令的输出告诉我们生成了一个RSA私钥,以及一个公共的2048位RSA公钥。这与SSL证书不同。为了生成SSL或X.509证书,我们首先需要生成一个证书请求。

生成证书请求

我们需要使用OpenSSL引擎engine_pkcs11,使用硬件令牌中的私钥生成证书请求。engine_pkcs11引擎最好与自定义openssl.cnf文件一起使用。我们首先创建这个文件:

此文件是为64位CentOS Linux系统生成的。在其他系统中,驱动程序的路径和名称将不同。请注意,openssl.cnf文件中的语句区分大小写!

我们现在使用以下openssl命令生成主题为/CN=movpn的证书请求:

成功后,该命令不会产生进一步的输出。现在应该有一个movpn.csr文件,该文件需要由本章前面设置的CA签名。假设签名的证书将命名为movpn.crt

将X.509证书写入令牌

OpenVPN期望X.509证书出现在硬件令牌上。因此,我们必须首先将上一步中的X.509证书写入eToken。

首先,将签名的证书转换为DER格式:

接下来,我们将DER文件写入令牌:

我们需要验证私钥和证书的ID是否匹配:

该令牌现在已准备好与OpenVPN一起使用。

获取硬件令牌ID

为了使用硬件令牌中的证书和私钥,您必须首先找出OpenVPN所期望的硬件令牌ID。这是使用--show-pkcs11-id选项完成的:

序列化ID由以下部分组成:

不使用证书或私钥的标签,但保持它们彼此同步是一种很好的做法。

在OpenVPN中使用硬件令牌

我们现在终于可以在OpenVPN中使用硬件令牌了。为了使用它,我们替换了OpenVPN配置文件中的行:

使用选项pkcs11-providerspkcs11-id

总结

在本章中,我们讨论了创建根证书颁发机构的工具和方法,以及底层服务器和客户端证书。此外,还涵盖了PKCS#11的概念,尽管底层技术在不断发展。现在,您应该有一个完整的PKI和扩展它的工具。

下一章将介绍路由VPN设置。还将讨论tun网络设备的使用和工作连接的第3层要求。