我有一台运行 Ubuntu 的 AWS 服务器,它有一个用于 VPN 的 pptpd 服务器,以及许多具有不同凭据的客户端。它运行良好。但显然我不应该再使用它了,我应该使用 ipsec。我先在运行 Ubuntu 16.04 的本地计算机上尝试一下,然后再尝试在实时服务器上执行此操作。
我能找到的唯一相关教程是这个。其他教程似乎是针对我拥有“公路战士”设置时的站点到站点 VPN,或针对其他操作系统,或者一般只是针对每天这样做的系统管理员(没有人付钱让我这样做)。
https://raymii.org/s/tutorials/IPSEC_vpn_with_Ubuntu_16.04.html
该教程说使用证书进行身份验证,因为它们“更易于使用”。
我按照说明操作。服务器名为“winter”,地址为 192.168.3.144。客户端名为“charly”,地址为 192.168.3.138。我按如下方式生成服务器证书:
ipsec pki --pub --in private/vpnHostKey.der --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/strongswanCert.der --cakey private/strongswanKey.der --dn "C=CN, O=Winter, CN=winter.lan" --san winter --san 192.168.3.144 --san @192.168.3.144 --flag serverAuth --flag ikeIntermediate --outform der > certs/vpnHostCert.der
系统日志显示:
May 30 20:34:36 winter charon: 03[CFG] adding virtual IP address pool 2002:25f7:7489:3::/112
May 30 20:34:36 winter charon: 03[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
“sudo ipsec statusall”的连接部分如下所示:
Connections:
IPSec-IKEv2: %any...%any IKEv2, dpddelay=300s
IPSec-IKEv2: local: [C=CN, O=Winter, CN=winter.lan] uses public key authentication
IPSec-IKEv2: cert: "C=CN, O=Winter, CN=winter.lan"
IPSec-IKEv2: remote: uses public key authentication
IPSec-IKEv2: child: 0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear
我生成了这样的客户端证书:
cat Charly-public.der | sudo ipsec pki --issue --lifetime 730 --cacert /etc/ipsec.d/cacerts/strongswanCert.der --cakey /etc/ipsec.d/private/strongswanKey.der --dn "C=CN, O=Winter, [email protected]" --san "mat@winter" --san "[email protected]" --outform der > Charly-cert.der
...现在我尝试使用运行 macOS 10.13.4 的 Macbook 进行连接。我将 macintosh VPN 配置为:
- 服务器地址:winter
- 远程 ID:[电子邮件保护]
- 本地 ID:
...并为其提供我在身份验证设置下创建的证书。
当我尝试连接时,它立即失败,没有任何错误消息。在服务器日志中:
May 30 20:53:15 winter charon: 06[CFG] looking for peer configs matching 192.168.3.144[[email protected]]...192.168.3.138[192.168.3.138]
May 30 20:53:15 winter charon: 06[CFG] peer config match local: 0 (ID_RFC822_ADDR -> 6d:61:74:40:77:69:6e:74:65:72:2e:6c:61:6e)
May 30 20:53:15 winter charon: 06[CFG] peer config match remote: 1 (ID_IPV4_ADDR -> c0:a8:03:8a)
May 30 20:53:15 winter charon: 06[CFG] ike config match: 28 (192.168.3.144 192.168.3.138 IKEv2)
May 30 20:53:15 winter charon: 06[CFG] no matching peer config found
这是左侧和右侧的配置:
mat@winter:~$ sudo grep -E 'left|right' /etc/ipsec.conf
left=%any
leftid=winter.lan
leftsubnet=0.0.0.0/0
leftcert=vpnHostCert.der
leftsendcert=always
right=%any
rightsourceip=10.42.42.0/24,2002:25f7:7489:3::/112
rightdns=8.8.8.8,2001:4860:4860::8888
我真正的问题是,“正在查找与 192.168.3.144[mat@winter]...192.168.3.138[192.168.3.138] 匹配的对等配置 / 未找到匹配的对等配置”是什么意思?我不明白匹配是如何进行的 - 哪些值是可以接受的,客户端发送了哪些值,以及我如何在客户端和服务器端控制这些值。而且我不明白如何解析该行,每个部分代表什么。
谢谢!
下面已经正确回答了这个问题,但是这是我用我理解的术语来解释我做错的事情。tl;dr:leftid 需要作为 SAN 存在于证书中,而不仅仅是作为 DN 中的 CN。
这个想法是连接两个证书,一个服务器证书和一个客户端证书,这样双方就可以相互信任。这两个证书都由证书颁发机构(“CA”)签名,双方都拥有 CA 公钥。如果双方认识到彼此的证书是由同一个 CA 签名的,他们就会很高兴。问题在于说服 StrongSwan 认识到传入的客户端连接想要连接到特定的服务器证书。对我来说,这似乎是一件轻而易举的事,因为我只配置了一个证书。但 StrongSwan 是为更复杂的设置而设计的。
关键组件是 ipsec.conf 中配置的“leftid”。您可以在 StrongSwan 中配置任意数量的不同 VPN,每个 VPN 都由不同的 leftid 区分。当客户端连接时,它会请求具有此名称的 VPN,在我的情况下,它是在 VPN 设置中的“远程 ID”下配置的。然后,它期望服务器向其发送证书,并且该证书应将自己标识为相同的 VPN 名称/leftid/远程 ID。
因此 StrongSwan 需要为其 leftid 提供证书。您可以使用 ipsec 生成服务器证书。您提供一个“专有名称”(“DN”),它是一串长字符串,如“C=CN、O=Winter、CN=winter.lan”。您还可以提供任意数量的主题备用名称 (“SAN”)。当服务器启动时,它会读取“leftid”和“leftcert”配置。它会尝试在 DN 或 SAN 中找到 leftid。
诀窍如下:如果找不到 leftid,它会丢弃 leftid,而使用整个 DN。如下所示:
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
这意味着 VPN 现在不再命名为“winter.lan”,而是命名为“C=CN, O=Winter, CN=winter.lan”。如果客户端想要连接,它必须请求该名称,而不是“winter.lan”。这样做有点道理,因为如果名称不匹配,运行就没有意义了。客户端可以连接到 winter.lan,但如果服务器发送该证书,它将与客户端请求的证书不匹配,客户端将中止连接。另一方面,这样做真的很令人沮丧,因为没有办法说服 Macintosh 请求该 leftid。
我所遵循的教程中最大的问题是它使用的 leftid 是“vpn.example.org”,并且在建议的生成服务器证书的 ipsec 命令中,它仅在 DN 中使用,而不是作为 SAN 添加。如果我对“winter.lan”执行此操作,则会失败。id 与证书不匹配。
May 31 21:32:00 winter charon: 05[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 31 21:32:00 winter charon: 05[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
只有当我使用 --san 将 leftid 作为 SAN 提供时,它才有效。教程甚至说“您需要确保 leftid= 与证书中的 CN 相同”。我不知道他们是否使用了与我不同的 strongswan 版本,或者那里有什么问题。
另一个混乱的原因是,不清楚字符串“C=CN, O=Winter, CN=winter.lan”何时何地与字符串“winter.lan”匹配。这可能是因为这些标识符还附加了必须匹配的“类型”,而这些类型通常在日志中是不可见的。
无论如何,需要注意的关键是服务器启动时出现的“证书未确认”行。在修复此问题之前,不要尝试连接客户端。
答案1
您添加到证书的 subjectAltName 扩展之一为[email protected]
,但您配置了leftid=mat@winter
。由于不匹配,本地身份将回退到证书的主题 DN(即C=HK, O=Winter, CN=mat@winter
)。这反过来又与客户端提出的远程身份不匹配(looking for peer configs matching 192.168.3.144[mat@winter]
)。
因此,要么[email protected]
在客户端配置中相应地配置和更改远程身份,要么在客户端上将完整的主题 DN 配置为远程身份(但某些 IKEv2 客户端实际上并不支持这一点,尤其是 Apple 的客户端)。
使用更新后的配置,winter.lan
必须将其作为 subjectAltName 包含。它不会与CN
主题 DN 的相对 DN 进行匹配。因此,您必须--san winter.lan
在颁发服务器证书时明确添加。
当配置的本地身份与本地证书中的任何身份(主题 DN 或任何 subjectAltName - 请注意类型也必须匹配)都不匹配时,主题 DN 将用作身份。加载配置时,日志中会出现相应的消息(类似id 'mat@winter' not confirmed by certificate, defaulting to 'C=HK, O=Winter, CN=mat@winter'
),这也可以在列出配置的 IP 和身份的部分的输出中看到ipsec statusall
。Connections
因此,请确保您配置的身份是 IKE 守护程序在身份验证期间实际使用的身份。
日志消息的组成部分looking for peer config...
实际上非常简单。例如192.168.3.144[mat@winter]...192.168.3.138[192.168.3.138]
:
- 192.168.3.144:IKE_SA 的本地 IP 地址(= 响应者/服务器的 IP)
- [mat@winter]: 发起者/客户端 (IDr) 提出的响应者/服务器身份必须与配置的身份相匹配(左派)
- 192.168.3.138:IKE_SA 的远程 IP 地址(= 发起者/客户端的 IP)
- [192.168.3.138]: 发起者/客户端 (IDi) 提出的发起者/客户端身份必须与服务器上配置的远程身份相匹配 (右标识,默认为%任何(如果未配置)
请注意,比较的身份类型(例如 FQDN 与 USER_FQDN 或 KEY_ID)也必须匹配(身份在日志中可能看起来相同,ipsec statusall
但其类型可能不同)。只有当日志级别为了配置文件增加至 3。
身份有两大作用。首先,身份允许选择特定配置。因此,通过在 IDr 有效负载中发送特定身份,客户端表示它希望使用该特定身份连接到服务器,服务器将选择与该身份匹配的配置。有效负载是可选的,有些客户端不会发送它(例如 Windows 客户端),这允许服务器选择它认为合适的任何配置。客户端身份也是如此,如果配置不匹配,则允许服务器切换到特定配置(但是,使用rightid=%任意默认情况下,选择配置时将忽略客户端身份 - 但必须确认通过客户端证书)。
其次,身份很重要,可以防止任何拥有有效证书的人以他们喜欢的任何身份进行身份验证。例如,如果您的客户端除了 CA“X”之外还安装了其他 CA,并且您不强制执行特定身份(它们通常与服务器的主机名匹配),则客户端将接受由这些 CA 颁发的任何证书,而不仅仅是专门为该身份/主机名颁发的证书(如果 CA“X”是唯一受信任的 CA,如果它不强制执行特定的服务器身份,它甚至会接受另一个客户端证书作为服务器证书)。客户端也是如此。您不希望您的客户端“Y”使用专门颁发给客户端“Y”的证书将自己验证为客户端“Z”。如果有多个具有不同身份的连接定义,这一点尤其重要右标识设置和例如不同的子网或虚拟 IP 范围,以允许根据客户端身份通过 VPN 访问不同的网络。
我所遵循的教程中存在的大问题是它使用的 leftid 是“vpn.example.org”,并且在建议的 ipsec 命令中生成服务器证书,该证书仅在 DN 中使用,而不是作为 SAN 添加。
是的,出于某种原因,他们在证书中添加了两个具有不同 TLD (.com
和)的不相关 SAN。.net
教程甚至说“您需要确保 leftid= 与证书中的 CN 相同”。我不知道他们是否使用了与我不同的 strongswan 版本,或者那里存在什么问题。
它不取决于 strongSwan 版本,而是取决于客户端。如果它不发送远程身份,服务器可以自由选择使用完整主题 DN 作为身份的配置。然后由客户端决定是否接受服务器返回的身份。因此,与它们想要强制执行的远程身份(例如服务器的 FQDN)匹配的客户端与服务器发送的 DN 的 CN 匹配就可以了。Windows 客户端会这样做,Apple 客户端可能也会这样做(尽管某些版本的 macOS 也需要匹配的 SAN)。但是作为客户端,strongSwan 不会并且将要求配置的远程身份与服务器返回的身份(及其类型)完全匹配。有一个特殊的客户端配置(rightid=%vpn.example.com),其中 strongSwan 不发送远程身份,并且还会将配置的身份与服务器证书中的所有身份进行匹配。这允许客户端强制使用 FQDN 作为身份,而服务器使用完整的主题 DN 来标识自己,只要该 FQDN 也包含在服务器证书中的 subjectAltName 中。
另一个混乱的原因是,不清楚字符串“C=CN, O=Winter, CN=winter.lan”何时何地与字符串“winter.lan”匹配。这可能是因为这些标识符还附加了必须匹配的“类型”,而这些类型通常在日志中是不可见的。
这主要是因为 strongSwan 不会将身份与 DN 的部分进行匹配。但如上所述,有些客户端会这样做(至少它们会将 FQDN 与 CN 进行匹配)。
无论如何,需要注意的关键是服务器启动时出现的“证书未确认”行。在修复此问题之前,不要尝试连接客户端。
检查该日志消息或检查输出是否与ipsec statusall
预期配置匹配绝对是个好主意。
如果客户机无法连接no matching peer config found
,请确保将日志消息中列出的 IP 和身份looking for peer configs...
与中配置的连接 IP 和身份进行比较ipsec statusall
。