各位大佬,
我们在给甲方部署一个 Go 项目 时,遇到一个关于外部网络访问受限的问题,想请教有没有通用、优雅的解决方案。
✅ 背景信息:
1. 项目使用 Go 编写,集成了多个第三方 SDK ,比如:
• 阿里云 SDK ( Aliyun )
• AWS SDK
• Let’s Encrypt (自动申请证书)
• 其他 RESTful API 客户端
2. 这些 SDK 会直接访问公网域名,比如:
• https://alidns.aliyuncs.com
• https://acme-v02.api.letsencrypt.org
• https://sts.amazonaws.com
🚧 甲方网络要求:
1. 甲方有严格的出口策略,服务器不能直接访问公网。
2. 所有流量必须经过其提供的 内网网关,并统一审计。
3. 我们需要先提交所需的“外部域名列表”,然后他们会提供 一一对应的代理地址,比如:
• https://alidns.aliyuncs.com → http://alidns.my.local
• https://acme-v02.api.letsencrypt.org → http://acme.my.local
4. 服务实际运行时,必须通过这些映射地址访问外部服务。
⛰️我们面临的核心挑战是:
1. Go 项目中大量使用第三方 SDK ,这些 SDK 会直接访问外部域名。
2. 我们不想直接修改 SDK 的代码,不想维护一堆 fork 。
3. 域名数量多、来源复杂,难以完全靠手工收集和配置。
🤔 当前尝试:
1. 部分 SDK (如 AWS )提供了自定义 Endpoint 的设置方式,我们可以通过代码配置替换了对应的 URL 。
2. 其他 SDK (如 tencentcloud go sdk 、Aliyun Go SDK ):
• 有的不支持 endpoint 替换,或者是在计算签名要包含 host 参数
• 有的需要深度改代码或 fork
3. 考虑过系统层或中间层方案,比如:
• hosts 劫持(不适用于 HTTPS + SNI )
• 本地 HTTP 代理 + 域名重写(如 mitmproxy 、squid )
• iptables + redsocks 实现透明代理(过于复杂)
• Go 中自定义 http.Transport + DialContext:受限于 SDK 能否复用全局 http.Client
❓想请教大家:
1. 有没有通用方式拦截 Go 项目中 SDK 发起的 HTTPS 请求,并做统一的域名映射或代理转发?
• 比如运行时 Hook 、网络中间层、标准库配置等。
2. 是否有成熟的内网网关代理解决方案(支持 hostname 映射、HTTPS 转发)适合这种场景?
3. 有没有人做过类似政企、金融、军工、政府等受限内网部署,你们是怎么处理第三方 SDK 出口问题的?
非常感谢大家宝贵的经验和建议!🙏 如有成熟工具、框架、示例代码或经验文章,也欢迎推荐。
![]() |
1
cat 51 天前 ![]() 内部 DNS 不行嘛,解析到有外网访问权限的机器上反代
|
2
FrankAdler 51 天前 via Android
go 的网络库支持指定 proxy ,你可以在 proxy 内分析所有出现的 host ,或者直接代理
|
![]() |
3
lsk569937453 51 天前
内网配置 dns 解析,然后解析到代理机上,由代理机统一出口。
|
![]() |
4
minami 51 天前
挂透明代理,你这个是 go 项目,不能用 proxychains-ng ,用 graftcp 或者 cgproxy 可以
|
![]() |
5
aladdinding 51 天前
搭建一个公网代理服务器,然后让这些 sdk 走代理就行了
|
![]() |
6
lepig 51 天前 ![]() 我觉得分析第三方 SDK 的 host 这个路子就不对,一开始就钻牛角尖了。
简单的方法就是项目基本不做变动,而且想办法将所有请求劫持打到一台代理服务上,让这个代理服务去访问公网。 所有的审计,就审计这一台代理服务就行。 |
7
mengzhuo 51 天前
HTTPS_PROXY+ NO_PROXY 环境变量就行了啊,当然 SDK 得用的是 DefaultTrans
|
![]() |
8
ohhal 51 天前
我们需要先提交所需的“外部域名列表”,然后他们会提供 一一对应的代理地址
|
![]() |
9
yplam 51 天前
试试自己实现 net.Resolver , 覆盖掉 net.DefaultResolver
|
![]() |
11
dallaslu 51 天前
Go 所在主机将所有域名解析到代理机,代理机可自动收集域名并上报给甲方,甲方反馈的代理地址自动应用到代理机规则上。可以使用 Nginx+ETCD+Confd ,加上一个收集上报、写入规则的管理器
|
![]() |
12
vus520 51 天前
考虑到有些 SDK 可能会使用自己的 Resolver 和 DefaultTrans ,最简单的方案是 HTTPS_PROXY 环境变量,最复杂和可靠的方案是做流量劫持。
|
![]() |
13
COW 51 天前 via Android
挂透明代理,第三方 sdk 请求统一走你的代理,代理日志里提取域名列表
|
14
macaodoll 51 天前
申请域名白名单啊
|
![]() |
15
kidlj 51 天前
建议内网搭一个 clash 🐶
|
![]() |
16
zhenlang 51 天前
gost 研究一下
|
17
sky3hao9 51 天前
SDK 都下载下来 , 搭建私有仓库
|
18
wwhontheway 51 天前
DNS 劫持 + 反向代理
|
19
fulln 51 天前
申请个内部域名专门走内网代理,用 fasthttp 走设置 http proxy 访问的域名就行。 这个应该很成熟了
|
20
name1991 51 天前
蹲个答案
|
![]() |
21
lysShub 51 天前
替换 net.DefaultResolver
|
![]() |
22
nuk 51 天前
可以不改 SDK ,直接改官方库,然后 map 一下地址
|
23
crackidz 51 天前
环境变量就行,你们内部接口不需要走代理的就自己单独初始一个不用代理的 client
|
![]() |
24
zljklang 51 天前
写 hosts 文件嘛
|
![]() |
25
realpg PRO 全局代理, 代理处分流
用 ss 那种带分流的代理软件... |
![]() |
26
Augix 51 天前 ![]() 透明代理又不能 HTTPS 转 HTTP ,你这只能 DNS 劫持+自签证书+Nginx 转发到上游 HTTP 地址
|
27
gam2046 51 天前 ![]() 怕是有点难办
https://alidns.aliyuncs.com → http://alidns.my.local 这个过程中,你有测试过,具体网关是什么行为嘛,https 降级成 http ,那基本不可能是简单的一个 http/socks 代理那种形式了,因此其他回答里提到的 https_proxy 这种环境变量是白扯的。 同样的 DNS 劫持无法实现,因为客户端发起请求时,需要降级到 http ,这一点单纯 DNS 劫持做不到。 相对而言,fork ,改代码可能结果与工期更为可控。 非要整花活的话,运行程序的本机,DNS 设置为自己或其他可控的机器,先让原始请求到自己的代理,然后自签证书返回给客户端,你这边的代理,再根据外部域名列表,请求到.my.local 的地址。 相当于你自己需要写个代理,先把 https 降级。 而且这种情况下,还得原始的 SDK 内没有采用一些证书固定的方案,否则也降级不了。 |
28
IndexOutOfBounds 51 天前 via Android ![]() 问题表达形式不错呀
|
![]() |
29
lasuar 51 天前
第三方不支持替换 url 的 sdk 能有多少?改代码可能还是最靠谱的。
|
![]() |
30
ksedz 51 天前
隔离环境最好用的还是 go mod vendor
|
![]() |
31
ksedz 51 天前
看错了,忽略吧
|
33
kekxv 51 天前
看起来只有几个 sdk ,最合适的方法,应该是直接 fork 他们的仓库,然后加上参数或者配置之后,给他们提交 pr ,这样就不需要自己单独维护一套代码
|
34
ansuanboy 51 天前
可以使用双层代理,
向甲方申请一个代理出口到你们公司自己的公网代理入口 然后自己写代码创建一个 http 代理服务器,代理所有 SDK 请求包并自定义封装一层。 再通过甲方的代理出口代理到你们自己的公网代理服务入口,解包发出实际请求,再将响应内容返回 整个过程只涉及四层网络结构,http\https 都可以穿透 |
![]() |
35
chf007 51 天前
一般第三方 sdk ,域名这种变量,一般都会暴露配置出来的啊,你们用的时候都不配置一下的么?或初始化时配置,或通过环境变量配置,只要把这些集中管理一下就行了。
|
36
mooyo 51 天前
你这个咋看着像 fake ip ,和 fake ip 实现类似吧?
|
37
flat 51 天前
如果甲方允许在代理服务器上部署代理,那就很简单,直接用代理就行。但是如果不行,就只能看原本的 sdk 支持不支持域名替换了。前面那些内网 dns 的啥的,都不行,你配置解析到那个代理服务器有啥用,那个机器上又没有类似 nginx 的东西监听你原本的这个域名。只监听了人家给你提供的新域名。
|
38
flat 51 天前
@flat
一般的 http 库都支持这几个环境变量,配置下就能用,但是只是走代理 export HTTP_PROXY=http://127.0.0.1:8888 export HTTPS_PROXY=http://127.0.0.1:8888 export NO_PROXY=localhost,127.0.0.1 |
![]() |
39
zxp 51 天前
在公网上部署 1 个接口服务,设置成通过 a.com 域名访问,把需要访问外部域名的第三方 SDK 全部剥离出来集成到接口服务上,内网开放 1 个可以访问接口服务的代理域名,内网应用只需要通过代理域名访问这个接口服务就行了。
|
![]() |
40
shannn OP @chf007
我们这边不考虑走 SDK 层配置 endpoint 的方案了,主要原因有两个: 1. 不同 SDK 支持程度不一,有的可以配,有的只能改源码; 2. 后续维护成本高,一旦 SDK 升级或接入新的 SDK ,就得重新梳理和适配,影响开发效率。 我们更倾向于类似代理转发方案,这样: • 能集中发现和整理 SDK 中访问的外部域名; • 和甲方的域名映射策略配合更灵活; • 后续不需要动业务代码,部署也更可控。 |
![]() |
41
z44z8kDw76Vt3Pz1 51 天前
在外网编译好做成系统镜像在安装到内网不就行了。
|
![]() |
42
iguess 51 天前
显然不让你自行出公网,所以自己配代理是行不通的。 还是开发一个小工具来自动批处理你的 SDK 源码吧
|
44
partner666 51 天前
@Augix #26 测试了一下 这可行,关键是信任根证书
|
![]() |
46
lolico 51 天前
透明网关+dns 劫持,完全透明无侵入的做法,不需要自签名证书
|
![]() |
48
loushizan 51 天前
感觉可以参考 sing-box ,http Inbound 和 http Outbound
只是一个思路 |
![]() |
49
edisonwong 51 天前
GO_PROXY 到固定的(能访问外网的机器)
|
![]() |
50
edisonwong 51 天前
@edisonwong 接上,软路由,网关等都可以
|
51
wanglong167 51 天前
frp
|
![]() |
52
kinkin666 50 天前
光搞代理没用的,一般还得帮他们把第三方库的合规审计问题处理掉
得把所有跟互联网第三方相关东西包起来布你们自己服务器上,甲方专线调你们,你们公网往外走 也可以考虑把这个转发程序包成一个 docker 放他们 dmz 区,这样甲方就只用搞定你们这个镜像的合规审计问题了 |
![]() |
54
realpg PRO ![]() @kekxv #33
不具备可行性 我举个不恰当的例子 假如你是微信支付 sdk 你的内部写死了 服务器地址是 pay.weixin.qq.com 然后你提个 pr 允许自己配置服务器地址 为野鸡 URL 你觉得会是啥结果 |
![]() |
56
hymzhek 50 天前
假如甲方的设备 不知道能不能 https 审计 用 sniproxy
|
58
paragon 50 天前
在外面搭好项目 go vendor 再从里面把项目 clone 进去~
|
59
chobitssp 50 天前
换支持 endpoint 配置的 sdk
|
60
chobitssp 50 天前
|
![]() |
61
realpg PRO |
62
chobitssp 50 天前
|
65
yunpiao111 50 天前
|
66
Ramoncjs 50 天前
@IndexOutOfBounds #28 +1 背景和需求写的非常清楚,当前的进度和难点也一清二白,一次性把事儿说清楚很厉害。
|
67
iuser 49 天前
安装一个自签证书,做 https 劫持 + 搭一个 nginx ,实现 https 降级+hosts 替换+下一跳指向+把要劫持的域名配 host 指到 nginx 上 可能可行
|
![]() |
68
PopRain 49 天前
都走 Http , 所有的信息都可以被抓包,不知道是为了安全还是为了不安全
|
![]() |
69
leokun 49 天前
|
70
open9527 49 天前
op 问题解决了吗 等答案呢
|
71
wwhontheway 48 天前
op 问题解决了吗 等答案呢
|
72
alsas 43 天前
dns 解析到代理服务器统一出口
|