【背景】
为什么需要固定的IP/域名访问OSS bucket呢?
- 对于阿里公有云OSS:某些企业内网应用需要访问阿里云公网OSS,在没有拉专线的情况下,需要在阿里云公网VPC开通一个ECS,ECS部署nginx反向代理连接公有云OSS bucket,最后实现企业内网应用程序访问nginx反向代理IP(ECS公网IP)进而访问阿里云OSS bucket。
- 对于阿里私有云OSS:反过来,如果某些企业公网应用系统需要访问阿里私有云平台OSS,在没有拉专线的情况下,需要在私有云VPC开通一个ECS,ECS部署nginx反向代理连接私有云OSS bucket,最后实现企业公网应用系统访问nginx反向代理IP(私有云ECS绑定的公网IP)进而访问阿里私有云平台OSS bucket。
- 对于阿里公有云OSS:某些企业由于安全机制,需要在出口防火墙配置策略,以限制内部员工和业务系统只能访问指定的公网IP,但是OSS的Bucket访问IP会随机变换,导致需要经常修改防火墙策略。
- 对于阿里私有云OSS:金融云环境下,因金融云网络架构限制,金融云内网类型的Bucket只能在金融云内部访问,不支持在互联网上直接访问金融云内网类型Bucket。
【OSS官方文档的疏漏】
本文基于阿里云OSS手册:https://help.aliyun.com/zh/oss/use-cases/use-an-ecs-instance-that-runs-centos-to-configure-a-reverse-proxy-for-access-to-oss,继续深入讨论如何利用nginx反向代理,实现固定的IP/域名访问OSS bucket。官方文档能够解决大部分的反向代理固定IP访问oss bucket的场景,比如应用程序调用OSS sdk、ossutil工具等,通过将OSS endpoint设置为nginx反向代理的IP,就可以访问OSS bucket。
但是,对于oss-browser、备份一体机(veritas、爱数等)等系统,将OSS endpoint设置为nginx反向代理的IP,访问OSS bucket会出现鉴权问题:
【错误原因分析】
oss-browser、备份一体机(veritas、爱数等)等系统,在将ak、sk、endpoint等参数转换为signature签名的时候,endpoint必须使用域名,使用IP的endpoint参数被转换得到的signatrue无法被oss后台认可。
因此,技术人员必须用OSS endpoint“原始域名”作为访问bucket的 endpoint。但是,OSS endpoint原始域名解析出来的IP是oss bucket的实际IP,应用系统需要直接访问的是nginx反向代理IP,怎么解决该问题呢?我们采用以下方案:
【本地hosts域名解析配置】
应用系统本地服务器配置hosts:
# 应用程序本地机器配置hosts文件: ECS_IP OSS_endpoint_原始域名 ECS_IP bucketname_OSS_endpoint_原始域名 ## 比如: 112.110.4.11 oss-cn-beijing-internal.aliyuncs.com 112.110.4.11 rj51.oss-cn-beijing-internal.aliyuncs.com 112.110.4.11 rj61.oss-cn-beijing-internal.aliyuncs.com ## 其中:rj51、rj61就是被访问的bucket 名称
【nginx反向代理配置】
在nginx里面,配置server_name的时候,必须将部署nginx的ECS IP、OSS endpoint原始域名 都加上。
同时,为了能够正常鉴权,必须设置:proxy_pass http://${OSS endpoint原始域名}; proxy_set_header Host $http_host;
完整的nginx server配置参考如下:
server { listen ${port} default_server; ## 反向代理的端口,一般是80/443 # listen [::]:80 default_server; ## IPv6的端口监听一般可以不开启 server_name ${ip} ${OSS endpoint原始域名}; ## 将反向代理IP(也就是部署nginx的ECS IP)、OSS endpoint原始域,都作为server_name root /usr/share/nginx/html; # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; ## 如果有其他配置,建议放到/etc/nginx/default.d/ 目录下的conf配置文件 location / { proxy_pass https://${OSS endpoint原始域名}; ## 将访问nginx 反向代理域名(IP)的请求,转发到OSS bucket真正的域名。 proxy_set_header Host $http_host; ## 保持应用系统原始访问OSS bucket配置的endpoint 域名host,否则还会出现鉴权问题。 } }
【验证效果】
在oss-browser、备份一体机(veritas、爱数等)等系统,配置endpoint为${OSS endpoint原始域名},然后将ak/sk、oss://${bucket名字}等参数填上,就可以正常访问OSS bucket,不再出现鉴权问题: