GOST 使用与技术原理分析:从代理转发到内网穿透

3 阅读13分钟

日常开发和运维工作中,我们经常会遇到以下需求:

  • 在服务器上快速搭建一个 HTTP 或 SOCKS5 代理;
  • 将本地端口映射到远程服务;
  • 把只支持 HTTP 代理的软件接入 SOCKS5 上游;
  • 通过加密隧道访问远程网络;
  • 将内网中的 Web、SSH、数据库等服务暴露到公网;
  • 串联多个代理节点,实现多级转发;
  • 为 TCP、UDP 流量提供统一的转发入口。

这些需求通常需要 Nginx、SSH Tunnel、FRP、HAProxy、Clash 等不同工具分别解决,而 GOST 的特点是:它把代理、端口转发、隧道、代理链和内网穿透能力整合进了一个工具。

GOST 的全称是 GO Simple Tunnel,是一个使用 Go 编写的网络代理和安全隧道工具。官方将其核心使用方式归纳为代理、端口转发和反向代理隧道三类,同时还支持负载均衡、流量路由、限速、访问控制、DNS 代理、透明代理、TUN/TAP、Prometheus 指标和动态配置等功能。

需要注意的是,GOST v3 相对于 v2 是一次较大的重构。官方甚至表示,除功能和使用方式存在相似之处外,v3 可以被视为一个全新的应用。因此,网上很多 GOST v2 教程不能直接套用到 v3。


一、GOST 的核心设计思想

理解 GOST,首先要理解两个最常用的参数:

-L
-F

其中:

-L:定义本机对外提供什么服务
-F:定义流量通过哪个上游节点转发

例如:

gost -L http://:8080

表示在本机 8080 端口启动一个 HTTP 代理。

而下面这条命令:

gost \
  -L http://:8080 \
  -F socks5://192.168.1.10:1080

表示:

应用程序
   ↓ HTTP 代理
本机 GOST:8080
   ↓ SOCKS5
192.168.1.10:1080
   ↓
目标服务器

也就是说,-L 负责接收流量,-F 决定流量接下来走向哪里。

GOST 支持同时配置多个 -L,也支持多个 -F。多个 -F 会按照配置顺序组成多级代理链。

例如:

gost \
  -L http://:8080 \
  -F http://192.168.1.1:8080 \
  -F socks5://192.168.1.2:1080

它形成的链路是:

客户端
  ↓
本机 HTTP 代理
  ↓
第一级 HTTP 代理
  ↓
第二级 SOCKS5 代理
  ↓
目标服务器

二、协议与传输通道是分开的

GOST v3 一个很重要的设计是:代理协议和传输通道可以组合使用。

例如:

socks5+tls
http+tls
socks5+ws
socks5+wss
http+grpc

以:

socks5+tls://proxy.example.com:8443

为例,它可以拆成两部分:

socks5:代理协议
tls:数据传输通道

在 GOST 的内部架构中,SOCKS5 会被解析为 Connector,TLS 会被解析为 Dialer。换句话说,GOST 先通过 TLS 建立安全传输通道,再在这个通道内运行 SOCKS5 代理协议。

其通用 URL 可以理解为:

协议+传输方式://用户名:密码@主机:端口?参

例如:

socks5+tls://user:password@proxy.example.com:8443

这种协议与传输层分离的设计,是 GOST 灵活性的主要来源。


三、安装 GOST

GOST 官方提供二进制程序、源码编译和 Docker 镜像三种安装方式。

1. 查看版本

下载对应操作系统的 GOST v3 二进制文件后执行:

gost -V

使用前应当先确认版本,避免把 v2 命令误用到 v3。

2. 源码编译

git clone https://github.com/go-gost/gost.git
cd gost/cmd/gost
go build

3. Docker 运行

官方 Docker 镜像为:

gogost/gost

验证镜像:

docker run --rm gogost/gost -V

以上安装方式均来自 GOST 官方文档。


四、搭建 HTTP 代理

最简单的 HTTP 代理命令是:

gost -L http://:8080

此时 GOST 会监听:

0.0.0.0:8080

客户端可以这样测试:

curl -x http://服务器IP:8080 https://api.ipify.org

但这个代理没有认证,任何能够访问该端口的人都可以使用它,不应该直接暴露到公网。

加入用户名和密码:

gost -L http://gundy:StrongPassword@:8080

测试:

curl \
  -x http://gundy:StrongPassword@服务器IP:8080 \
  https://api.ipify.org

需要特别注意:这种方式只是增加了身份认证,HTTP 代理连接本身依然没有加密。官方也明确将其描述为“带用户认证的非加密 HTTP 代理”。

因此,普通 HTTP 代理更适合:

  • 本机使用;
  • 内网使用;
  • 已经由 VPN 或其他安全通道保护的网络;
  • 临时调试。

不适合直接作为公网长期代理服务。


五、搭建 SOCKS5 代理

启动一个带认证的 SOCKS5 代理:

gost -L socks5://gundy:StrongPassword@:1080

测试:

curl \
  --proxy socks5h://gundy:StrongPassword@服务器IP:1080 \
  https://api.ipify.org

这里建议使用:

socks5h

而不是:

socks5

区别在于 socks5h 会让代理服务器负责域名解析,可以避免客户端直接进行 DNS 查询。

GOST v3 的 SOCKS5 实现支持 CONNECT、BIND、UDP ASSOCIATE 和用户名密码认证。服务端的 UDP 中继默认没有开启,需要通过 udp=true 显式启用。

例如:

gost -L "socks5://gundy:StrongPassword@:1080?udp=true"

不过,UDP 转发比普通 TCP 代理更复杂。特别是在代理链场景中,上游节点也必须支持对应的 UDP 转发方式。GOST 的 HTTP 和 SOCKS5 上游通常需要显式开启 udp=true


六、使用 TLS 保护代理连接

如果代理需要通过公网传输,建议为代理增加 TLS。

服务器端

gost \
  -L "socks5+tls://gundy:StrongPassword@:8443?notls=true"

这里的:

socks5+tls

表示 SOCKS5 运行在 TLS 通道之上。

notls=true 并不是关闭外层 TLS,而是关闭 GOST SOCKS5 自身的协商加密,从而避免 SOCKS5 内层和 TLS 外层重复加密。官方的 SOCKS Over TLS 示例也采用了这种配置。

客户端

在本地启动一个普通 SOCKS5 入口:

gost \
  -L "socks5://127.0.0.1:1080?notls=true" \
  -F "socks5+tls://gundy:StrongPassword@proxy.example.com:8443?notls=true&secure=true&serverName=proxy.example.com"

本地软件只需要连接:

地址:127.0.0.1
端口:1080
协议:SOCKS5

完整链路如下:

浏览器或应用
      ↓
127.0.0.1:1080
      ↓
TLS 加密连接
      ↓
proxy.example.com:8443
      ↓
目标网站

其中:

secure=true

表示验证服务器证书和域名。

serverName=proxy.example.com

用于指定证书域名。

这一点非常重要,因为 GOST 客户端的 secure 默认值为 false。如果不启用证书验证,虽然流量经过了 TLS 加密,但客户端不能严格确认连接的就是预期服务器。


七、配置正式 TLS 证书

如果没有提供证书,GOST 会在每次运行时自动生成一个证书。自动生成的证书适合测试,但生产环境更适合配置受信任的正式证书。

假设当前目录中存在:

cert.pem
key.pem

可以运行:

gost \
  -L "socks5+tls://gundy:StrongPassword@:8443?notls=true&certFile=cert.pem&keyFile=key.pem"

也可以使用 YAML 配置文件:

services:
  - name: socks-tls
    addr: ":8443"

    handler:
      type: socks5
      auth:
        username: gundy
        password: StrongPassword
      metadata:
        notls: true

    listener:
      type: tls
      tls:
        certFile: cert.pem
        keyFile: key.pem

运行:

gost -C gost.yml

对于长期运行的生产服务,配置文件通常比超长命令行更适合,因为它更容易:

  • 纳入版本管理;
  • 进行配置审查;
  • 管理多个服务;
  • 配置日志、限速和访问控制;
  • 调整代理链和路由规则。

但真实密码不建议直接提交到公开代码仓库。


八、代理协议转换

GOST 很实用的一项能力是代理协议转换。

假设已有一个 SOCKS5 上游:

10.0.0.10:1080

但某个老旧程序只支持 HTTP 代理,可以运行:

gost \
  -L http://127.0.0.1:8080 \
  -F socks5://user:pass@10.0.0.10:1080

软件连接:

HTTP 代理:127.0.0.1:8080

GOST 会将流量转换成 SOCKS5 后发送给上游:

应用程序
   ↓ HTTP
本地 GOST
   ↓ SOCKS5
上游代理
   ↓
目标服务器

同样,也可以把远程 HTTP 代理转换成本地 SOCKS5:

gost \
  -L socks5://127.0.0.1:1080 \
  -F http://user:pass@代理服务器:8080

这类协议转换对于命令行工具、老旧软件、容器应用和只支持单一代理协议的程序非常有用。


九、TCP 端口转发

除了代理,GOST 也能进行普通 TCP 端口转发。

例如,将本机 3307 转发到:

10.0.0.5:3306

执行:

gost -L tcp://127.0.0.1:3307/10.0.0.5:3306

之后连接:

mysql -h 127.0.0.1 -P 3307

实际链路为:

MySQL 客户端
     ↓
127.0.0.1:330710.0.0.5:3306

官方的 TCP 本地转发语法为:

gost -L tcp://监听地址/目标地址

对应的 UDP 转发则是:

gost -L udp://:10053/192.168.1.1:53

GOST 将端口转发划分为 TCP、UDP,以及本地转发和远程转发,共四种组合。


十、通过代理链访问内网服务

端口转发还可以与 -F 代理链组合。

假设:

本机无法直接访问:10.0.0.5:3306
SOCKS5 跳板机:192.168.1.2:1080

可以运行:

gost \
  -L tcp://127.0.0.1:3307/10.0.0.5:3306 \
  -F socks5://192.168.1.2:1080

链路变成:

本地 MySQL 客户端
       ↓
127.0.0.1:3307
       ↓
SOCKS5 跳板机
       ↓
10.0.0.5:3306

这个场景非常适合:

  • 通过堡垒机连接数据库;
  • 访问测试环境 Redis;
  • 转发内网 SSH;
  • 访问只能从特定网络进入的管理后台;
  • 为不支持代理的软件增加代理能力。

十一、远程端口转发与内网穿透

本地端口转发解决的是:

本机端口 → 远程服务

远程端口转发解决的是:

远程服务器端口 → 本地或内网服务

GOST 的远程 TCP 转发使用:

rtcp

例如:

gost \
  -L "rtcp://:2222/:22" \
  -F "socks5://公网服务器:1080"

其目标是让公网代理节点监听 2222,再把流量转回客户端所在机器的 22 端口。GOST 官方快速入门文档提供了相同模式的远程 TCP 转发示例。

不过,使用 SOCKS5 进行远程转发时,上游 SOCKS5 服务需要启用 BIND:

gost -L "socks5://user:pass@:1080?bind=true"

远程转发中的监听位置和数据方向比本地转发更容易混淆,生产环境部署前应当先明确:

入口端口监听在哪台服务器?
目标服务运行在哪台机器?
哪一端主动建立隧道?
公网是否需要开放入口端口?

对于复杂的内网穿透,GOST v3 还提供了反向代理隧道。官方将这种模式描述为类似 Cloudflare Tunnel 的增强型反向代理方案:服务端提供公网入口,客户端主动建立隧道,入口流量再通过隧道发送到客户端。每个隧道使用唯一 ID,并可建立多个连接形成连接池。


十二、使用 Docker 部署 SOCKS5 TLS 代理

一个简单的 Docker 部署命令如下:

docker run -d \
  --name gost \
  --restart unless-stopped \
  -p 8443:8443 \
  gogost/gost \
  -L "socks5+tls://gundy:StrongPassword@:8443?notls=true"

查看日志:

docker logs -f --tail 100 gost

查看容器状态:

docker ps --filter name=gost

测试端口:

nc -vz 服务器IP 8443

使用 Docker Compose 可以写成:

services:
  gost:
    image: gogost/gost
    container_name: gost
    restart: unless-stopped

    ports:
      - "8443:8443"

    command:
      - "-L"
      - "socks5+tls://gundy:StrongPassword@:8443?notls=true"

启动:

docker compose up -d

需要注意,Docker Compose 文件中的密码可能被读取,因此更合理的做法是限制文件权限,并使用独立的配置管理或密钥管理方案。


十三、生产环境安全建议

1. 不要暴露无认证代理

下面这种配置不应直接暴露到公网:

gost -L socks5://:1080

否则服务器可能变成任何人都能使用的开放代理,进而导致:

  • 带宽被大量消耗;
  • IP 被滥用;
  • 服务器参与扫描或攻击;
  • 云服务商封禁实例;
  • 日志和合规风险增加。

2. 认证不等于加密

下面的 HTTP 代理虽然有密码:

gost -L http://user:pass@:8080

但传输通道没有加密。

公网环境更适合:

HTTP/SOCKS5 + TLS

3. 开启证书校验

客户端使用 TLS 上游时建议配置:

secure=true
serverName=代理域名

不要只追求“能连接”,还要确认连接的是正确服务器。

4. 使用防火墙限制来源

如果代理只供固定 IP 使用,可以通过 UFW 限制:

sudo ufw allow from 客户端公网IP to any port 8443 proto tcp

不要直接:

sudo ufw allow 8443/tcp

除非确实需要向整个互联网开放。

5. 监听地址遵循最小暴露原则

只供本机使用:

gost -L socks5://127.0.0.1:1080

需要对外提供服务时才监听:

0.0.0.0

6. 密码包含特殊字符时进行 URL 编码

用户名和密码位于 URL 中。

如果密码包含:

@
:
?
#
&

可能导致 URL 解析异常,应当进行百分号编码,或者改用 YAML 配置文件。

7. 记录必要日志,但避免泄露敏感信息

生产环境应记录:

  • 连接时间;
  • 来源地址;
  • 错误信息;
  • 流量异常;
  • 认证失败。

但不要把明文密码、令牌或其他敏感参数写入公开日志。


十四、GOST 与其他工具有什么区别

GOST 与 Nginx

Nginx 更擅长:

  • HTTP/HTTPS 反向代理;
  • 域名路由;
  • 静态资源;
  • Web 负载均衡;
  • TLS 终止。

GOST 更擅长:

  • SOCKS5;
  • TCP/UDP 转发;
  • 多级代理链;
  • 协议转换;
  • 隧道和内网穿透。

如果只是部署网站,优先考虑 Nginx。

如果需要处理任意 TCP/UDP 流量,或者组合多种代理协议,GOST 更灵活。

GOST 与 SSH Tunnel

SSH Tunnel 的优势是系统普遍自带、配置简单、安全模型成熟,适合少量临时端口转发。

GOST 更适合:

  • 多协议;
  • 多入口;
  • 多级代理;
  • SOCKS5 和 HTTP 转换;
  • UDP;
  • 复杂隧道。

GOST 与 FRP

FRP 的核心方向是内网穿透和服务暴露。

GOST 的覆盖面更广,除了内网穿透,还包含代理服务、协议转换、代理链和通用端口转发。

GOST 与 Clash 类工具

Clash 类工具更偏向客户端流量管理、规则分流和代理节点选择。

GOST 更偏向网络基础设施:

  • 搭建代理服务;
  • 转发端口;
  • 构造隧道;
  • 转换协议;
  • 连接多个网络节点。

二者也可以配合使用,例如由 Clash 负责规则分流,再把部分流量交给 GOST 提供的本地 SOCKS5 入口。


十五、如何快速读懂一条 GOST 命令

看到下面这条命令:

gost \
  -L socks5://127.0.0.1:1080 \
  -F "socks5+tls://user:pass@proxy.example.com:8443?notls=true&secure=true"

可以分成三步理解。

第一步,找到 -L

本机提供一个 SOCKS5 代理
监听 127.0.0.1:1080

第二步,找到 -F

流量交给 proxy.example.com:8443

第三步,拆解协议:

socks5:上游代理协议
tls:上游传输通道
user:pass:认证信息
secure=true:验证服务器证书

最终数据流就是:

本地应用
   ↓ SOCKS5
127.0.0.1:1080
   ↓ SOCKS5 over TLS
proxy.example.com:8443
   ↓
目标服务器

掌握这个分析方法后,大多数 GOST 命令都可以快速读懂。


结语

GOST 并不是单纯的 SOCKS5 代理工具,也不仅仅是一个端口转发工具。

它真正的价值在于,将以下能力统一到了一套模型中:

本地服务
   +
代理协议
   +
传输通道
   +
上游代理链
   +
最终转发目标

其中最值得记住的三个规则是:

-L 决定本机接收什么流量
-F 决定流量经过哪些上游节点
/ 后面的地址决定端口转发的最终目标

对于开发者和运维人员来说,GOST 尤其适合临时网络调试、协议转换、数据库转发、远程代理、多级跳板、内网服务暴露等场景。

但功能越灵活,安全配置就越重要。公网部署时,应当至少做好身份认证、TLS 加密、证书校验、防火墙限制和日志审计,避免将服务器变成没有访问控制的开放代理。