go-gost / gost

GO Simple Tunnel - a simple tunnel written in golang
https://gost.run
MIT License
4.04k stars 495 forks source link

[Help/Question] How can we make client as a proxy in reverse proxy tunnel ? #553

Open xzycn opened 1 month ago

xzycn commented 1 month ago

As the docs(https://gost.run/tutorials/reverse-proxy-tunnel/) say, the test config as follows: client side :

log:
  level: debug
services:
  - name: service-0
    addr: :0
    handler:
      type: rtcp
    listener:
      type: rtcp
      chain: chain-0

chains:
  - name: chain-0
    hops:
      - name: hop-0
        nodes:
          - name: node-0
            addr: [server_ip]:8443
            connector:
              type: tunnel
              metadata:
                tunnel.id: 4d21094e-b74c-4916-86c1-d9fa36ea677b
                tunnel.weight: 1
            dialer:
              type: tcp

server side :

services:
  - name: service-0
    addr: :8443
    handler:
      type: tunnel
      metadata:
        entrypoint: "127.0.0.1:10086"
        ingress: ingress-0
    listener:
      type: tcp

ingresses:
  - name: ingress-0
    rules:
      - hostname: "example.com"
        endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

Well, after starting them in each node, we can visit http://ipinfo.io by curl -x server_ip:10086 http://example.com, but https failed with TLS shakehand error. After some investigations, found that entrypoint hanler don't handle connect method expect one case:

if v[0] == relay.Version1 {
        return ep.handleConnect(ctx, xnet.NewBufferReaderConn(conn, br), log)
}

some questions: 1 What should we do to make the request from curl as a relay request? 2 Now the entrypoint handler only support HTTP proxy request, could we create a auto type handler(support socks and http) forward the request to entrypoint handler?

In one word, how can we access any websites or applications(TCP or UDP) from server side? Thx.

ginuerzh commented 1 month ago

The entrypoint in tunnel handler is a normal HTTP reverse proxy service (not an HTTP proxy), used as a convenient way to access web services, and only accepts normal HTTP requests. For non-HTTP traffic, a separate TCP (or UDP) entrypoint needs to be run.

services:
  - name: entrypoint
    addr: :8000
    handler:
      type: tcp
      chain: chain-0
    listener:
      type: tcp
    forwarder:
      nodes:
        - name: target-0
          addr: example.com
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

See https://gost.run/tutorials/reverse-proxy-tunnel/#tcp

xzycn commented 1 month ago

@ginuerzh We don't know which website will be visited in advance, we need make client (or whole thing including server 、client and tunnel bettwen them) as a proxy, we should provide a proxy to our mates instead of a reverse proxy.Is there a suitable way for our use case ?

ginuerzh commented 1 month ago

Do you want to expose the internal proxy service and access other services through the proxy? As mentioned above, you need to run a TCP entrypoint and map it to the internal proxy server.

For example

Client side

Proxy server that need to be exposed

gost -L :8080

Tunnel client

gost -L rtcp://:0/:8080 -F tunnel://[server_ip]: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: :8080
chains:
  - name: chain-0
    hops:
      - name: hop-0
        nodes:
          - name: node-0
            addr: [server_ip]:8443
            connector:
              type: tunnel
              metadata:
                tunnel.id: 4d21094e-b74c-4916-86c1-d9fa36ea677b
            dialer:
              type: tcp

Server side

Tunnel service

gost -L tunnel://:8443?tunnel=proxy:4d21094e-b74c-4916-86c1-d9fa36ea677b
services:
  - name: service-0
    addr: :8443
    handler:
      type: tunnel
      metadata:
        ingress: ingress-0
    listener:
      type: tcp

ingresses:
  - name: ingress-0
    rules:
      - hostname: "proxy"
        endpoint: 4d21094e-b74c-4916-86c1-d9fa36ea677b

TCP entrypoint

gost -L tcp://:8000/proxy -F tunnel://:8443?tunnel.id=4d21094e-b74c-4916-86c1-d9fa36ea677b
services:
  - name: entrypoint
    addr: :8000
    handler:
      type: tcp
      chain: chain-0
    listener:
      type: tcp
    forwarder:
      nodes:
        - name: target-0
          addr: proxy
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

NOTE: the hostname in the ingress rule is a virtual host, it is used for tunnel routing.

Then you can use the entrypoint as a proxy to access other services:

curl --socks5-hostname server_ip:8000 https://ipinfo.io
xzycn commented 1 month ago

@ginuerzh It works, the configs are a bit complicated, we even thought metadata.entrypoint is required for tunnel handler,no idea it can be a seperated service, and there is no docs for tunnel handler and tunnel connector now in https://gost.run. IMHO,if it means we need to create a TCP entrypoint to a tunnel(ie. a new forwarder node, a new chain, and a newingress rule) ? If so, it will be a problem when we have a lot tunnel clients, right?