实际上这个世界上没有好人和坏人,只有做了好事的人,和做了坏事的人。
——柴静《看见》
阿里云函数计算(Function Compute)是一个事件驱动的全托管 Serverless 计算服务。使用函数计算只需编写代码并上传,而无需管理服务器等基础设施,函数计算会准备好计算资源,并以弹性、可靠的方式运行代码。
不久前在一个项目上使用了函数计算,需要在函数计算中调用第三方服务,第三方服务有可能会对函数计算的地址进行白名单验证,但函数是通过弹性扩容的方式动态为函数分配计算资源的,因此无法提前预知访问第三方接口服务的IP地址,而且目前函数计算也没有像阿里云WEB应用防火墙一样提供回源地址清单,第三方接口需要的白名单IP要使用一些特殊手段来取得。
在阿里云函数计算的文档中的“场景案例”中有一个章节就是针对这种情况的,使用的是Nginx正向代理来代理函数计算的访问请求,这种通过Nginx的代理后,第三方服务看到的将是Nginx服务器的公网IP地址,这样就可以解决白名单的问题。
其中Nginx的配置如下:
server{
resolver x.x.x.x; listen 8080; location / { proxy_pass http://$http_host$request_uri; }
}
其中resolver x.x.x.x;是DNS服务器的地址。
这样虽然能解决白名单的问题,但这个代理你能使用,别人也能用,这肯定不是你要看到的情况。解决的方案是对请求的目标主机名进行验证,只对目标第三方服务的请求进行代理,其余的请求一律拒绝。
Nginx服务器的配置如下:
server {
resolver x.x.x.x;
listen 8080;
location /{if ( $http_host = ‘y.y.y.y’ ) { proxy_pass http://$http_host$request_uri; break; } return 403;
}
}
用一个或者多个条件判断对请求的http主机名进行验证,假如请求的是第三方服务则代理发送,否则请求将被拒绝。
解决了Nginx的盗用的问题,还有一个问题要解决,就是Nginx服务的可用性问题,这个问题可以通过负载均衡SLB和来解决,架构如下:
第三方服务的防火墙需要加两条地址,分别是两台Nginx服务器的公网IP。
上图中xx.xx.125.101和xx.xx.119.208是两台ECS的外网地址,可以将这两个地址提供给第三方加白名单,xx.xx.227.184是函数计算的地址,这个地址无法保证固定,不能用做白名单。
这里需要至少加两个IP,那么假如只能加一条地址怎么办?
这就需要对架构进行一些调整了,架构如下:
需要给函数计算增加VPC内网访问接口,访问在内网的SLB负载均衡和Nginx代理,Nginx代理服务器不配置公网IP而是通过NAT网关访问第三方接口。
为函数计算增加VPC访问接口需要进行访问授权,配置的方式是在函数计算的控制台打开服务配置。
点击修改,后可以看到网络配置,选择函数计算要对接的VPC和虚拟交换机。
在权限配置部分选择新建角色,并指定系统模版授权,选择
AliyunECSNetworkInterfaceManagementAccess ,并点击授权。
使用函数计算访问代理服务后,从阿里云弹性网卡控制台可以看到新增的ENI弹性网卡。
该弹性网卡地址虽然也是动态分配的,但地址范围仅限于指定的虚拟交换机内。