go-gost / gost

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

[Help/Question] About routing traffic from iptables to gost #566

Open vansention opened 2 months ago

vansention commented 2 months ago

Hi there,

Gost has been an invaluable tool for me over the years, and I appreciate the author's excellent work.

I'm currently facing a SOCKS5 version mismatch issue while trying to route VPN traffic through a Gost server.

Background:

iptables -t nat -A PREROUTING -s 172.24.0.0/14 -p tcp -j DNAT --to-destination 10.148.0.8:4726
2024/09/02 06:34:26 socks.go:855: [socks5] 172.24.0.2:59838 -> 10.148.0.8:4726 : bad version
2024/09/02 06:34:32 socks.go:855: [socks5] 172.24.0.2:50071 -> 10.148.0.8:4726 : bad version
...

Question:

I'm wondering if this error is indeed due to a SOCKS5 version mismatch or if there might be other underlying issues.

I've already consulted with Google Gemini, and they suggested that it could be a version incompatibility. However, I'd like to confirm this and explore any other potential causes.

Any insights or suggestions would be greatly appreciated. Thank you!

egg1234 commented 2 months ago

你这样做协议不对,因为4726端口只接受socks5的协议请求,而你把所有vpn流量都扔给4726端口,而vpn客户端是把所有客户端的tcp及udp流量都转发到服务器端,这些流量完全没有socks5的协议请求,而是各种协议请求如http、https、ftp、pop、smtp等等,这些协议与socks5没毛关系,gost当然要报错了

你唯一可以用的方法是,服务器端像你那样gost监听socks5,并且服务器端不要写iptables的规则,然后客户端用gost监听一个本地协议,然后-F转发给服务器端gost的socks5端口

vansention commented 2 months ago

@egg1234 thanks for you help.

the 'redirect' mode is fit the senario rather than "socks5"

TCP proxy worked

route all tcp traffic to gost server

iptables -t nat -A PREROUTING -s 172.24.0.0/14 -p tcp -j DNAT --to-destination 10.148.0.8:4726

the following both worked

gost -L red://10.148.0.8:4726?sniffing=true

gost -L red://10.148.0.8:4726?sniffing=true -F mws://an-internet-ip:443 --> gost -L mws://:443

UDP proxy not works

start a udp proxy

gost -L red://10.148.0.8:4726?ttl=30s

route all udp traffic to gost server

iptables -t nat -A PREROUTING -s 172.24.0.0/14 -p udp -j DNAT --to-destination 10.148.0.8:4726

Got the output of gost when i run nslookup google.com on the client. The udp proxy not worked

2024/09/03 15:01:58 route.go:695: redu://10.148.0.8:4726 on 10.148.0.8:4726
2024/09/03 15:02:01 redirect.go:187: [red-udp] 10.148.0.8:4726: 172.24.0.1:61681 -> 10.148.0.8:4726
2024/09/03 15:02:01 redirect.go:191: [red-udp] 172.24.0.1:61681 -> 10.148.0.8:4726 : dial: socket bind: address already in use

If anyone knows how to fix it I would be grateful

egg1234 commented 2 months ago

在linux里面redirect模式本来就不支持udp包转发,这个和gost无关,这个是linux系统协议限制,如果要做udp包转发,至少需要使用tproxy模式

vansention commented 2 months ago

Thanks again @egg1234 and thanks the author.

Now it is all set. Let me breakdown. Hope it useful for any one.

The goal

Route all traffic from a router, which could be a internal server or an OpenWRT router, to another server that is out of a firewall.

Server A is behand a firewall:

local ip: 10.148.0.8 VPN network: 172.24.0.0/14

Server B is out of a firewall:

public ip: x.x.x.x

The final configuration

Add iptables and route rules

#!/bin/bash

ip rule add fwmark 1 lookup 100
ip route add local default dev lo table 100

# route tcp traffic to gost redirect service  "red://10.148.0.8:4726?sniffing=true"
iptables -t nat -A PREROUTING -s 172.24.0.0/14 -p tcp -j DNAT --to-destination 10.148.0.8:4726

# mark udp traffic and jump to TPROXY of gost  "redu://10.148.0.8:4726?ttl=30"
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p udp -s 172.24.0.0/14 -m socket -j DIVERT

iptables -t mangle -N GOST
iptables -t mangle -A GOST -m mark --mark 100 -j RETURN
iptables -t mangle -A GOST -p udp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 4726 --on-ip 10.148.0.8
iptables -t mangle -A PREROUTING -p udp -s 172.24.0.0/14 -j GOST

iptables -t mangle -N GOST_LOCAL
iptables -t mangle -A GOST_LOCAL -m mark --mark 100 -j RETURN
iptables -t mangle -A GOST_LOCAL -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp -s 172.24.0.0/14 -j GOST_LOCAL

Run gost on Server A

sudo gost -L "redu://10.148.0.8:4726?ttl=30" -L "red://10.148.0.8:4726?sniffing=true" -F "mws://x.x.x.x:443?so_mark=100"

Run gost on Server B.

I think i can set a nginx in the front to protect the gost and prevent sniffing, but I haven't tested it yet

gost -L "mws://:443"

test on the client