你的位置:首页 > 互联网IT

gost,gost3,gost-v3,gost3配置文件教材,http代理,socks5代理,转发端口,shadowsocks代理,SS代理,负载均衡,中转服务,端口映射,gost3命令教材,教程,TLS设置,HTTP通道

系统:Windows/linux

软件:gost v3.0

功能:http代理,socks5代理,转发端口,shadowsocks代理,SS代理,负载均衡,中转服务,端口映射

官网:https://gost.run/

项目地址:https://github.com/go-gost/gost

gost-v3-beta.6(使用很久,稳定版本)

本地下载1-Windows-32位:gost-windows-386-3.0.0-beta.6.zip

本地下载2-Windows-64位:gost-windows-amd64-3.0.0-beta.6.zip

本地下载3-linux-32位:gost-linux-386-3.0.0-beta.6.gz

本地下载4-linux-64位:gost-linux-amd64-3.0.0-beta.6.gz

gost-v3.0.0-rc8

本地下载5-Windows-32位:gost_3.0.0-rc8_windows_386.zip

本地下载6-Windows-64位:gost_3.0.0-rc8_windows_amd64.zip

本地下载7-linux-32位:gost_3.0.0-rc8_linux_386.tar.gz

本地下载8-linux-64位:gost_3.0.0-rc8_linux_amd64.tar.gz

项目地址下载地址:https://github.com/go-gost/gost/releases


本文内容:教程,TLS设置,HTTP通道,端口转发,反向代理,反向代理隧道,反向代理隧道-高可用,HTTP文件服务


gost,gost3,gost-v3版本-配置文件文章

https://www.zhuguodong.com/?id=771


gost,gost3,gost-v3版本-命令文章

https://www.zhuguodong.com/?id=767


同类型gost-v2.0(gost2)版本

https://www.zhuguodong.com/?id=700


-----------------------------------------------------------


Windows隐藏运行软件,cmd隐藏运行,bat隐藏运行,命令窗口隐藏运行

https://www.zhuguodong.com/?id=520


linux隐藏运行软件

nohup /root/gost -L ss://aes-256-cfb:123456@:23333 >/dev/null 2>&1 &

nohup 《内容替换》 >/dev/null 2>&1 &


-----------------------------------------------------------


简单配置运行:

Windows:新建 gost.bat 文件

linux:命令窗口隐藏运行,gost要加入权限:chmod +x gost


启动参数:-c

Windows:start "" "gost.exe" -C gost.yaml

linux:gost -C gost.yaml


说明:.yaml配置文件不能有空行,或者不必要的空格,不然会运行不成功


启动参数:-c

Windows:start "" "gost.exe" -C gost.json

linux:gost -C gost.json

程序gost与文件同一目录下,说明:.json与.yaml配置文件格式(这个文件格式配置不能出现空格),教材就用.json格式演示


配置.json与.yaml格式可相互转换的


输出yaml格式配置

gost -L http://:8080 -O yaml


输出json格式配置

gost -L http://:8080 -O json


将json格式配置转成yaml格式

gost -C gost.json -O yaml

gost -C gost.yaml -O json


 gost,gost3,gost-v3,gost3配置文件教材,http代理,socks5代理,转发端口,shadowsocks代理,SS代理,负载均衡,中转服务,端口映射,gost3命令教材,教程,T 互联网IT

-----------------------------------------------------------

TLS¶


GOST有三种类型TLS证书:自生成证书,全局证书,服务层级证书。


自生成证书¶


GOST在每次运行时自动生成TLS证书,如果未指定任何证书,会使用此证书作为默认证书。


自定义证书信息¶



命令行

命令行模式下暂不支持设置全局证书。

validity (duration, default=8760h)

证书有效期,默认1年。

commonName (string, default=gost.run)

证书CN信息。

organization (string, default=GOST)

证书的Organization信息。

配置文件

tls:

  validity: 8760h

  commonName: gost.run

  organization: GOST

validity (duration, default=8760h)

证书有效期,默认1年。

commonName (string, default=gost.run)

证书CN信息。

organization (string, default=GOST)

证书的Organization信息。

全局证书¶


全局证书默认使用自动生成的证书,也可以通过配置指定自定义证书文件。



命令行

命令行模式下暂不支持设置全局证书。

配置文件

tls:

  certFile: "cert.pem"

  keyFile: "key.pem"

  caFile: "ca.pem"

提示

GOST会自动加载当前工作目录下的cert.pem, key.pem, ca.pem文件来初始化全局证书。


服务层级证书¶


每个服务的监听器和处理器可以分别设置各自的证书,默认使用全局证书。



命令行

gost -L http+tls://:8443?certFile=cert.pem&keyFile=key.pem&caFile=ca.pem

配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: http

  listener:

    type: tls

    tls:

      certFile: cert.pem

      keyFile: key.pem

      caFile: ca.pem

客户端设置¶


客户端可以对每个节点的拨号器和连接器分别设置证书。



命令行

gost -L http://:8080 -F tls://IP_OR_DOMAIN:8443?secure=true&serverName=www.example.com

配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.1:8443

      connector:

        type: http

      dialer:

        type: tls

        tls:

          secure: true

          serverName: www.example.com

caFile (string)

CA证书文件路径。设置CA证书将会开启证书锁定(Certificate Pinning)。

secure (bool, default=false)

开启服务器证书和域名校验。

serverName (string)

若secure设置为true,则需要通过此参数指定服务器域名用于域名校验。默认使用设置中IP_OR_DOMAIN作为serverName。

TLS选项¶


services:

- name: service-0

  addr: :8443

  handler:

    type: http

  listener:

    type: tls

    tls:

      options:

        minVersion: VersionTLS12

        maxVersion: VersionTLS13

        cipherSuites:

        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

minVersion (string)

TLS最小版本,可选值VersionTLS10,VersionTLS11,VersionTLS12,VersionTLS13。

maxVersion (string)

TLS最大版本,可选值VersionTLS10,VersionTLS11,VersionTLS12,VersionTLS13。

cipherSuites (list)

加密套件,可选值参考Cipher Suites。

双向证书校验¶


如果服务端设置了CA证书,则会对客户端证书进行强制校验,此时客户端须提供证书。



命令行

gost -L http://:8080 -F tls://IP_OR_DOMAIN:8443?certFile=cert.pem&keyFile=key.pem

配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.1:8443

      connector:

        type: http

      dialer:

        type: tls

        tls:

          certFile: cert.pem

          keyFile: key.pem

注意

通过命令行设置的证书信息仅会应用到监听器或拨号器上。


-----------------------------------------------------------


HTTP数据通道¶


HTTP是目前互联网上使用最广泛的一种数据交换协议,随着互联网的发展,协议也进行了几次重大的版本升级,从最原始的HTTP/1到HTTP/2,再到现在的基于QUIC协议的HTTP/3。


原始HTTP协议是一种请求响应式的交互方式,由客户端主动发起请求,服务端收到请求后再将处理结果发送回客户端,这种方式无法在客户端和服务端之间保持长连接,因此很难做到双向实时数据传输。为了实现全双工通信,HTTP协议又进行了多种扩展,例如增加CONNECT方法,Websocket扩展协议,HTTP/2的服务端推送和HTTP/3的WebTransport等。GOST已经支持了以上大部分的功能。


注意

CONNECT方法用于HTTP建立代理连接,严格来说不能称之为数据通道,然而其本质都是建立了可以双向通讯的长连接,所以在这里统一被当作数据通道。


HTTP CONNECT方法¶


服务端¶



命令行

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


配置文件

services:

- name: service-0

  addr: ":8080"

  handler:

    type: http

    auth:

      username: user

      password: pass

  listener:

    type: tcp

以上是一个最简单的带有认证功能的HTTP代理服务。


客户端¶



命令行

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


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8080

      connector:

        type: http

        auth:

          username: user

          password: pass

      dialer:

        type: tcp

客户端本身也是一个HTTP代理服务,并通过转发链将请求转发给上面的HTTP代理服务。


Plain HTTP Tunnel(pht)¶


CONNECT方法并不是所有服务都支持,为了尽可能通用,GOST利用原始HTTP协议中的GET和POST方法来实现数据通道,包括加密的phts和明文的pht两种模式。


服务端¶



命令行

gost -L relay+pht://:8080?authorizePath=/authorize&pushPath=/push&pullPath=/pull

gost -L relay+phts://:8080


配置文件

services:

- name: service-0

  addr: ":8080"

  handler:

    type: relay

  listener:

    type: pht

    # type: phts

    metadata:

      authorizePath: /authorize

      pullPath: /pull

      pushPath: /push

客户端¶



命令行

gost -L http://:8000 -F relay+pht://:8080?authorizePath=/authorize&pushPath=/push&pullPath=/pull

gost -L http://:8000 -F relay+phts://:8080

配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8080

      connector:

        type: relay

      dialer:

        type: pht

        # type: phts

        metadata:

          authorizePath: /authorize

          pullPath: /pull

          pushPath: /push

Caution

PHT是一个实验性功能,还在不断完善中。


Websocket¶


Websocket是HTTP/1中为了建立长连接而增加的扩展协议。


服务端¶



命令行

gost -L socks5+ws://user:pass@:1080


配置文件

services:

- name: service-0

  addr: ":1080"

  handler:

    type: socks5

    auth:

      username: user

      password: pass

  listener:

    type: ws

客户端¶



命令行

gost -L http://:8000 -F socks5+ws://user:pass@:1080


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :1080

      connector:

        type: socks5

        auth:

          username: user

          password: pass

      dialer:

        type: ws

注意

这里的认证信息设置的是SOCKS5代理的认证,Websocket暂不支持认证设置。


HTTP/2¶


GOST中HTTP/2有两种使用方式,代理模式和标准数据通道模式。


HTTP/2 CONNECT方法¶


HTTP/2使用与HTTP相同的CONNECT方法实现代理模式。


服务端¶



命令行

gost -L http2://user:pass@:8443


配置文件

services:

- name: service-0

  addr: ":8443"

  handler:

    type: http2

    auth:

      username: user

      password: pass

  listener:

    type: http2

客户端¶



命令行

gost -L http://:8000 -F http2://user:pass@:8443


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: http2

        auth:

          username: user

          password: pass

      dialer:

        type: http2

HTTP/2数据通道¶


HTTP/2做为数据通道可以使用加密(h2)和明文(h2c)两种模式。


服务端¶



命令行

gost -L socks5+h2://user:pass@:8443

gost -L socks5+h2c://user:pass@:8443

配置文件

services:

- name: service-0

  addr: ":8443"

  handler:

    type: socks5

    auth:

      username: user

      password: pass

  listener:

    type: h2

    # type: h2c

客户端¶



命令行

gost -L http://:8000 -F socks5+h2://user:pass@:8443

gost -L http://:8000 -F socks5+h2c://user:pass@:8443

配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: socks5

        auth:

          username: user

          password: pass

      dialer:

        type: h2

        # type: h2c

服务端推送

GOST不支持HTTP/2的服务端推送功能。


gRPC¶


gRPC是基于HTTP/2,因此具有HTTP/2本身固有的优点,另外gRPC天然的支持双向流传输,因此很适合作为数据通道。


服务端¶



命令行

gost -L relay+grpc://user:pass@:8443


配置文件

services:

- name: service-0

  addr: ":8443"

  handler:

    type: relay 

    auth:

      username: user

      password: pass

  listener:

    type: grpc

客户端¶



命令行

gost -L http://:8000 -F relay+grpc://user:pass@:8443


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: relay

        auth:

          username: user

          password: pass

      dialer:

        type: grpc

gRPC默认使用TLS加密,可以通过设置grpcInsecure参数使用明文进行通讯。


服务端¶



命令行

gost -L relay+grpc://user:pass@:8443?grpcInsecure=true


配置文件

services:

- name: service-0

  addr: ":8443"

  handler:

    type: relay 

    auth:

      username: user

      password: pass

  listener:

    type: grpc

    metadata:

      grpcInsecure: true

客户端¶



命令行

gost -L http://:8000 -F relay+grpc://user:pass@:8443?grpcInsecure=true


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: relay

        auth:

          username: user

          password: pass

      dialer:

        type: grpc

        metadata:

          grpcInsecure: true

HTTP/3¶


HTTP/3协议规范中支持CONNECT方法和WebTransport两种方式建立数据通道。


GOST目前不支持以上两种方式,而是通过在HTTP/3之上利用pht来建立数据通道。


WebTransport

WebTransport目前处在早期草案阶段,待时机成熟后GOST会添加对其的支持。


服务端¶



命令行

gost -L "h3://:8443?authorizePath=/authorize&pushPath=/push&pullPath=/pull"


配置文件

services:

- name: service-0

  addr: ":8443"

  handler:

    type: auto

  listener:

    type: h3

    metadata:

      authorizePath: /authorize

      pullPath: /pull

      pushPath: /push

客户端¶



命令行

gost -L http://:8000 -F h3://:8443?authorizePath=/authorize&pushPath=/push&pullPath=/pull


配置文件

services:

- name: service-0

  addr: ":8000"

  handler:

    type: http

    chain: chain-0

  listener:

    type: tcp

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: http

      dialer:

        type: h3

        metadata:

          authorizePath: /authorize

          pullPath: /pull

          pushPath: /push


-----------------------------------------------------------


端口转发¶


端口转发根据协议类型分为TCP和UDP端口转发,根据转发类型又分为本地转发和远程转发,总共有四种组合。


本地端口转发¶


TCP¶


可以设置单一的转发目标地址进行一对一端口转发



命令行1

gost -L tcp://:8080/:80


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: tcp

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

将本地的TCP端口8080映射到192.168.1.1的80端口,所有到本地8080端口的数据会被转发到192.168.1.1:80。


也可以设置多个目标地址进行一对多端口转发



命令行

gost -L tcp://:8080/192.168.1.1:80,192.168.1.2:80,192.168.1.3:8080?strategy=round&maxFails=1&failTimeout=30s


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: tcp

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

    - name: target-1

      addr: 192.168.1.2:80

    - name: target-1

      addr: 192.168.1.3:8080

    selector:

      strategy: round

      maxFails: 1

      failTimeout: 30s

在每次收到转发请求后,会利用转发器中的节点选择器在目标地址列表中选择一个节点作为本次转发的目标地址。


UDP¶


和TCP端口转发类似,也可以指定单个和多个目标转发地址。



命令行

gost -L udp://:10053/192.168.1.1:53,192.168.1.2:53,192.168.1.3:53?keepAlive=true&ttl=5s


配置文件

services:

- name: service-0

  addr: :10053

  handler:

    type: udp

  listener:

    type: udp

    metadata:

      keepAlive: true

      ttl: 5s

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:53

    - name: target-1

      addr: 192.168.1.2:53

    - name: target-2

      addr: 192.168.1.3:53

每一个客户端对应一条转发通道,当keepAlive参数设置为false时(默认情况),请求的响应数据返回给客户端后会立即关闭通道连接。


当keepAlive参数设置为true时,转发服务一定时间内收不到转发目标主机数据,此转发通道会被标记为空闲状态。转发服务内部会按照ttl参数(默认值5秒)指定的周期检查转发通道是否空闲,如果空闲则此通道将被关闭。一个空闲通道最多会在两个检查周期内被关闭。


转发链¶


端口转发可以配合转发链进行间接转发。



命令行

gost -L=tcp://:8080/192.168.1.1:80 -F socks5://192.168.1.2:1080


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: tcp

    chain: chain-0

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:1080

      connector:

        type: socks5

      dialer:

        type: tcp

将本地的TCP端口8080通过转发链映射到192.168.1.1的80端口。



命令行

gost -L=udp://:10053/192.168.1.1:53 -F socks5://192.168.1.2:1080


配置文件

services:

- name: service-0

  addr: :10053

  handler:

    type: udp

    chain: chain-0

  listener:

    type: udp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:53

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:1080

      connector:

        type: socks5

      dialer:

        type: tcp

将本地的UDP端口10053通过转发链映射到192.168.1.1的53端口。


限制

当UDP本地端口转发中使用转发链时,转发链末端最后一个节点必须是以下类型:


GOST HTTP代理服务并开启了UDP转发功能,采用UDP-over-TCP方式。

gost -L http://:8080?udp=true

GOST SOCKS5代理服务并开启了UDP转发功能,采用UDP-over-TCP方式。

gost -L socks5://:1080?udp=true

Relay服务,采用UDP-over-TCP方式。

SSU服务。

UDP-over-TCP

UDP-over-TCP是指使用TCP连接来传输UDP数据包。在GOST中这个说法可能并不太准确,例如使用SOCKS5进行UDP端口转发,SOCKS5服务可以是基于TCP类型的传输通道(TLS, Websocket等),也可以是基于UDP类型的传输通道(KCP, QUIC等),这里使用UDP-over-Stream更合适一些(相对于UDP不可靠的数据报式传输来说),任何可靠的流式传输协议均可以用在此处。


SSH¶


TCP端口转发可以借助于标准SSH协议的端口转发功能进行间接转发



命令行

gost -L=tcp://:8080/192.168.1.1:80 -F sshd://user:pass@192.168.1.2:22


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: tcp

    chain: chain-0

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:22

      connector:

        type: sshd

      dialer:

        type: sshd

        auth:

          username: user

          password: pass

这里的192.168.1.2:22服务可以是系统本身的标准SSH服务,也可以是GOST的sshd类型服务



命令行

gost -L sshd://user:pass@:22


配置文件

services:

- name: service-0

  addr: :22

  handler:

    type: sshd

  listener:

    type: sshd

    auth:

      username: user

      password: pass

远程端口转发¶


TCP¶



命令行

gost -L rtcp://:8080/192.168.1.1:80


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: rtcp

  listener:

    type: rtcp

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

将本地的TCP端口8080映射到192.168.1.1的80端口,所有到本地8080端口的数据会被转发到192.168.1.1:80。


UDP¶



命令行

gost -L rudp://:10053/192.168.1.1:53,192.168.1.2:53,192.168.1.3:53?ttl=5s


配置文件

services:

- name: service-0

  addr: :10053

  handler:

    type: rudp

  listener:

    type: rudp

    metadata:

      ttl: 5s

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:53

    - name: target-1

      addr: 192.168.1.2:53

    - name: target-2

      addr: 192.168.1.3:53

注意

在不使用转发链的情况下,远程端口转发与本地端口转发没有区别。


转发链¶



命令行

gost -L=rtcp://:8080/192.168.1.1:80 -F socks5://192.168.1.2:1080


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:1080

      connector:

        type: socks5

      dialer:

        type: tcp

根据rtcp服务指定的地址,通过转发链在主机192.168.1.2上监听8080TCP端口。当收到请求后再通过转发链将数据转发给rtcp服务,rtcp服务再将请求转发到192.168.1.1:80端口。



命令行

gost -L=rudp://:10053/192.168.1.1:53 -F socks5://192.168.1.2:1080


配置文件

services:

- name: service-0

  addr: :10053

  handler:

    type: rudp

  listener:

    type: rudp

    chain: chain-0

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:53

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:1080

      connector:

        type: socks5

      dialer:

        type: tcp

根据rudp服务指定的地址,通过转发链在主机192.168.1.2上监听10053端口。当收到请求后再通过转发链将数据转发给rudp服务,rudp服务再将请求转发到192.168.1.1:53端口。


注意

远程端口转发上的转发链默认设置在监听器上,此时处理器上也可以再设置另外的转发链。


远程端口转发服务中的监听地址,在使用转发链时将监听在转发链末端最后一个节点服务所在的主机上。


限制

当远程端口转发中使用转发链时,转发链末端最后一个节点必须是以下类型:


GOST SOCKS5代理服务并开启了BIND功能,采用UDP-over-TCP方式。

gost -L socks5://:1080?bind=true

Relay服务并开启了BIND功能,采用UDP-over-TCP方式。

gost -L relay://:8421?bind=true

SSH¶


TCP远程端口转发可以借助于标准SSH协议的远程端口转发功能进行间接转发



命令行

gost -L=rtcp://:8080/192.168.1.1:80 -F sshd://user:pass@192.168.1.2:22


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: 192.168.1.2:22

      connector:

        type: sshd

      dialer:

        type: sshd

        auth:

          username: user

          password: pass

这里的192.168.1.2:22服务可以是系统本身的标准SSH服务,也可以是GOST的sshd类型服务。


服务端转发¶


以上的转发方式可以看作是客户端转发,由客户端来控制转发的目标地址。目标地址也可以由服务端指定。


服务端¶



命令行

gost -L tls://:8443/192.168.1.1:80


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: forward

  listener:

    type: tls

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

客户端¶



命令行

gost -L=tcp://:8080 -F forward+tls://:8443


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: tcp

  listener:

    type: tcp

    chain: chain-0

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: forward

      dialer:

        type: tls

forward类型连接器和处理器

这里服务的处理器和转发链的连接器必须为forward类型,由于目标地址由服务端指定,因此客户端无需指定目标地址。forward连接器不做任何逻辑处理。


这里的tcp://:8080等同于tcp://:8080/:0,转发目标地址:0在这里作为占位符。仅当配合forward连接器使用时,这种用法才是有效的。


-----------------------------------------------------------


反向代理¶


反向代理是代理服务的一种。服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器集群的存在。


GOST中的端口转发服务也可以被当作是一种功能受限的反向代理,因其只能转发到固定的一个或一组后端服务。


反向代理是端口转发服务的一个扩展,其依托于端口转发功能,并通过嗅探转发的数据来获取特定协议(目前支持HTTP/HTTPS)中的目标主机信息。


关于反向代理更详细的说明可以参考这篇博文。


本地端口转发¶


services:

- name: https

  addr: :443

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: google

      addr: www.google.com:443

      host: www.google.com

    - name: github

      addr: github.com:443

      host: "*.github.com"

      # host: .github.com

- name: http

  addr: :80

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:80

      host: example.com

    - name: example-org

      addr: example.org:80

      host: example.org

通过sniffing选项来开启流量嗅探,并在forwarder.nodes中通过host选项可以对每一个节点设置(虚拟)主机名。


当开启流量嗅探后,转发服务会通过客户端的请求数据获取访问的目标主机,再通过转发器(forwarder)中的节点设置的虚拟主机名(node.host)找到最终转发的目标地址(node.addr)。


Reverse Proxy - TCP Port Forwarding


node.host也支持通配符,*.example.com或.example.com匹配example.com及其子域名:abc.example.com,def.abc.example.com等。


此时可以将对应的域名解析到本地通过反向代理来访问:


curl --resolve www.google.com:443:127.0.0.1 https://www.google.com

curl --resolve example.com:80:127.0.0.1 http://example.com

远程端口转发¶


远程端口转发服务同样也可以对流量进行嗅探。


services:

- name: https

  addr: :443

  handler:

    type: rtcp

    metadata:

      sniffing: true

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: local-0

      addr: 192.168.1.1:443

      host: srv-0.local

    - name: local-1

      addr: 192.168.1.2:443

      host: srv-1.local

    - name: fallback

      addr: 192.168.2.1:443

- name: http

  addr: :80

  handler:

    type: rtcp

    metadata:

      sniffing: true

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: local-0

      addr: 192.168.1.1:80

      host: srv-0.local

    - name: local-1

      addr: 192.168.1.2:80

      host: srv-1.local

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: SERVER_IP:8443 

      connector:

        type: relay

      dialer:

        type: wss

通过sniffing选项来开启流量嗅探,并在forwarder.nodes中通过host选项可以对每一个节点设置(虚拟)主机名。


Reverse Proxy - Remote TCP Port Forwarding


此时可以将对应的域名解析到服务器地址通过反向代理来访问内网服务:


curl --resolve srv-0.local:443:SERVER_IP https://srv-0.local

curl --resolve srv-1.local:80:SERVER_IP http://srv-1.local

如果访问的目标主机没有与转发器中的节点设定的主机名匹配上,当存在没有设置主机名的节点,则会在这些节点中选择一个使用。


curl --resolve srv-2.local:443:SERVER_IP https://srv-2.local

由于srv-2.local没有匹配到节点,因此会被转发到fallback节点(192.168.2.1:443)。


HTTP请求头设置¶


当嗅探到HTTP流量时,可以在目标节点上通过forwarder.nodes.http选项对HTTP的请求头部信息进行设置,包括Host头重写和自定义头部信息,对本地和远程端口转发均适用。


重写Host头¶


通过设置http.host选项可以重写原始请求头中的Host。


services:

- name: http

  addr: :80

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:80

      host: example.com

      http:

        host: test.example.com

    - name: example-org

      addr: example.org:80

      host: example.org

      http:

        host: test.example.org:80

curl --resolve example.com:80:127.0.0.1 http://example.com

当请求http://example.com时,最终发送给example.com:80的HTTP请求头中Host为test.example.com。


自定义头¶


通过设置http.header选项可以自定义头部信息,如果所设置的头部字段已存在则会被覆盖。


services:

- name: http

  addr: :80

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:80

      host: example.com

      http:

        header:

          User-Agent: gost/3.0

          foo: bar

          bar: 123

        # host: test.example.com

    - name: example-org

      addr: example.org:80

      host: example.org

      http:

        header:

          User-Agent: curl/7.81.0

          foo: bar

          bar: baz

        # host: test.example.org:80

当请求http://example.com时,最终发送给example.com:80的HTTP请求头中将会添加User-Agent,Foo和Bar三个字段。


TLS请求设置¶


如果转发的目标节点启用了TLS,可以通过设置forwarder.nodes.tls来建立TLS连接。


services:

- name: http

  addr: :80

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:443

      host: example.com

      tls:

        secure: true

        serverName: example.com

tls.secure (bool, default=false)

是否开启服务器证书和域名校验。

tls.serverName (string)

若secure设置为true,则需要通过此参数指定服务器域名用于域名校验。

HTTP Basic Authentication¶


可以通过设置forwarder.nodes.auth选项为目标节点启用HTTP基本认证功能。


services:

- name: http

  addr: :80

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:443

      host: example.com

      auth:

        username: user

        password: pass

特定应用转发¶


本地和远程端口转发服务也支持对特定的应用流量嗅探。目前支持的应用协议有:SSH。


SSH¶


在forwarder.nodes中通过protocol选项指定节点协议类型为ssh,当嗅探到SSH协议流量则会转发到此节点。



本地端口转发

services:

- name: https

  addr: :443

  handler:

    type: tcp

    metadata:

      sniffing: true

  listener:

    type: tcp

  forwarder:

    nodes:

    - name: ssh-server

      addr: example.com:22

      protocol: ssh

远程端口转发

services:

- name: https

  addr: :443

  handler:

    type: rtcp

    metadata:

      sniffing: true

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: local-ssh

      addr: 192.168.2.1:22

      protocol: ssh

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: SERVER_IP:8443 

      connector:

        type: relay

      dialer:

        type: wss

优先级

当同时设置了host和protocol选项,仅会按host进行匹配。


转发通道¶


除了原始TCP数据通道可以用来作为端口转发,其他数据通道也可以作为端口转发服务。


TLS转发通道¶


HTTPS-to-HTTP反向代理。


TLS转发通道可以动态的给后端HTTP服务添加TLS支持。


services:

- name: https

  addr: :443

  handler:

    type: forward

    metadata:

      sniffing: true

  listener:

    type: tls

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:80

      host: .example.com

    - name: example-org

      addr: example.org:80

      host: .example.org

curl -k --resolve example.com:443:127.0.0.1 https://example.com

HTTP3转发通道¶


HTTP3-to-HTTP反向代理。


HTTP3转发通道可以动态的给后端HTTP服务添加HTTP/3支持。


services:

- name: http3

  addr: :443

  handler:

    type: http3

  listener:

    type: http3

  forwarder:

    nodes:

    - name: example-com

      addr: example.com:80

      host: .example.com

    - name: example-org

      addr: example.org:80

      host: .example.org

curl -k --http3 --resolve example.com:443:127.0.0.1 https://example.com


-----------------------------------------------------------


反向代理隧道¶


在上一篇反向代理教程中,利用端口转发实现了简单的反向代理功能,在本篇中将利用隧道服务实现类似于Cloudflare Tunnel的增强版反向代理。


隧道(Tunnel)¶


隧道是一条服务端和客户端之间的(逻辑上的)通道,服务端可以开启一个额外的公共入口点(EntryPoint),由入口点进入的流量会通过隧道发送给客户端。每个隧道有一个唯一的ID(合法的UUID),一个隧道可以有多个连接(连接池)来实现隧道的高可用性。


Reverse Proxy - Remote TCP Port Forwarding


服务端¶



命令行

gost -L "tunnel://:8443?entrypoint=:80&tunnel=.example.com:4d21094e-b74c-4916-86c1-d9fa36ea677b,example.org:ac74d9dd-3125-442a-a7c1-f9e49e05faca"


配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: tunnel

    metadata:

      entrypoint: ":80"

      ingress: ingress-0

  listener:

    type: tcp


ingresses:

- name: ingress-0

  rules:

  - hostname: ".example.com"

    endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

  - hostname: "example.org"

    endpoint: ac74d9dd-3125-442a-a7c1-f9e49e05faca

通过entrypoint选项指定流量的公共入口点,同时通过ingress选项指定Ingress对象来定义流量路由规则。


隧道ID分配

如果使用了Ingress,隧道将通过(虚拟)主机名进行路由,隧道的ID应当由服务端提前分配并记录在Ingress中。如果客户端使用了一个未在Ingress中注册的隧道ID,则流量无法路由到此客户端。


客户端¶



命令行

gost -L rtcp://:0/192.168.1.1:80 -F tunnel://:8443?tunnel.id=4d21094e-b74c-4916-86c1-d9fa36ea677b


配置文件

services:

- name: service-0

  addr: :0

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: target-0

      addr: 192.168.1.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: 4d21094e-b74c-4916-86c1-d9fa36ea677b

      dialer:

        type: tcp

通过tunnel.id指定隧道ID,此时rtcp服务中指定的addr参数无效。


本例中当流量进入公共入口点(服务端的80端口)后会嗅探流量信息获取所要访问的主机名,再通过主机名在Ingress中找到匹配的规则,获取对应的服务端点(endpoint即隧道ID),最后在隧道的连接池中获取一个有效连接将流量通过此连接发送到客户端。


当主机名为example.com时,根据Ingress中的规则匹配到ID为4d21094e-b74c-4916-86c1-d9fa36ea677b的隧道。当流量到达客户端后再由rtcp服务转发给192.168.1.1:80服务。


高可用性

为了提高单个隧道的可用性,可以运行多个客户端,这些客户端使用相同的隧道ID。当需要从隧道获取连接时,将采用轮询机制,最多3次失败重试。


外部公共入口点¶


上面通过entrypoint选项设置的入口点可以看作是隧道服务内部提供的一个公共入口点,也可以运行多个外部公共入口点将流量转发到隧道服务。


服务端¶


服务端通过entrypoint.id指定入口点ID,客户端必须使用相同的ID才会被认为是一个公共入口点,否则会被当作私有入口点,仅能访问指定的隧道。



命令行

gost -L "tunnel://:8443?entrypoint.id=9fd6c586-86f9-49c1-a03a-d4876851695a


配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: tunnel

    metadata:

      entrypoint.id: 9fd6c586-86f9-49c1-a03a-d4876851695a

      ingress: ingress-0

  listener:

    type: tcp


ingresses:

- name: ingress-0

  rules:

  - hostname: ".example.com"

    endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

  - hostname: "example.org"

    endpoint: ac74d9dd-3125-442a-a7c1-f9e49e05faca

客户端¶


客户端通过tunnel.id指定隧道ID,当隧道ID与服务端的entrypoint.id相同时,此客户端会被当作一个公共入口点。



命令行

gost -L tcp://:8000?sniffing=true -F tunnel://:8443?tunnel.id=9fd6c586-86f9-49c1-a03a-d4876851695a


配置文件

  services:

  - name: service-0

    addr: :8000

    handler:

      type: tcp

      chain: chain-0

      metadata:

        sniffing: true

    listener:

      type: tcp

  chains:

  - name: chain-0

    hops:

    - name: hop-0

      nodes:

      - name: node-0

        addr: :8443

        connector:

          type: tunnel

          metadata:

            tunnel.id: 9fd6c586-86f9-49c1-a03a-d4876851695a

          dialer:

            type: tcp

客户端路由¶


客户端也可以同时开启流量嗅探对流量进行再次路由。


services:

- name: service-0

  addr: :0

  handler:

    type: rtcp

    metadata:

      sniffing: true

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: example-com

      addr: 192.168.1.1:80

      host: example.com

    - name: sub-example-com

      addr: 192.168.1.2:80

      host: sub.example.com

    - name: fallback

      addr: 192.168.2.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: 4d21094e-b74c-4916-86c1-d9fa36ea677b

      dialer:

        type: tcp

当主机名为example.com时,根据Ingress中的规则匹配到Tunnel 4d21094e-b74c-4916-86c1-d9fa36ea677b。当流量到达客户端后再由rtcp服务转发给192.168.1.1:80服务。


当主机名为sub.example.com时,根据Ingress中的规则匹配到Tunnel 4d21094e-b74c-4916-86c1-d9fa36ea677b。当流量到达客户端后再由rtcp服务转发给192.168.1.2:80服务。


当主机名为abc.example.com时,根据Ingress中的规则匹配到Tunnel 4d21094e-b74c-4916-86c1-d9fa36ea677b。当流量到达客户端后再由rtcp服务转发给192.168.2.1:80服务。


私有隧道¶


在Ingress中可以通过将隧道标记为私有来限制对隧道的访问,由公共入口点进入的流量无法路由到私有隧道。


若要使用私有隧道,用户(访问端)需要开启一个私有入口点将流量转发到指定的隧道,通过设置隧道ID来指定想要访问的隧道(不仅限于私有隧道)。


Reverse Proxy - Web Private Tunnel


服务端¶


services:

- name: service-0

  addr: :8443

  handler:

    type: tunnel

    metadata:

      entryPoint: ":80"

      ingress: ingress-0

  listener:

    type: tcp

ingresses:

- name: ingress-0

  rules:

  - hostname: "srv-0.local"

    endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

  - hostname: "srv-1.local"

    endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

  - hostname: "srv-2.local"

    endpoint: $ac74d9dd-3125-442a-a7c1-f9e49e05faca # private tunnel

  - hostname: "srv-3.local"

    endpoint: ac74d9dd-3125-442a-a7c1-f9e49e05faca

  - hostname: "ssh.srv-2.local" 

    endpoint: aede1f6a-762b-45da-b937-b6632356555a # tunnel for ssh TCP traffic

  - hostname: "redis.srv-3.local" 

    endpoint: aede1f6a-762b-45da-b937-b6632356555a # tunnel for redis TCP traffic

  - hostname: "dns.srv-2.local" 

    endpoint: aede1f6a-762b-45da-b937-b6632356555a # tunnel for DNS UDP traffic

  - hostname: "dns.srv-3.local" 

    endpoint: aede1f6a-762b-45da-b937-b6632356555a # tunnel for DNS UDP traffic

在Ingress的规则中,通过在endpoint所代表的隧道ID值前添加$便将此规则对应的隧道标记为私有,例如上面的srv-2.local主机对应的隧道ac74d9dd-3125-442a-a7c1-f9e49e05faca即为私有隧道,因此通过公共入口点80端口进入的流量无法使用此隧道。


私有性

私有性的作用范围为Ingress的规则,而不是隧道本身,同一个隧道在不同的规则中可以有不同的私有性。例如上面例子当中,srv-2.local和srv-3.local使用的是相同的隧道,但srv-3.local对应规则中隧道不是私有的,因此通过公共入口点80端口进入去往srv-3.local主机的流量可以路由到此隧道。


客户端¶



命令行

gost -L rtcp://:0/192.168.2.1:80 -F tunnel://:8443?tunnel.id=ac74d9dd-3125-442a-a7c1-f9e49e05faca


配置文件

services:

- name: service-0

  addr: :0

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: srv-2.local

      addr: 192.168.2.1:80

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: ac74d9dd-3125-442a-a7c1-f9e49e05faca

      dialer:

        type: tcp

客户端的配置与之前一致。


访问端¶



命令行

自动嗅探主机名


gost -L tcp://:8000?sniffing=true -F tunnel://:8443?tunnel.id=ac74d9dd-3125-442a-a7c1-f9e49e05faca

或指定主机名


gost -L tcp://:8000/srv-2.local -F tunnel://:8443?tunnel.id=ac74d9dd-3125-442a-a7c1-f9e49e05faca

配置文件

  services:

  - name: service-0

    addr: :8000

    handler:

      type: tcp

      chain: chain-0

      metadata:

        sniffing: true

    listener:

      type: tcp

  chains:

  - name: chain-0

    hops:

    - name: hop-0

      nodes:

      - name: node-0

        addr: :8443

        connector:

          type: tunnel

          metadata:

            tunnel.id: ac74d9dd-3125-442a-a7c1-f9e49e05faca

          dialer:

            type: tcp

访问端开启私有入口服务监听在8000端口,通过设置tunnel.id选项指定所要使用的隧道。


TCP服务¶


隧道并不限于Web流量,也可以应用于任何TCP服务(例如SSH)。例如上面服务端的Ingress中ssh.srv-2.local和redis.srv-3.local主机对应的隧道。


Reverse Proxy - TCP Tunnel


客户端¶


services:

- name: service-0

  addr: :0

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: ssh

      addr: 192.168.2.1:22

      host: ssh.srv-2.local

    - name: redis

      addr: 192.168.2.2:6379

      host: redis.srv-3.local

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: aede1f6a-762b-45da-b937-b6632356555a

      dialer:

        type: tcp

客户端的转发器设置了两个目标节点:192.168.2.1:22的ssh服务和192.168.2.2:6379的redis服务。 注意每个节点上的host参数需要与服务端Ingress对应规则中的hostname相匹配。


访问端¶



命令行

SSH服务


gost -L tcp://:2222/ssh.srv-2.local -F tunnel://:8443?tunnel.id=aede1f6a-762b-45da-b937-b6632356555a

或redis服务


gost -L tcp://:6379/redis.srv-3.local -F tunnel://:8443?tunnel.id=aede1f6a-762b-45da-b937-b6632356555a

配置文件

  services:

  - name: service-0

    addr: :2222

    handler:

      type: tcp

      chain: chain-0

    listener:

      type: tcp

    forwarder:

      nodes:

      - name: ssh

        addr: ssh.srv-2.local

      # - name: redis

      #   addr: redis.srv-3.local

  chains:

  - name: chain-0

    hops:

    - name: hop-0

      nodes:

      - name: node-0

        addr: :8443

        connector:

          type: tunnel

          metadata:

            tunnel.id: aede1f6a-762b-45da-b937-b6632356555a

          dialer:

            type: tcp

访问端需要在转发器中指定目标节点主机名,需要与服务端Ingress对应规则中的hostname相匹配。


UDP服务¶


隧道也可以应用于任何UDP服务(例如DNS)。例如上面服务端的Ingress中dns.srv-2.local和dns.srv-3.local主机对应的隧道。


Reverse Proxy - UDP Tunnel


客户端¶


services:

- name: service-0

  addr: :0

  handler:

    type: rudp

  listener:

    type: rudp

    chain: chain-0

  forwarder:

    nodes:

    - name: dns-1

      addr: 192.168.2.1:53

      host: dns.srv-2.local

    - name: dns-2

      addr: 192.168.2.2:53

      host: dns.srv-3.local

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: aede1f6a-762b-45da-b937-b6632356555a

      dialer:

        type: tcp

客户端的转发器设置了两个目标节点:192.168.2.1:53的DNS服务和192.168.2.2:53的DNS服务。 注意每个节点上的host参数需要与服务端Ingress对应规则中的hostname相匹配。


访问端¶



命令行

gost -L udp://:1053/dns.srv-2.local -L udp://:2053/dns.srv-3.local -F tunnel://:8443?tunnel.id=aede1f6a-762b-45da-b937-b6632356555a


配置文件

  services:

  - name: service-0

    addr: :1053

    handler:

      type: udp

      chain: chain-0

    listener:

      type: udp

    forwarder:

      nodes:

      - name: dns-1

        addr: dns.srv-2.local

  - name: service-1

    addr: :2053

    handler:

      type: udp

      chain: chain-0

    listener:

      type: udp

    forwarder:

      nodes:

      - name: dns-2

        addr: dns.srv-3.local

  chains:

  - name: chain-0

    hops:

    - name: hop-0

      nodes:

      - name: node-0

        addr: :8443

        connector:

          type: tunnel

          metadata:

            tunnel.id: aede1f6a-762b-45da-b937-b6632356555a

          dialer:

            type: tcp

访问端需要在转发器中指定目标节点主机名,需要与服务端Ingress对应规则中的hostname相匹配。


直接路由¶


上面的隧道都是通过定义Ingress,根据Ingress规则中虚拟主机名来路由,这种方式可以看作是间接路由模式,Ingress在这里即是路由表,又可以看作是白名单。


也可以开启直接路由模式,访问端与客户端直接通过隧道ID进行匹配,当访问端未匹配上Ingress中的规则后会采用隧道ID直接匹配方式来查找客户端。Ingress是可选的。


提高安全性

当开启直接路由模式后,隧道的分配及使用完全由客户端控制,请确保服务端仅能够被受信任的用户访问,可以通过增加用户认证功能提高服务的安全性,以防止被滥用。


服务端通过tunnel.direct选项开启直接路由模式。



命令行

gost -L tunnel://:8443?tunnel.direct=true


配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: tunnel

    metadata:

      tunnel.direct: true

  listener:

    type: tcp

多路复用¶


隧道本身支持多路复用,单个隧道不仅限于某一种类型的流量使用,也支持同时传输不同类型的流量(Web,TCP,UDP)。


TCP和UDP服务可以共用同一个隧道,隧道会对TCP和UDP的客户端连接作区分,对于TCP的访问端仅会匹配TCP客户端,对于UDP的访问端仅会区配UDP客户端。


下面将通过一个具体的示例来说明。


示例 - 通过隧道进行iperf测试¶


Reverse Proxy - iperf3


服务端¶



命令行

Ingress模式


gost -L tunnel://:8443?tunnel=iperf.local:22f43305-42f7-4232-bbbc-aa6c042e3bc3

或直接路由模式


gost -L tunnel://:8443?tunnel.direct=true

配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: tunnel

    metadata:

      ingress: ingress-0

      # direct routing mode

      # tunnel.direct: true 

  listener:

    type: tcp

ingresses:

- name: ingress-0

  rules:

  - hostname: "iperf.local"

    endpoint: 22f43305-42f7-4232-bbbc-aa6c042e3bc3

客户端¶


由于转发的目标只有一个,因此可以使用命令行直接转发,如果要转发多个服务需要通过配置文件在转发器中为每个目标节点定义主机名(forwarder.nodes.host),通过主机名来匹配不同的服务。



命令行

gost -L rtcp://:0/:5201 -L rudp://:0/:5201 -F tunnel://:8443?tunnel.id=22f43305-42f7-4232-bbbc-aa6c042e3bc3


配置文件

services:

- name: iperf-tcp

  addr: :0

  handler:

    type: rtcp

  listener:

    type: rtcp

    chain: chain-0

  forwarder:

    nodes:

    - name: iperf

      addr: :5201

      host: iperf.local

- name: iperf-udp

  addr: :0

  handler:

    type: rudp

  listener:

    type: rudp

    chain: chain-0

  forwarder:

    nodes:

    - name: iperf

      addr: :5201

      host: iperf.local

chains:

- name: chain-0

  hops:

  - name: hop-0

    nodes:

    - name: node-0

      addr: :8443

      connector:

        type: tunnel

        metadata:

          tunnel.id: 22f43305-42f7-4232-bbbc-aa6c042e3bc3

      dialer:

        type: tcp

访问端¶


转发的目标地址需要与服务端的Ingress中规则对应的主机名匹配,如果要转发多个服务需要通过配置文件在转发器中为每个目标节点定义主机名(forwarder.nodes.host),通过主机名来匹配不同的服务。


UDP连接保持

UDP端口转发服务默认在进行完一次数据交互后连接状态便失效,这对于像DNS这种服务会很有效。但是对于需要多次数据交互的UDP服务,需要通过keepalive选项开启连接保持功能,另外可以通过ttl选项来控制超时时长,默认超过5秒无数据交互连接状态将会失效。



命令行

Ingress模式


gost -L tcp://:15201/iperf.local -L udp://:15201/iperf.local?keepalive=true -F tunnel://:8443?tunnel.id=22f43305-42f7-4232-bbbc-aa6c042e3bc3

直接路由模式


gost -L tcp://:15201 -L udp://:15201?keepalive=true -F tunnel://:8443?tunnel.id=22f43305-42f7-4232-bbbc-aa6c042e3bc3


配置文件

  services:

  - name: iperf-tcp

    addr: :15201

    handler:

      type: tcp

      chain: chain-0

    listener:

      type: tcp

    forwarder:

      nodes:

      - name: iperf

        addr: iperf.local

  services:

  - name: iperf-udp

    addr: :15201

    handler:

      type: udp

      chain: chain-0

    listener:

      type: udp

      metadata:

        keepalive: true

        # ttl: 5s

    forwarder:

      nodes:

      - name: iperf

        addr: iperf.local

  chains:

  - name: chain-0

    hops:

    - name: hop-0

      nodes:

      - name: node-0

        addr: :8443

        connector:

          type: tunnel

          metadata:

            tunnel.id: 22f43305-42f7-4232-bbbc-aa6c042e3bc3

          dialer:

            type: tcp

iperf3服务¶


启动iperf3服务。


iperf3 -s

执行iperf3测试¶


TCP测试


iperf3 -c 127.0.0.1 -p 15201

UDP测试


iperf3 -c 127.0.0.1 -p 15201 -u

公共反向代理服务¶


如果需要临时来反向代理内网服务提供公网访问,可以通过GOST.PLUS提供的公共反向代理服务将内网服务匿名暴露到公网来访问。


gost -L rtcp://:0/192.168.1.1:80 -F tunnel+wss://tunnel.gost.plus:443

或者手动指定隧道ID:


gost -L rtcp://:0/192.168.1.1:80 -F tunnel+wss://tunnel.gost.plus:443?tunnel.id=893787fd-fcd2-46a0-8dd4-f9103ae84df4

当正常连接到GOST.PLUS服务后,会有类似如下日志信息:


{"connector":"tunnel","dialer":"wss","endpoint":"134c714b65d54a4f","hop":"hop-0","kind":"connector","level":"info",

"msg":"create tunnel on 134c714b65d54a4f:0/tcp OK, tunnel=893787fd-fcd2-46a0-8dd4-f9103ae84df4, connector=3464af8b-49c5-424c-89ea-b4e9af075a7d",

"node":"node-0","time":"2023-10-19T23:17:27.403+08:00",

"tunnel":"893787fd-fcd2-46a0-8dd4-f9103ae84df4"}

日志的endpoint信息中134c714b65d54a4f是为此服务生成的临时公共访问点,有效期为1小时。


如果192.168.1.1:80是一个HTTP服务,通过https://134c714b65d54a4f.gost.plus便能立即访问。


TCP服务¶


对于TCP服务同样可以以私有隧道的方式来访问。这里假设192.168.1.1:22是一个SSH服务。


gost -L rtcp://:0/192.168.1.1:22 -F tunnel+wss://tunnel.gost.plus:443?tunnel.id=f8baa731-4057-4300-ab75-c4e603834f1b

内网服务不会在服务端暴露公开端口,需要在访问端开启一个私有入口点:


gost -L tcp://:2222/f1bbbb4aa9d9868a.gost.plus -F tunnel+wss://tunnel.gost.plus:443?tunnel.id=f8baa731-4057-4300-ab75-c4e603834f1b

注意两端的隧道ID必须匹配才能访问到隧道对应的服务。


此时在访问端执行以下命令便可以访问到192.168.1.1:22。


ssh -p 2222 user@localhost

UDP服务¶


同样也可以以私有隧道的方式暴露UDP服务。这里假设192.168.1.1:53是一个DNS服务。


gost -L rudp://:0/192.168.1.1:53 -F tunnel+wss://tunnel.gost.plus:443?tunnel.id=f8baa731-4057-4300-ab75-c4e603834f1b

要访问此服务需要在访问端开启一个私有入口点:


gost -L udp://:1053/f1bbbb4aa9d9868a.gost.plus -F tunnel+wss://tunnel.gost.plus:443?tunnel.id=f8baa731-4057-4300-ab75-c4e603834f1b

注意两端的隧道ID必须匹配才能访问到隧道对应的服务。


此时在访问端执行以下命令便可以访问到192.168.1.1:53。


dig -p 1053 @127.0.0.1


-----------------------------------------------------------


反向代理隧道-高可用¶


在上一篇反向代理隧道教程中,详细的讲述了反向代理隧道的功能和使用方法。在本篇教程中将侧重于服务的部署及系统的高可用性方面。


单点故障¶


一个反向代理隧道系统是由三个部分组成:


服务端 - 反向代理隧道服务,负责隧道的管理和流量的路由。

客户端 - 与服务端建立隧道连接,接收服务端过来的流量,再次路由并转发到目标主机。

访问端 - 访问端通过入口点将请求转发给服务,服务再将流量路由到对应隧道的客户端,最终到达目标主机。

Tunnel


在上面这个系统中存在单点故障(SPOF)问题,当三个部分中的任意一个出现问题,隧道就不可用。例如下图中,当客户端网络出现问题无法与服务端建立隧道连接,或者访问点无法连通服务,其对应的隧道也就无法访问。


Tunnel SPOF


解决单点故障比较成熟的方案是,让系统的每个部分都可以做到水平扩展。通过运行多个实例形成一个集群,当集群中的单个实例出现故障时,其他实例可以继续运作,从而实现整个系统的高可用。对于客户端和访问端的单点问题,可以简单的通过运行多个实例来解决。


Tunnel HA


反向代理隧道中的单个隧道支持多个连接,通过运行多个客户端并指定相同的隧道ID。多个连接在隧道服务端构成一个连接池,服务端以轮询的方式使用这些连接,当检测到客户端的连接异常后会将此连接剔除连接池。访问端也可以通过运行多个访问点来提高可用性。


客户端和访问端是无状态的,因此可以很容易实现水平扩展。但是服务端却无法简单的做到,服务端需要维护每个隧道的状态,隧道本身并不能随着服务端的扩展而自动迁移或复制。


Tunnel SPOF


如上图运行了两个服务端实例,客户端连接到Server-1。此时如果访问端的请求发送到Server-2,由于Server-2中没有隧道的连接,因此路由失败。对于服务端需要一些额外的手段来实现扩展性。


服务注册和发现¶


服务端无法做到水平扩展的原因是,服务端实例之间是相互独立的,彼此无法感知到其他实例中隧道的信息。因此我们需要一种方法来让服务端共享所有的客户端隧道和连接信息。反向代理隧道服务中通过服务注册和发现机制来达到此目的,但其内部并没有集成具体的服务注册和发现功能模块,而是通过插件的方式将功能开放出来,由用户自己选择实现方式。


Tunnel SD


当客户端连接到隧道服务后,服务端会将此客户端的连接信息发送给插件(Register),服务端会定期检查连接状态并向插件报告(Renew)以便维持连接信息的有效性。当客户端断开后,服务端也会报告插件(Deregister)。


当访问端的请求到达服务端后,服务端首先在其自身的连接池中获取隧道的连接,如果没有找到则会再次向插件查询(Get),插件会返回对应隧道的连接列表。其中每个连接信息中包含此连接所在的服务节点地址(入口点),服务端最终将请求转发给其他实例处理。


云原生部署示例¶


当系统的所有部分都可以水平扩展后,就可以借助于Kubernetes等云原生平台来灵活部署。下面是一个完整的高可用反向代理隧道系统部署示例,其中Ingress路由和服务发现的插件部分均采用redis服务提供支持。


客户端通过gost.local域名连接隧道服务:


gost -L file://:8000 -L rtcp://:0/:8000 -F tunnel+ws://gost.local:80?tunnel.id=381433e1-7980-11ee-bbdb-60f262c1e32d

然后就可以通过http://b7de88a94729b931.gost.local来访问。


deploy.yaml


-----------------------------------------------------------

HTTP文件服务¶


HTTP文件服务,将本地的文件系统目录转成HTTP服务。


使用方法¶



命令行

gost -L file://:8080?dir=/path/to/dir


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: file

    metadata:

      dir: /path/to/dir

  listener:

    type: tcp

dir (string):

文件目录,默认为当前工作目录。

转发链

文件服务会忽略转发链。


示例¶


简单的HTTP文件服务¶


将/home以HTTP服务的方式暴露在8080端口。



命令行

gost -L file://:8080?dir=/home


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: file

    metadata:

      dir: /home

  listener:

    type: tcp

认证¶


为服务设置基本认证。



命令行

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


配置文件

services:

- name: service-0

  addr: :8080

  handler:

    type: file

    auth:

      username: user

      password: pass

  listener:

    type: tcp

TLS¶


为服务增加TLS加密传输层(HTTPS)。



命令行

gost -L file+tls://:8443


配置文件

services:

- name: service-0

  addr: :8443

  handler:

    type: file

  listener:

    type: tls

公网临时访问¶


如果需要临时通过公网来访问文件服务,可以通过GOST.PLUS提供的公共反向代理服务将本地文件服务匿名暴露到公网来访问。


gost -L file://:8080 -L rtcp://:0/:8080 -F tunnel+wss://tunnel.gost.plus:443

当正常连接到GOST.PLUS服务后,会有类似如下日志信息:


{"connector":"tunnel","dialer":"wss","endpoint":"006478add9ed096a","hop":"hop-0","kind":"connector","level":"info",

"msg":"create tunnel on 006478add9ed096a:0/tcp OK, tunnel=50ce9728-5d92-4d45-871d-4f275d5179cb, connector=956fcbe5-6e2d-439a-8aa3-af0df848a81a",

"node":"node-0","time":"2023-10-19T22:41:05.759+08:00",

"tunnel":"50ce9728-5d92-4d45-871d-4f275d5179cb"}

日志的endpoint信息中006478add9ed096a是为此服务生成的临时公共访问点,有效期为1小时。通过https://006478add9ed096a.gost.plus便能立即访问到此文件服务。


-----------------------------------------------------------


GO Simple Tunnel

GO语言实现的安全隧道

功能特性

多端口监听

多级转发链

多协议支持

TCP/UDP端口转发

TCP/UDP透明代理

DNS解析和代理

TUN/TAP设备

反向代理

负载均衡

路由控制

限速限流

准入控制

动态配置

插件系统

Prometheus监控指标

Web API

Web UI

Telegram讨论群:https://t.me/gogost


Google讨论组:https://groups.google.com/d/forum/go-gost


提交Issue:https://github.com/go-gost/gost/issues


旧版入口:v2.gost.run


下载安装

二进制文件

https://github.com/go-gost/gost/releases


源码编译


git clone https://github.com/go-gost/gost.git

cd gost/cmd/gost

go build

Docker


docker run --rm gogost/gost -V

Shadowsocks Android插件

xausky/ShadowsocksGostPlugin

https://github.com/xausky/ShadowsocksGostPlugin



  • 发表评论
  • 查看评论
【暂无评论!】

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。