使用Amazon WAF对Amazon API Gateway的接口做IP地址白名单保护

一、背景

Amazon API Gateway(以下简称)是AWS的托管的API网关服务。许多企业需要将自身应用的数据接口暴露给第三方合作伙伴,但使用专线成本较高,或者因面向多个互联网服务交互,因此将接口暴露在互联网上。为提升接口安全性,可采用为API Gateway设置来源IP地址限制的办法,提升安全。API Gateway支持设置Resource Policy,通过资源策略中填写IP Condition来限制可以访问的IP访问,包括白名单允许,或者显式拒绝。

使用API Gateway自带的策略控制IP地址有一些局限,因为资源策略是随着API Gateway的部署Stages下发生效的,因此有时候仅需要IP地址的策略变更,但是为了让其生效,需要对整个接口开发的版本和Stages阶段创建新的版本,并进行流量切换。如此过程对整个应用开发和运行体系的影响较大。那么有什么办法实施Out-of-band方式(带外)的IP策略管控呢?这里就可以用到Amazon WAF。

Amazon WAF(以下简称WAF)是AWS的托管Web Application Firewall应用防火墙。WAF支持设置OSI网络模型七层的规则,包括对HTTP/HTTPS请求的URI/Header等信息进行检查。通过WAF实施IP地址检查规则,并将WAF绑定到API Gateway上,简单方便,不影响当前API Gateway的开发、部署。WAF优先于所有API Gateway策略,在网络层生效。因此WAF配置的规则,优先于API Gateway的Resource Policy中配置的IP Condition规则。

本例配置中,会将来自本地的IP加入白名单,并拒绝除本地之外的所有IP请求。

二、使用WAF保护API Gateway

1、验证API Gateway访问从互联网访问正常

首先进入API Gateway界面,从向导创建一个默认的petstore的演示用API接口。这个接口默认不带身份验证,默认类型为regional也就是当前AWS区域级别可以访问,有外网入口。创建完毕后,执行部署,生成一个新的Stage

进入Stages界面,可以看到接口信息如下截图。

在这个界面中,可以看到新创建的API接口,以及支持调用的方法。如图中支持GET和POST。接下来将接口复制下来,用curl命令校验下接口能否正常访问。如下截图。

可看到API Gateway接口访问正常。

2、在WAF中创建IP sets地址集

在`Stages界面,点击右侧的WAF菜单位置的Create Web ACL链接。如下截图。

进入WAF界面后,请注意WAF的控制台是全局的,右上角显示Region的界面会显示为Global。在AWS中国区,这个Global的意思是北京region和宁夏region统一管理。在海外区,这个Global的意思是全球所有region。这里不用担心,后续创建ACL时候会再次选择正确的region。

此时先不要着急点击创建按钮,而是先要创建IP地址集(IP sets)。点击页面左侧菜单的IP sets。如下截图。

在IP地址集页面上,选择正确的区域。WAF管理控制台虽然是全局的,但是设置规则是regional级别的,因此把IP地址集要设定到正确的区域。本例中为宁夏区域。如下截图。

输入IP地址集的信息,包括名称、描述,确认region的正确。如果有多个地址段,在文本框内每行输一个。然后点击Create IP set按钮。如下截图。

显示绿色信息创建完成。如下截图。

3、创建Web ACL设置规则

在左侧菜单,点击Web ACLs按钮,在页面右侧切换到正确的region,本例为宁夏区域。然后点击页面右侧的Create web ACL按钮继续。如下截图。

在配置WAF规则向导第一步,输入名称,在Region位置选择正确的区域(本例为宁夏),然后点击下方的Add Amazon Web Services resources,将WAF和API Gateway绑定。如下截图。

在绑定云资源的对话框里边,选择Amazon API Gateway,然后从资源清单中,选择本例创建的API Gateway的Stages的名称。如果有多个API Gateway,或者一个API Gateway的接口有多个Stages部署,那么这里也要选择多个不同的Stages的名称,以实现保护。如果只选一个,那么意味着其他的Stages部署不会被保护。选择好了之后,点击Add按钮。如下截图。

绑定好了后,在资源清单中,能看到刚才选择的Stages的名字了。现在点击Next下一步。如下截图。

在向导第二步,Add rules and rule groups界面,点击Add rules,有两个选项,第一个选项是AWS托管规则,第二个是自定义规则。这里选择第二项Add my own rules and rule groups。如下截图。

在自定义规则的界面上,将上方的Rule type选择为IP set类型,即IP规则。在Rule名称位置,输入一个平淡但是友好的名称作为规则名称。在IP set位置,从下拉框中,选择本文前一个步骤自定义IP地址集时候设定的名称。在下方针对入站访问的来源,WAF支持可能是经过NAT等通道的场景,一般选择第一个选项针对网络层体现的最终IP。如果有特定的HTTP Header标记真实客户端IP,那么也可以选择第二个选项IP address in header,并手工制定特定的Header名称。一般不需要调整这个选项,选择第一个Source IP address即可。如下截图。

将页面向下滚动,将本条规则行为选为Allow即允许通过。因为本例的配置是对特定IP白名单,拒绝其他所有IP,所以这里选择对本条IPAllow放行。然后点击右下角的Add rule。如下截图。

在添加完毕自定义规则后,页面返回了向导第二步,在页面上方已经看到刚才的规则被添加进来,且Action行为的位置显示为Allow。接下来,要将所有非这个来源IP的流量设置为拒绝。在下方Default web ACL action for requests that don't match any rules位置,表示默认规则的处理,这里将Default action选择为Block拒绝访问。然后点击页面右下角的Next下一步按钮。

在向导第三步,设置多条规则的优先级。如果有多个防护规则,一般建议将网络层IP拒绝的规则放在最上方第一条,以便有限屏蔽无关流量,减少总体扫描量。如果只有一条的话,可直接点击Next下一步。如下截图。

在向导第四步,上方的下方的Amazon CloudWatch metrics选项保持默认打开即可。在下方的Request sampling options采样设置,选择Enable sampled requests,这样在WAF规则Rule下方即可看到部分访问的采样,同时包括允许和拒绝的信息。最后点击Next按钮下一步继续。如下截图。

向导最后一步Review,无需调整任何设置,直接将页面卷动到最下方,点击Create web ACL按钮。如下截图。

显示绿色的则表示创建WAF ACL完成。如下截图。

4、验证WAF工作

首先从本地网络(也就是被授权Allow放行)的位置发起访问,可看到访问正常。

接下来更换到其他的网络环境,对刚才被保护的URL发起访问。可看到返回报错信息。

[root@ip-172-31-16-68 ~]# curl https://038iiposid.execute-api.cn-northwest-1.amazonaws.com.cn/prod-v1/pets

{"message":"Forbidden"}

[root@ip-172-31-16-68 ~]#

现在回到WAF服务界面,来到Web ACLs菜单,点击刚才新创建的ACL,点击Overview标签页。然后向下卷动页面。如下截图。

在页面下方的Sampled requests位置可以看到最近的访问记录取样,可查看其中列出的允许的规则和拒绝的规则都与预期一致。

至此配置完成。