我们在Intranet网络中使用onPrem S3存储服务器,并且我们希望将此Intranet网址公开给互联网,因此我们使用了具有到Intranet网址的映射的代理。当我们测试内部网网址时,它运行良好,但是当我们测试互联网网址时,我们收到403错误:
我们计算的请求签名与您提供的签名不符。检查您的秘密访问密钥和签名方法。有关详细信息,请参阅REST身份验证和SOAP身份验证。 (服务:Amazon S3;状态代码:403;错误代码:SignatureDoesNotMatch;请求ID:0a440c7f:15cc604b1e2:12d3af:24d; S3扩展请求ID:null),S3扩展请求ID:null
调试后,我们发现代理修改了用于计算签名的主机头,以便将请求重定向到内网网址...
所以我的问题是如何使用AWS SDK或Boto3客户端从V4签名计算中抑制一些标题。或者是否有更好的架构来公开onPrem S3服务。
提前致谢。 阿米尔。
答案 0 :(得分:1)
基本上有两种解决方案。
第一个更容易:签署内部URL的请求,然后只需使用简单的字符串前缀替换来重写签名URL的主机部分,将其指向外部代理的主机名。当代理重写Host
标题时,它最终会将其重新写回您签名的内容。
我认为,通常知道,签名网址不受篡改影响,出于所有实际目的:您无法在不使其失效的情况下更改关于签名网址的任何内容 ...但是这不是什么。此更改是暂时的,代理的净效果是撤消更改。
备用解决方案需要链中的代理或其他服务(在存储服务之前)知道签名密钥和机密,以便它可以首先验证传入请求,如果有效,则修改请求然后生成服务将接受的新签名。我曾经编写过一个服务来执行此操作,以便当请求为HEAD
时,代理将使用相同的密钥和密钥(它知道)为同一请求生成签名,但使用{{1} }。如果它与传入请求中的签名匹配,则代理将使用GET
请求的签名替换现有签名 - 从而允许客户端使用最初为HEAD
请求签名的URL,提出GET
或GET
请求 - S3本身不支持,因为同一对象的HEAD
和GET
需要两个不同的签名网址。但是,概念是相同的 - 在代理中为客户端请求生成签名,验证传入签名,然后根据需要重新签名请求。我构建的解决方案使用HAProxy的Lua集成来检查和修改飞行中的请求。