首页 文章

Haproxy用于授权来自AWS API Gateway的流量

提问于
浏览
1

我已经使用AWS API Gateway设置了一个基本API,我想将我的 endpoints 链接到我在EC2实例上运行的服务(使用“HTTP代理”集成类型) . 我已经读过,为了锁定我的EC2服务器只接受来自API网关的流量,我基本上有两个选项之一:

  • 将EC2实例粘贴在VPC后面并使用具有VPC权限的Lambda函数(而不是HTTP代理)充当API请求的"pass through"

  • 在API网关中创建客户端证书,使用该证书发出后端请求,并验证EC2实例上的证书 .

我想使用#2的变体而不是验证EC2服务实例本身的证书,我想在另一个运行Haproxy的实例上进行验证 . 我已经使用Haproxy设置了第二个EC2实例,并将其指向我的另一个实例作为后端 . 我已经锁定了我的服务实例,因此它只接受来自Haproxy实例的请求 . 这一切都有效 . 我一直在努力弄清楚的是如何在Haproxy机器上验证AWS Gateway Client证书(我已生成) . 我已经完成了大量的谷歌搜索,并且令人惊讶地没有关于如何做到这一点的零信息 . 几个问题:

  • 我读过的所有内容似乎都暗示我需要在我的Haproxy机器上生成SSL服务器证书并在配置中使用它们 . 我是否必须这样做,或者我是否可以在不生成任何其他证书的情况下验证AWS客户端证书?

  • 我所做的阅读建议我需要生成一个CA,然后使用该CA生成服务器和客户端证书 . 如果我确实需要生成服务器证书(在Haproxy机器上),如果我无法访问亚马逊用于创建网关客户端证书的CA,我该如何生成它们?根据我的说法,我只能访问客户端证书本身 .

有什么帮助吗?


SOLUTION UPDATE

  • 首先,我必须将我的HAproxy版本升级到v1.5.14,这样我才能获得SSL功能

  • 我最初尝试使用letsencrypt生成官方证书 . 虽然我能够让API网关使用此证书,但我无法在API网关接受的HAproxy机器上生成letsencrypt证书 . 该问题表现为来自API网关的"Internal server error"响应以及详细的CloudWatch日志中的"General SSLEngine problem" .

  • 然后我从Gandi购买了一个通配符证书,并在HAproxy机器上尝试了这个,但最初遇到了完全相同的问题 . 但是,我能够确定我的SSL证书的结构不是API网关想要的 . 我用Google搜索并在此处找到了Gandi链:https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem然后我构建了我的SSL文件,如下所示:

-----BEGIN PRIVATE KEY-----
# private key I generated locally...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
# cert from gandi...
-----END CERTIFICATE-----
# two certs from file in the above link

我保存了这个新的PEM文件(如haproxy.pem)并在我的HAproxy前端绑定语句中使用它,如下所示:

bind :443 ssl crt haproxy.pem verify required ca-file api-gw-cert.pem

上述绑定语句中的api-gw-cert.pem是一个文件,其中包含我在API网关控制台中生成的客户端证书 . 现在,HAproxy机器可以正确阻止来自除网关之外的任何流量 .

2 回答

  • 0

    我所做的阅读建议我需要生成一个CA,然后使用该CA生成服务器和客户端证书 .

    这是一种方法,但在这种情况下不适用 .

    您的HAProxy需要配置由受信任的CA签署的有效SSL证书 - 而不是签署客户端证书的证书,而不是您创建的证书 . 它必须是由公共可信CA签名的证书,其根证书位于API网关的后端系统的信任存储中...这应该与您的Web浏览器信任的基本相同,但可能是子集 .

    正如您的Web浏览器不会向运行自签名证书的服务器发送SSL而不会发出必须绕过的警告,API网关的后端将不会与不受信任的证书进行协商(并且没有旁路) .

    可以这么说,在尝试使用客户端证书之前,您需要让API网关通过TLS与您的HAProxy通信,否则您将引入太多未知数 . 另请注意,您无法使用Amazon Certificate Manager证书,因为这些证书仅适用于CloudFront和ELB,它们都不会直接支持客户端证书 .

    HAProxy使用API网关后,您需要将其配置为对客户端进行身份验证 .

    您需要在 bind 语句中使用 sslverify required ,但如果没有要验证的情况,则无法验证SSL客户端证书 .

    据我所知,我只能访问客户端证书本身 .

    这就是你所需要的一切 .

    bind ... ssl ... verify required ca-file /etc/haproxy/api-gw-cert.pem .

    SSL证书本质上是一个信任层次结构 . 树顶部的信任是明确的 . 通常,CA是明确信任的,并且它已签名的任何内容都是隐式信任的 . CA“担保”它签署的证书......和对于证书,它使用CA属性集进行签名,CA属性集也可以在其下签署证书,从而扩展该隐式信任 .

    但是,在这种情况下,您只需将客户端证书作为CA文件,然后客户端证书“凭证”......本身 . 呈现相同证书的客户端是受信任的,其他任何人都将断开连接 . 当然,只有证书对于客户端与您的代理进行通信是不够的 - 客户端还需要API网关所具有的匹配私钥 .

    因此,请考虑这两个单独的要求 . 首先通过TLS获取API网关与您的代理进行通信...之后,对客户端证书进行身份验证实际上是更容易的部分 .

  • 0

    我认为您正在混合服务器证书和客户端证书 . 在这种情况下,API Gateway是客户端,HAProxy是服务器 . 您希望HAProxy验证API Gateway发送的客户端证书 . API Gateway将为您生成证书,您只需配置HAProxy即可验证其处理的每个请求中是否存在证书 .

    我猜你可能正在查看this tutorial,他们告诉你生成客户端证书,然后配置HAProxy来验证证书 . 由于API Gateway正在为您生成证书,因此可以跳过该教程的"generate the cert"部分 .

    您只需单击API网关中的“生成”按钮,然后复制/粘贴它提供给您的证书的内容,并将其保存为HAProxy服务器上的.pem文件 . 现在我不是一个大的HAProxy用户,但我认为从该教程中获取HAProxy配置的示例如下所示:

    bind 192.168.10.1:443 ssl crt ./server.pem verify required
    

相关问题