外网 CI/CD 访问内网 GitLab 的典型困境
把 GitLab 暴露到公网是很多团队踩过的坑。直接给 GitLab 配公网 IP 或端口映射,等于把代码仓库、CI/CD 配置、Runner 注册信息一并推到公网攻击面里。GitLab 实例承载的不只是源码,还有 .gitlab-ci.yml 中嵌入的部署密钥、镜像仓库凭证、内部系统回调地址。一旦公网端口被扫描到,撞库、未授权访问、历史 CVE 利用就会接踵而至。另一种做法是要求 CI/CD 执行机放在内网,外网开发者每次推送代码都得先拨 VPN 再操作,本地 Runner 更是无从谈起。GitLab 的 Webhook、外部 Runner、制品上传都需要稳定的双向连接,传统 VPN 按网段放行又做得太粗。问题的本质不是“能不能连通”,而是连接的粒度、身份与审计是否可控。NexTunnel 的解法是把 GitLab 的访问入口从公网收回内网,同时保留外网发起 CI/CD 操作的能力。
NexTunnel 前置部署:Server 在内网侧的落地位置
NexTunnel Server 部署在 GitLab 所在的网络区域,这是整条链路的锚点。Server 不需要公网 IP,不需要在防火墙开入站端口。它只出站连接 NexTunnel 的调度服务,建立一条长连接。GitLab 本身不感知 NexTunnel 的存在,不需要改 GitLab 的监听地址,也不需要给 GitLab 配置外部 URL 的公网形态。Server 侧上线后,在管理后台把这台 Server 加入一个企业,后续的访问策略都围绕这个企业派生。
内网 GitLab 通常绑定固定主机名,例如 gitlab.internal,HTTP 监听 80 或 8443,SSH 协议用于 git push/pull。NexTunnel 的端口资源授权不是按网段一刀切,而是可以逐个资源添加。添加资源时,目标指向 GitLab 主机名和协议端口。授权后,只有被允许的 Client 才能解析或访问这个目标。
部署时有一个容易忽略的点:Server 所在内网如果启用了严格的 DNS 层管控,尽量让 Server 通过内网 DNS 解析 GitLab 主机名,不要依赖外网公共 DNS 或是把 GitLab 改成 IP 直连。端口资源保持主机名形式,后续 GitLab 做会话保持、HTTPS 证书校验时才不会稀里糊涂地看到 IP 与证书不符。
[插图建议:NexTunnel Server 部署位置与 GitLab 内网拓扑示意,标出 Server 与 GitLab 之间的内网连接、Server 到调度服务的单向出站连接]
端到端建立连接的操作路径
NexTunnel 的访问模型建立在设备维度上。每个外网开发者的电脑安装 NexTunnel Client,这台设备先在 NexTunnel 环境中完成注册。客户端接通后,终端只有设备离线、在线、授权目标这几件事。管理员在后台给设备发起授权,指定可访问的服务器或串联的资源端口。开发者不需要知道 GitLab 后面有没有公网 IP,客户端会按规则把流量送向出口。这样的处理方式更适合临时执行节点:一个外部 CI Runner 如果需要跑几天流水线,设备加进允许范围后跑完直接撤销,链条干净利落。
这里重点说外部工具如何感知隧道。NexTunnel Client 与 Server 建立的是按需连接。用户点击连接后,gitlab.internal:443 转为可在客户端机器可达的本地入口。开发者在接入层的 Client 上检查标识,之后的 git 操作不再需要额外配置代理。理解起来很简单:进入连接状态时,本机已拥有访问内网 GitLab 的可行路径。
但建议不要在任何文档中把该入口写成长期监听钩子,在实际运维中这会误导后续的权限收敛策略。始终把连接视为“发起任务前建立、任务结束后可断开”。GitLab Webhook 主动回调的场景除外,譬如外网 Jenkins 要接收来自 GitLab 的事件。此时客户端需要保持在线状态,否则 Webhook 事件失去回推目标。这里其实也是 NexTunnel 方案优于传统端口映射的一点,临时断连不会造成公网 GitLab 端口暴露。
权限与审计:端口白名单和设备授权如何限制 CI/CD 风险
CI/CD 场景最忌讳把内网服务划成同一网段再送给远端。外网 Jenkins、本机 Runner、研发笔记本可能是三种完全不同的信任层级,如果只给一个“内网可达”的访问路径,任何一个设备都拥有了过宽的入口面。NexTunnel 后台授权单位是设备,不是网段。每个设备能看到的服务器、资源、端口由授权列表决定。访问 GitLab 的构建服务器可以只被授权 GitLab HTTP 协议用端口;普通开发笔记本可以同样或再分配 SSH 用端口;如果第三方审计人员要查看 Runner 日志,只需要开放构建系统首页,没有 GitLab 主库可达性。
这种收口能力的直接好处是:即使某台外网 Client 失陷,攻击者只能在已授权端口里横向探测。它没有获得探索整段内网的入口。配合流水线中的最小权限策略,GitLab Runner 也照这个思路来——Runner 所在设备如果就是 Client,它只需要 git clone/push 面向的协议目标可用,ci_job_token 由 GitLab 身份系统管,底层的网络出口收在 NexTunnel。
在 CI/CD 长时间运行的面貌下,访问审计还要有基本的责任关怀,这恰恰是这类流水线管理容易缺失的一层。外部共享账号、短期联调窗口这些实践都很常见,但事后基本无法知道哪个会话在什么时候做过什么。NexTunnel 的日志按连接行为呈现,管理端可以确认授权动作发生时间,以及对应资源目标范围。审计结果更倾向于通道连接层面,把它与 GitLab 内部登录跟踪联动,两套日志互补能提高整体可见性。
| 接入方式 | 公网暴露面 | 设备级授权 | 审计颗粒度 | 部署/操作成本 |
|---|---|---|---|---|
| 公网端口映射 GitLab | 大,长期暴露 GitLab Web 与 SSH 端口 | 无,依赖防火墙或路由器策略 | 多为 IP 级别,难以区分具体设备 | 低但长期运维风险高 |
| 全链路 VPN | VPN 网关暴露,集中攻防点 | 通常只有用户角度的信任 | 部分可审计,按用户关联网络流 | 中高,需要客户端部署与运维 |
| NexTunnel Client/Server | 无额外对公网暴露的 GitLab 端口 | 设备/账号双因子管控,端口白名单 | 连接事件与资源授权改动可回溯 | 低,无内网入侵改造 |
为什么 CI/CD 比普通远程办公更需要稳定的协议通道
你可以把远程桌面断掉后重连,Web 页面刷新一次换条 HTTP 会话也无所谓,但 CI/CD 任务属于连续性高、上下文长的操作。克隆一个大型仓库分支途中网络断掉,后面的流水线阶段全废;Runner 正在上传构建产物时断连,几百 MB 的制品白传;LFS 对象 fetch 遇连接抖动,触发整个作业重跑。降低重建连接频率是实际生产环境里的刚需。
常规端口映射方案很难实时识别断线再切重连,连接权重完全悬在基础网络质量上。NexTunnel 建立路径时就存在两种转发类型,一种链路较优时使用 P2P 直连,两端可达即可点对点走流量;中间路径受限时由中继转发配合通信。判断逻辑由产品内部维持,Client 反而不需要做手工选择。这很适合部署环境各异的构建机器:联调的工作站、放在异地的 Runner 主机、临时用 Windows 笔记本触发的打包任务,各自网络环境差异大,统一走同一个接入模型会让链路重建少出很多意外。
真正的弹性仍然来自客户端可以在任务以外有离线状态。传统的映射规则一旦删掉,出网规则频繁改动;取消一个开发者的 GitLab 权限时,可能还要同时禁止公网端口上发现相关痕迹。NexTunnel 之中权限被收回、设备被移除或设备自己在 Client 端断开,作用都更直接。对管流水线的运维来说,“把一次 CI/CD 工作窗口关掉”的时间几乎缩短到一次设备授予就能终止。
把生产变更集中到三层:Server 基线、资源端口、设备周期
要让外部可管理地访问内网 GitLab,不一定非得给配置里多造几个特殊参数。把日常全部操作压在管理页面上,实际上要理清楚的只有三件事。
- Server 基线:确认内网 GitLab 可达性始终从 Server 侧校验。每次新增用户设备后,在给外部授权之前,先在 Server 一侧确认连通性。Server 离线时不应让 Client 处于等待假连接状态。
- 资源端口维护:HTTP(S)、SSH 等不同端口的端口白名单要随 GitLab 的服务演进实际更新。GitLab Container Registry 使用单独端口或独立域名时,也要有对应条目,避免只放行一个 Web 端口,最后 Container Registry 怎么都拉不到镜像。
- 设备周期:所有 CI/CD 设备尽量以有限周期授权。外部测试 Webhook 构建的机器可能只活跃一到两天,阶段性任务结束就从后台移除设备,保持“此刻活跃的入网点最小化”。每次授权在审计里都有痕迹,万一有异常可以判断这条链是在哪段被展开的。
这类窄而严的把控不是为了让开发者不爽。CI/CD 团队对 GitLab 的可用性敏感,如果他们频繁发现远端连接受阻,会绕过网络策略自行开隧道。规则要省心到与 GitLab 本地推送区分度低。NexTunnel 的优点不是推出更多的安全页签,而是减少决策量、让原来需要一整套 VPN 工单过程的操作变成后台加设备即可达成的管理动作。
下一步:用最小访问集跑通一条真实流水线
可以从小范围验证开始,不需要让整个研发团队立刻全量迁移。在一台外网测试机上做三阶段验收。
- 搭建验证:在内网部署 NexTunnel Server,绑定资源目标为 GitLab HTTP(S) 协议端口。外网 Client 只对这台测试机授权,确认可 clone 和 push,不切开任何现有访问路线。
- 权限观察:后台为一条流水线 Runner 设备设置最小端口集,在 GitLab 中触发一次真实流水线,观察 connection、资源目标与结期的完整连接状态,同步核对审计链路。NexTunnel 与 GitLab 二者都应能记录到这份操作上下文。
- 逐步内聚:外部的固定 Runner、项目经理、运维的值守设备,按工作性质分批纳入授权。待全团队熟悉该链路稳定性后,再评估把公网 GitLab 访问整体关停,只保留 Client 到 Server 的联接通道。
最终企业的 GitLab 不会向公网开放任何端口,也不需要内网的 Router、交换机为经常变化的“外网 IP+端口”规则耗尽维护资源。集中维护入口身份与资源策略,通常运营成本不升反降。CI/CD 请求仍然源自真实外部客户端,但是每个连接都有归属、有限定目标、有过程。NexTunnel 的价值也在这里:它不是让内网 GitLab 突破边界,而是完整替换掉那种大爆炸式公网暴露接入模型。