diff --git a/README.md b/README.md index c17345b..9363cf1 100644 --- a/README.md +++ b/README.md @@ -15,23 +15,20 @@ A simple VPN written in golang. ``` Usage of ./vtun: - -S server mode -c string - tun interface CIDR (default "172.16.0.2/24") - -g string - gateway (default "172.16.0.1") + tun interface CIDR (default "172.16.0.10/24") -k string key (default "6w9z$C&F)J@NcRfWjXn3r4u7x!A%D*G-") -l string - local address (default "0.0.0.0:3000") - -s string - server address (default "0.0.0.0:3001") + local address (default ":3000") -p string protocol ws/wss/udp (default "wss") - -r string - route - -o enable data obfuscation + -s string + server address (default ":3001") -P enable pporf server on :6060 + -S server mode + -g client global mode + -o enable data obfuscation ``` @@ -48,6 +45,13 @@ sudo ./vtun-linux-amd64 -l=:3000 -s=server-addr:3001 -c=172.16.0.10/24 -k=123456 ``` +## Client with global mode(routing all your traffic to server) + +``` +sudo ./vtun-linux-amd64 -l=:3000 -s=server-addr:3001 -c=172.16.0.10/24 -k=123456 -g + +``` + ## Server ``` @@ -71,19 +75,24 @@ sudo ./vtun-linux-amd64 -S -l=:3001 -c=172.16.0.1/24 -k=123456 ### Run client ``` -docker run -d --privileged --restart=always --net=host --name vtun-client netbyte/vtun -l=:3000 -s=server-addr:3001 -c=172.16.0.10/24 -k=123456 +docker run -d --privileged --restart=always --net=host --name vtun-client netbyte/vtun -l :3000 -s server-addr:3001 -c 172.16.0.10/24 -k 123456 +``` + +### Run client with global mode +``` +docker run -d --privileged --restart=always --net=host --name vtun-client netbyte/vtun -l :3000 -s server-addr:3001 -c 172.16.0.10/24 -k 123456 -g ``` ### Run server ``` -docker run -d --privileged --restart=always --net=host --name vtun-server netbyte/vtun -S -l=:3001 -c=172.16.0.1/24 -k=123456 +docker run -d --privileged --restart=always --net=host --name vtun-server netbyte/vtun -S -l :3001 -c 172.16.0.1/24 -k 123456 ``` ## Mobile client ### [Android](https://github.com/net-byte/vTunnel) -## Caution -1. Only support on Linux and MacOS -2. Only support IPv4 +## TODO +1. support windows +2. support IPv6 diff --git a/common/config/config.go b/common/config/config.go index e51cb4f..9c51c37 100644 --- a/common/config/config.go +++ b/common/config/config.go @@ -11,11 +11,11 @@ type Config struct { LocalAddr string ServerAddr string CIDR string - Route string Gateway string Key string Protocol string ServerMode bool + GlobalMode bool Obfuscate bool Pprof bool } diff --git a/common/netutil/netutil.go b/common/netutil/netutil.go index 3a67d23..1279092 100644 --- a/common/netutil/netutil.go +++ b/common/netutil/netutil.go @@ -73,6 +73,7 @@ func GetPhysicalInterface() (name string, gateway string, network string) { ipNet[3]++ gateway = ipNet.String() name = ifaces[0].Name + log.Printf("physical interface %v gateway %v network %v", name, gateway, network) break } } @@ -87,16 +88,19 @@ func getAllPhysicalInterfaces() []net.Interface { } var outInterfaces []net.Interface - for _, element := range ifaces { - if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.Name) { - outInterfaces = append(outInterfaces, element) + for _, iface := range ifaces { + if iface.Flags&net.FlagLoopback == 0 && iface.Flags&net.FlagUp == 1 && isPhysicalInterface(iface.Name) { + netAddrs, _ := iface.Addrs() + if len(netAddrs) > 0 { + outInterfaces = append(outInterfaces, iface) + } } } return outInterfaces } func isPhysicalInterface(addr string) bool { - prefixArray := []string{"ens", "enp", "eth", "wlan", "wlp"} + prefixArray := []string{"ens", "enp", "enx", "eth", "wlan", "wlp"} for _, pref := range prefixArray { if strings.HasPrefix(strings.ToLower(addr), pref) { return true diff --git a/main.go b/main.go index 310cc35..a34b8f8 100644 --- a/main.go +++ b/main.go @@ -12,14 +12,13 @@ import ( func main() { config := config.Config{} - flag.StringVar(&config.CIDR, "c", "172.16.0.2/24", "tun interface CIDR") - flag.StringVar(&config.LocalAddr, "l", "0.0.0.0:3000", "local address") - flag.StringVar(&config.ServerAddr, "s", "0.0.0.0:3001", "server address") + flag.StringVar(&config.CIDR, "c", "172.16.0.10/24", "tun interface CIDR") + flag.StringVar(&config.LocalAddr, "l", ":3000", "local address") + flag.StringVar(&config.ServerAddr, "s", ":3001", "server address") flag.StringVar(&config.Key, "k", "6w9z$C&F)J@NcRfWjXn3r4u7x!A%D*G-", "key") - flag.StringVar(&config.Gateway, "g", "172.16.0.1", "gateway") - flag.StringVar(&config.Route, "r", "", "route") flag.StringVar(&config.Protocol, "p", "wss", "protocol ws/wss/udp") flag.BoolVar(&config.ServerMode, "S", false, "server mode") + flag.BoolVar(&config.GlobalMode, "g", false, "client global mode") flag.BoolVar(&config.Obfuscate, "o", false, "enable data obfuscation") flag.BoolVar(&config.Pprof, "P", false, "enable pporf server on :6060") flag.Parse() diff --git a/scripts/build.sh b/scripts/build.sh index 0f4dda9..9f1ad72 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,13 +1,12 @@ #!bin/bash -export GO111MODULE=on #Linux amd64 -GOOS=linux GOARCH=amd64 go build -o ./bin/vtun-linux-amd64 ./main.go +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/vtun-linux-amd64 ./main.go #Linux arm64 -GOOS=linux GOARCH=arm64 go build -o ./bin/vtun-linux-arm64 ./main.go +CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o ./bin/vtun-linux-arm64 ./main.go #Mac amd64 -GOOS=darwin GOARCH=amd64 go build -o ./bin/vtun-darwin-amd64 ./main.go +CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o ./bin/vtun-darwin-amd64 ./main.go #Openwrt mipsel_24kc -GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -o ./bin/vtun-mipsel-24kc ./main.go +CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -o ./bin/vtun-mipsel-24kc ./main.go echo "DONE!!!" diff --git a/scripts/start_wsclient.sh b/scripts/start_wsclient.sh deleted file mode 100755 index 9273caf..0000000 --- a/scripts/start_wsclient.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!bin/bash -#change your config -DOMAIN="your.domain" -PORT="443" -CIDR="172.16.0.235/24" -GATEWAY="192.168.1.1" -DEVICE="wlp36s0" -TUN="tun0" - -echo "starting..." -IP=$(ping -c 1 $DOMAIN | gawk -F'[()]' '/PING/{print $2}') -echo $DOMAIN $IP - -#start client -sudo killall vtun-linux-amd64 -sudo ./bin/vtun-linux-amd64 -c $CIDR -s $DOMAIN:$PORT & -sleep 1 - -#routing all your traffic -sudo ip route add 0.0.0.0/1 dev $TUN -sudo ip route add 128.0.0.0/1 dev $TUN -sudo ip route delete $IP/32 via $GATEWAY dev $DEVICE -sudo ip route add $IP/32 via $GATEWAY dev $DEVICE - -echo "show ip route" -sudo ip route - -echo "STARTED!!!" diff --git a/tun/tun.go b/tun/tun.go index 9aa4555..ea91af5 100644 --- a/tun/tun.go +++ b/tun/tun.go @@ -26,29 +26,32 @@ func CreateTun(config config.Config) (iface *water.Interface) { func configTun(config config.Config, iface *water.Interface) { os := runtime.GOOS - ip, _, err := net.ParseCIDR(config.CIDR) + ip, ipNet, err := net.ParseCIDR(config.CIDR) if err != nil { log.Panicf("error cidr %v", config.CIDR) } - physicalIface, gatewayIP, localNetwork := netutil.GetPhysicalInterface() if os == "linux" { execCmd("/sbin/ip", "link", "set", "dev", iface.Name(), "mtu", "1500") execCmd("/sbin/ip", "addr", "add", config.CIDR, "dev", iface.Name()) execCmd("/sbin/ip", "link", "set", "dev", iface.Name(), "up") - if config.Route != "" { - execCmd("/sbin/ip", "route", "add", config.Route, "dev", iface.Name()) + if config.GlobalMode { + physicalIface, gateway, _ := netutil.GetPhysicalInterface() + serverIP := netutil.LookupIP(strings.Split(config.ServerAddr, ":")[0]) + if physicalIface != "" && serverIP != "" { + execCmd("/sbin/ip", "route", "add", "0.0.0.0/0", "dev", iface.Name()) + execCmd("/sbin/ip", "route", "delete", strings.Join([]string{serverIP, "32"}, "/"), "via", gateway, "dev", physicalIface) + execCmd("/sbin/ip", "route", "add", strings.Join([]string{serverIP, "32"}, "/"), "via", gateway, "dev", physicalIface) + } } - serverIP := netutil.LookupIP(strings.Split(config.ServerAddr, ":")[0]) - execCmd("/sbin/ip", "route", "add", "0.0.0.0/1", "dev", iface.Name()) - execCmd("/sbin/ip", "route", "add", "128.0.0.0/1", "dev", iface.Name()) - execCmd("/sbin/ip", "delete", strings.Join([]string{serverIP, "32"}, "/"), "via", gatewayIP, "dev", physicalIface) - execCmd("/sbin/ip", "add", strings.Join([]string{serverIP, "32"}, "/"), "via", gatewayIP, "dev", physicalIface) + } else if os == "darwin" { execCmd("ifconfig", iface.Name(), "inet", ip.String(), config.Gateway, "up") - if config.Route != "" { - execCmd("route", "add", "-net", config.Route, "-interface", iface.Name()) - execCmd("route", "add", "0.0.0.0/0", "-interface", iface.Name()) - execCmd("route", "add", localNetwork, "-interface", config.Route) + if config.GlobalMode { + _, _, localNetwork := netutil.GetPhysicalInterface() + if localNetwork != "" { + execCmd("route", "add", "0.0.0.0/0", "-interface", iface.Name()) + execCmd("route", "add", localNetwork, "-interface", ipNet.IP.To4().String()) + } } } else { log.Printf("not support os:%v", os)