华为云sdk内网代理
背景
处于内网存在网络限制,无法在本地使用华为云sdk(sdk有endpoint);但本地可以访问某华为云虚拟机A,A处于华为云内网可以访问,因此计划通过在A上做代理,通过A转发请求以实现。
Note&踩坑
1. endpoint必须使用华为云域名,不能使用代理地址;
# 需写明project_id;因为 credentials中会通过
credentials = BasicCredentials(ak, sk) \
.with_iam_endpoint("https://iam.cn-south-1.myhuaweicloud.com")
client = KafkaClient.new_builder() \
.with_credentials(credentials) \
.with_region(KafkaRegion.value_of("cn-south-1")) \
.with_endpoint("https://dms.cn-south-1.myhuaweicloud.com") \
.build()
原计划为在华为云虚拟机A上通过nginx做七层代理+固定host,将endpoint替换为虚拟机A地址 http://1.1.1.1:10086 ,但实际会导致报错ak sk校验不通过;
AK/SK 签名不是只校验密钥本身,还会校验请求方法、路径、时间戳、Host 等信息。只要 endpoint 写错,签名一定对不上。
- 由于endpoint必须固定,因此必须在endpoint不变的情况下,想办法使sdk流量走虚拟机A。主要有两种方案:
(1)需改本地域名解析,将iam.cn-south-1.myhuaweicloud.com映射至虚拟机A IP;(弃用;①修改本地hosts映射需要管理员权限,内网受限;②端口必须保持443,并根据host转发至不同地址,但A上443被占用)
(2)引入 HttpConfig 配置sdk代理;只影响程序本身;而由于credentials没有httpconfig方法,因此需写明projectid,防止credentials通过iam endpoint获取;因此实际上我们这里只需要配置dms代理;
# 写明project_id;
credentials = BasicCredentials(ak, sk, project_id="xxx") \
.with_iam_endpoint("https://iam.cn-south-1.myhuaweicloud.com")
config = HttpConfig.get_default_config()
config.proxy_protocol = "http"
config.proxy_host = "1.1.1.1"
config.proxy_port = 10086
config.ignore_ssl_verification = True
client = KafkaClient.new_builder() \
.with_credentials(credentials) \
.with_region(KafkaRegion.value_of("cn-south-1")) \
.with_endpoint("https://dms.cn-south-1.myhuaweicloud.com") \
.with_http_config(config) \
.build()
3. 从 Nginx 换到 TinyProxy
SDK 走 HTTPS 正向代理时,会先发CONNECT请求;
正向代理——客户端显式配置代理地址,代理客户端,让代理替自己访问外部。
CONNECT dms.cn-south-1.myhuaweicloud.com:443 HTTP/1.1
而Nginx默认是反向代理,默认不支持 HTTP CONNECT,所以报:
Unable to connect to proxy; Tunnel connection failed: 400 Bad Request
在在代理服务器上装 TinyProxy,监听 10086。
-
如果用nginx四层代理怎么做?
(1)HttpConfig是正向代理方式,如使用这种方式,可直接去掉这一块;
(2)四层代理只能看到IP和端口,看不到域名,所以必须配合修改本地dns解析,然后nginx按sni分流;
(3)四层代理可以避开connect,connect为http标准方法;由https+正向代理触发; -
为什么一定是正向代理?
场景:客户端在内网,不能直接访问华为云,必须经过一台代理服务器出网。这就是正向代理——客户端显式配置代理地址,让代理替自己访问外部。
要访问的是 https://dms.cn-south-1.myhuaweicloud.com ,全程 TLS 加密。代理服务器没有华为云的私钥,不可能解密后再转发。所以客户端必须先用明文告诉代理:"帮我建一条到目标 443 端口的 TCP 隧道"——这就是 CONNECT。
换言之,如果当目标地址是http,没有解密需求,也不会触发connect;

浙公网安备 33010602011771号