我已经使用AWS API网关建立了一个基本的API,我想将我的端点链接到我在EC2实例上运行的服务(使用"HTTP代理"集成类型)。我已经读到,为了将我的EC2服务器锁定为只接受来自API网关的流量,我基本上有两个选项之一:
- 将EC2实例粘贴到VPC之后,使用具有VPC权限的Lambda函数(而不是HTTP代理)作为API请求的"传递">
- 在API网关中创建一个客户端证书,使用该证书进行后端请求,并在EC2实例上验证该证书
我想使用#2的变体,而不是在EC2服务实例本身上验证证书,而是在另一个运行Haproxy的实例上进行验证。我已经用Haproxy建立了第二个EC2实例,并将其指向我的另一个实例作为后端。我已经锁定了我的服务实例,所以它只接受来自Haproxy实例的请求。这一切都奏效了。我一直在努力弄清楚如何在Haproxy机器上验证AWS网关客户端证书(我已经生成)。我在谷歌上搜索了很多,但令人惊讶的是,关于如何做这件事的信息却为零。几个问题:
- 我所读到的一切似乎都表明我需要在我的Haproxy机器上生成SSL服务器证书,并在配置中使用这些证书。我必须这样做吗?或者我可以在不生成任何额外证书的情况下验证AWS客户端证书吗
- 我所做的阅读表明,我需要生成一个CA,然后使用该CA来生成服务器和客户端证书。如果我确实需要生成服务器证书(在Haproxy机器上),如果我没有访问亚马逊用来创建网关客户端证书的CA的权限,我该如何生成它们?据我所知,我只能访问客户端证书本身
这里有什么帮助吗?
解决方案更新
- 首先,我必须将我的HAproxy版本升级到v1.5.14,这样我才能获得SSL功能
- 我最初试图用letsencrypt生成一个官方证书。虽然我能够让API网关使用此证书,但我无法在HAproxy计算机上生成API网关可以接受的letsencrypt证书。该问题在详细的CloudWatch日志中显示为API网关的"内部服务器错误"响应和"常规SSLEngine问题">
- 然后,我从Gandi购买了一个通配符证书,并在HAproxy机器上尝试了这个证书,但最初遇到了完全相同的问题。然而,我能够确定我的SSL证书的结构不是API网关想要的。我在谷歌上搜索了一下,在这里找到了甘迪链:https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem然后,我将SSL文件结构化如下:
-----开始私钥-----#我在本地生成的私钥。。。-----结束私钥----------开始证书-----#来自甘地的证书。。。-----最终证书-----#上面链接中文件的两个证书
我保存了这个新的PEM文件(作为haproxy.PEM),并在我的haproxy前端绑定语句中使用了它,如下所示:
bind :443 ssl crt haproxy.pem verify required ca-file api-gw-cert.pem
上面bind语句中的api-gw-cert.pem是一个文件,其中包含我在api网关控制台中生成的客户端证书。现在,HAproxy机器正确地阻止了来自网关以外任何地方的任何流量。
我所做的阅读表明,我需要生成一个CA,然后使用该CA来生成服务器和客户端证书。
这是一种方法,但在这种情况下不适用。
您的HAProxy需要配置一个由受信任的CA签署的有效SSL证书,而不是签署客户端证书的证书,也不是您创建的证书。它需要是由一个公共的、受信任的CA签名的证书,其根证书位于API网关的后端系统的信任存储中。。。哪个应该与您的web浏览器所信任的基本相同,但可能是一个子集。
正如您的web浏览器不会在不发出必须绕过的警告的情况下与拥有自签名证书的服务器进行SSL通信一样,API网关的后端不会与不受信任的证书进行协商(而且没有绕过)。
只需说一句,在尝试让HAProxy使用客户端证书之前,您需要让API网关通过TLS与您的HAProxy对话,因为否则您会引入太多未知因素。还要注意的是,您不能为此使用Amazon Certificate Manager证书,因为这些证书只适用于CloudFront和ELB,它们都不直接支持客户端证书。
一旦HAProxy使用API网关,您就需要对其进行配置以验证客户端。
在bind
语句中需要ssl
和verify required
,但如果没有针对进行验证的东西,就无法验证SSL客户端证书。
根据我的判断,我只能访问客户端证书本身。
这就是您所需要的。
bind ... ssl ... verify required ca-file /etc/haproxy/api-gw-cert.pem
。
SSL证书本质上是一个信任层次结构。树顶部的信任是明确的。通常,CA是显式信任的,它所签名的任何内容都是隐式信任的。CA为其签署的证书"担保"。。。对于证书,它使用CA属性集进行签名,CA属性集也可以对证书下的证书进行签名,从而扩展了隐式信任。
不过,在这种情况下,您只需将客户端证书作为CA文件放入,然后客户端证书"担保"。。。它本身提供相同证书的客户端是可信的,而其他任何客户端都是断开连接的。当然,只有证书还不足以让客户端与您的代理进行通信——客户端还需要匹配的私钥,而API网关拥有该私钥。
因此,请考虑这两个单独的要求。让API网关首先通过TLS与您的代理对话。。。之后,根据客户端证书进行身份验证实际上是更容易的部分。
我认为您混淆了服务器证书和客户端证书。在这种情况下,API网关是客户端,HAProxy是服务器。您希望HAProxy验证API网关发送的客户端证书。API网关将为您生成证书,您只需要配置HAProxy来验证证书是否存在于它处理的每个请求中。
我猜你可能正在看本教程,他们告诉你生成客户端证书,然后配置HAProxy来验证该证书。由于API网关正在为你生成证书,因此可以跳过该教程的"生成证书"部分。
您只需要单击API网关中的"生成"按钮,然后复制/粘贴它提供给您的证书的内容,并将其保存为HAProxy服务器上的.pem文件。现在我不是一个HAProxy的大用户,但我认为以教程中的例子为例,你的HAProxy配置看起来像:
bind 192.168.10.1:443 ssl crt ./server.pem verify required