V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
shannn
V2EX  ›  Go 编程语言

[求助] Go 项目中大量第三方 SDK 需要访问外部域名,但甲方要求全部走内网代理,有哪些优雅处理方式?

  •  2
     
  •   shannn · 51 天前 · 6243 次点击
    这是一个创建于 51 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大佬,

    我们在给甲方部署一个 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 条附言  ·  51 天前
    📝 补充说明:
    甲方提供的代理地址是 HTTP 协议 的(他们有审计要求),例如:
    https://alidns.aliyuncs.com → http://alidns.my.local 。

    而我们项目中大量 SDK 请求是基于 HTTPS 协议 的,这就要求我们在实际方案中进行 HTTPS → HTTP 的协议转换
    72 条回复    2025-06-05 17:14:05 +08:00
    cat
        1
    cat  
       51 天前   ❤️ 2
    内部 DNS 不行嘛,解析到有外网访问权限的机器上反代
    FrankAdler
        2
    FrankAdler  
       51 天前 via Android
    go 的网络库支持指定 proxy ,你可以在 proxy 内分析所有出现的 host ,或者直接代理
    lsk569937453
        3
    lsk569937453  
       51 天前
    内网配置 dns 解析,然后解析到代理机上,由代理机统一出口。
    minami
        4
    minami  
       51 天前
    挂透明代理,你这个是 go 项目,不能用 proxychains-ng ,用 graftcp 或者 cgproxy 可以
    aladdinding
        5
    aladdinding  
       51 天前
    搭建一个公网代理服务器,然后让这些 sdk 走代理就行了
    lepig
        6
    lepig  
       51 天前   ❤️ 3
    我觉得分析第三方 SDK 的 host 这个路子就不对,一开始就钻牛角尖了。

    简单的方法就是项目基本不做变动,而且想办法将所有请求劫持打到一台代理服务上,让这个代理服务去访问公网。

    所有的审计,就审计这一台代理服务就行。
    mengzhuo
        7
    mengzhuo  
       51 天前
    HTTPS_PROXY+ NO_PROXY 环境变量就行了啊,当然 SDK 得用的是 DefaultTrans
    ohhal
        8
    ohhal  
       51 天前
    我们需要先提交所需的“外部域名列表”,然后他们会提供 一一对应的代理地址
    yplam
        9
    yplam  
       51 天前
    试试自己实现 net.Resolver , 覆盖掉 net.DefaultResolver
    ohhal
        10
    ohhal  
       51 天前
    @ohhal 不好意思回车直接回了,直接搞个代理就行啊
    dallaslu
        11
    dallaslu  
       51 天前
    Go 所在主机将所有域名解析到代理机,代理机可自动收集域名并上报给甲方,甲方反馈的代理地址自动应用到代理机规则上。可以使用 Nginx+ETCD+Confd ,加上一个收集上报、写入规则的管理器
    vus520
        12
    vus520  
       51 天前
    考虑到有些 SDK 可能会使用自己的 Resolver 和 DefaultTrans ,最简单的方案是 HTTPS_PROXY 环境变量,最复杂和可靠的方案是做流量劫持。
    COW
        13
    COW  
       51 天前 via Android
    挂透明代理,第三方 sdk 请求统一走你的代理,代理日志里提取域名列表
    macaodoll
        14
    macaodoll  
       51 天前
    申请域名白名单啊
    kidlj
        15
    kidlj  
       51 天前
    建议内网搭一个 clash 🐶
    zhenlang
        16
    zhenlang  
       51 天前
    gost 研究一下
    sky3hao9
        17
    sky3hao9  
       51 天前
    SDK 都下载下来 , 搭建私有仓库
    wwhontheway
        18
    wwhontheway  
       51 天前
    DNS 劫持 + 反向代理
    fulln
        19
    fulln  
       51 天前
    申请个内部域名专门走内网代理,用 fasthttp 走设置 http proxy 访问的域名就行。 这个应该很成熟了
    name1991
        20
    name1991  
       51 天前
    蹲个答案
    lysShub
        21
    lysShub  
       51 天前
    替换 net.DefaultResolver
    nuk
        22
    nuk  
       51 天前
    可以不改 SDK ,直接改官方库,然后 map 一下地址
    crackidz
        23
    crackidz  
       51 天前
    环境变量就行,你们内部接口不需要走代理的就自己单独初始一个不用代理的 client
    zljklang
        24
    zljklang  
       51 天前
    写 hosts 文件嘛
    realpg
        25
    realpg  
    PRO
       51 天前
    全局代理, 代理处分流
    用 ss 那种带分流的代理软件...
    Augix
        26
    Augix  
       51 天前   ❤️ 1
    透明代理又不能 HTTPS 转 HTTP ,你这只能 DNS 劫持+自签证书+Nginx 转发到上游 HTTP 地址
    gam2046
        27
    gam2046  
       51 天前   ❤️ 1
    怕是有点难办

    https://alidns.aliyuncs.com → http://alidns.my.local

    这个过程中,你有测试过,具体网关是什么行为嘛,https 降级成 http ,那基本不可能是简单的一个 http/socks 代理那种形式了,因此其他回答里提到的 https_proxy 这种环境变量是白扯的。

    同样的 DNS 劫持无法实现,因为客户端发起请求时,需要降级到 http ,这一点单纯 DNS 劫持做不到。

    相对而言,fork ,改代码可能结果与工期更为可控。

    非要整花活的话,运行程序的本机,DNS 设置为自己或其他可控的机器,先让原始请求到自己的代理,然后自签证书返回给客户端,你这边的代理,再根据外部域名列表,请求到.my.local 的地址。

    相当于你自己需要写个代理,先把 https 降级。

    而且这种情况下,还得原始的 SDK 内没有采用一些证书固定的方案,否则也降级不了。
    IndexOutOfBounds
        28
    IndexOutOfBounds  
       51 天前 via Android   ❤️ 1
    问题表达形式不错呀
    lasuar
        29
    lasuar  
       51 天前
    第三方不支持替换 url 的 sdk 能有多少?改代码可能还是最靠谱的。
    ksedz
        30
    ksedz  
       51 天前
    隔离环境最好用的还是 go mod vendor
    ksedz
        31
    ksedz  
       51 天前
    看错了,忽略吧
    shannn
        32
    shannn  
    OP
       51 天前
    @lasuar 不想改腾讯云的 go sdk 了
    kekxv
        33
    kekxv  
       51 天前
    看起来只有几个 sdk ,最合适的方法,应该是直接 fork 他们的仓库,然后加上参数或者配置之后,给他们提交 pr ,这样就不需要自己单独维护一套代码
    ansuanboy
        34
    ansuanboy  
       51 天前
    可以使用双层代理,
    向甲方申请一个代理出口到你们公司自己的公网代理入口
    然后自己写代码创建一个 http 代理服务器,代理所有 SDK 请求包并自定义封装一层。
    再通过甲方的代理出口代理到你们自己的公网代理服务入口,解包发出实际请求,再将响应内容返回
    整个过程只涉及四层网络结构,http\https 都可以穿透
    chf007
        35
    chf007  
       51 天前
    一般第三方 sdk ,域名这种变量,一般都会暴露配置出来的啊,你们用的时候都不配置一下的么?或初始化时配置,或通过环境变量配置,只要把这些集中管理一下就行了。
    mooyo
        36
    mooyo  
       51 天前
    你这个咋看着像 fake ip ,和 fake ip 实现类似吧?
    flat
        37
    flat  
       51 天前
    如果甲方允许在代理服务器上部署代理,那就很简单,直接用代理就行。但是如果不行,就只能看原本的 sdk 支持不支持域名替换了。前面那些内网 dns 的啥的,都不行,你配置解析到那个代理服务器有啥用,那个机器上又没有类似 nginx 的东西监听你原本的这个域名。只监听了人家给你提供的新域名。
    flat
        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
    zxp
        39
    zxp  
       51 天前
    在公网上部署 1 个接口服务,设置成通过 a.com 域名访问,把需要访问外部域名的第三方 SDK 全部剥离出来集成到接口服务上,内网开放 1 个可以访问接口服务的代理域名,内网应用只需要通过代理域名访问这个接口服务就行了。
    shannn
        40
    shannn  
    OP
       51 天前
    @chf007

    我们这边不考虑走 SDK 层配置 endpoint 的方案了,主要原因有两个:
    1. 不同 SDK 支持程度不一,有的可以配,有的只能改源码;
    2. 后续维护成本高,一旦 SDK 升级或接入新的 SDK ,就得重新梳理和适配,影响开发效率。

    我们更倾向于类似代理转发方案,这样:
    • 能集中发现和整理 SDK 中访问的外部域名;
    • 和甲方的域名映射策略配合更灵活;
    • 后续不需要动业务代码,部署也更可控。
    z44z8kDw76Vt3Pz1
        41
    z44z8kDw76Vt3Pz1  
       51 天前
    在外网编译好做成系统镜像在安装到内网不就行了。
    iguess
        42
    iguess  
       51 天前
    显然不让你自行出公网,所以自己配代理是行不通的。 还是开发一个小工具来自动批处理你的 SDK 源码吧
    name1991
        43
    name1991  
       51 天前
    @shannn #40 这个听上去就很合理。。。
    partner666
        44
    partner666  
       51 天前
    @Augix #26 测试了一下 这可行,关键是信任根证书
    shannn
        45
    shannn  
    OP
       51 天前
    @Augix 刚才和公司擅长网络的同学聊了下,也是这个思路。服务埋自签证书,通过改 host 或 iptables 去转发到代理服务,代理服务再卸载和转发
    lolico
        46
    lolico  
       51 天前
    透明网关+dns 劫持,完全透明无侵入的做法,不需要自签名证书
    lolico
        47
    lolico  
       51 天前
    @lolico 可以不需要 dns 劫持,直接服务器使用的 dns 服务器也可以,类似家庭网络里单独搞一个网关出口走代理的做法
    loushizan
        48
    loushizan  
       51 天前
    感觉可以参考 sing-box ,http Inbound 和 http Outbound
    只是一个思路
    edisonwong
        49
    edisonwong  
       51 天前
    GO_PROXY 到固定的(能访问外网的机器)
    edisonwong
        50
    edisonwong  
       51 天前
    @edisonwong 接上,软路由,网关等都可以
    wanglong167
        51
    wanglong167  
       51 天前
    frp
    kinkin666
        52
    kinkin666  
       50 天前
    光搞代理没用的,一般还得帮他们把第三方库的合规审计问题处理掉

    得把所有跟互联网第三方相关东西包起来布你们自己服务器上,甲方专线调你们,你们公网往外走

    也可以考虑把这个转发程序包成一个 docker 放他们 dmz 区,这样甲方就只用搞定你们这个镜像的合规审计问题了
    BeGoood
        53
    BeGoood  
       50 天前
    @lolico 只是透明网关+DNS 劫持不行吧,这个场景中涉及到 HTTPS -> HTTP, SSL 卸载必须做中间人,信任自签证书才能解决吧。
    realpg
        54
    realpg  
    PRO
       50 天前   ❤️ 1
    @kekxv #33
    不具备可行性

    我举个不恰当的例子
    假如你是微信支付 sdk
    你的内部写死了 服务器地址是 pay.weixin.qq.com

    然后你提个 pr 允许自己配置服务器地址 为野鸡 URL
    你觉得会是啥结果
    kekxv
        55
    kekxv  
       50 天前 via iPhone
    @realpg #54 为啥要把地址写上去呢?读环境变量,或者配置刷新,等都可以
    hymzhek
        56
    hymzhek  
       50 天前
    假如甲方的设备 不知道能不能 https 审计 用 sniproxy
    realpg
        57
    realpg  
    PRO
       50 天前
    @kekxv #55
    我微信支付的 sdk 我不把我自己微信支付的服务器地址写进去?
    我工商银行的 sdk 我不把工商银行的 IP 写进去?
    paragon
        58
    paragon  
       50 天前
    在外面搭好项目 go vendor 再从里面把项目 clone 进去~
    chobitssp
        59
    chobitssp  
       50 天前
    换支持 endpoint 配置的 sdk
    chobitssp
        60
    chobitssp  
       50 天前
    realpg
        61
    realpg  
    PRO
       50 天前
    @chobitssp #60

    这就是举例你懂不懂?

    人家自己 sdk 都把容灾切换都写好了 那是 SDK 不是 API SAMPLE

    你连 sdk 和 api 都没搞明白吧
    realpg
        63
    realpg  
    PRO
       50 天前
    @chobitssp #62
    你是真不看贴 block 了 不用回我了
    lolico
        64
    lolico  
       50 天前 via iPhone
    @BeGoood 单纯把流量转到某一个代理机走代理访问是可以的,不需要自签证书。但如果还要审计之类的就另说
    yunpiao111
        65
    yunpiao111  
       50 天前
    我之前做的透明代理方案, 把 sdk 的流量全劫持过来, 转发到 clash, 之后再 calsh 里面写匹配规则, 使用不同的 http 代理或者 socks 代理
    Ramoncjs
        66
    Ramoncjs  
       50 天前
    @IndexOutOfBounds #28 +1 背景和需求写的非常清楚,当前的进度和难点也一清二白,一次性把事儿说清楚很厉害。
    iuser
        67
    iuser  
       49 天前
    安装一个自签证书,做 https 劫持 + 搭一个 nginx ,实现 https 降级+hosts 替换+下一跳指向+把要劫持的域名配 host 指到 nginx 上 可能可行
    PopRain
        68
    PopRain  
       49 天前
    都走 Http , 所有的信息都可以被抓包,不知道是为了安全还是为了不安全
    leokun
        69
    leokun  
       49 天前
    用站里面大佬写的 whistle 可以很轻松配置这样的代理

    这个工具的思路是在你的(系统)容器中安装一个自签证书,并且开启一个 socks 代理
    有一个 GUI 可以配置转发规则
    按照楼上的想法,你可以把它部署在另一台服务器,然后把当前的系统的代理配过去
    或者直接在当前系统部署
    open9527
        70
    open9527  
       49 天前
    op 问题解决了吗 等答案呢
    wwhontheway
        71
    wwhontheway  
       48 天前
    op 问题解决了吗 等答案呢
    alsas
        72
    alsas  
       43 天前
    dns 解析到代理服务器统一出口
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3017 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 10:45 · PVG 18:45 · LAX 03:45 · JFK 06:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.