Skip to content

Commit

Permalink
added scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
uoosef committed Feb 2, 2024
1 parent 511125e commit bec011c
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 22 deletions.
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ replace github.com/Psiphon-Labs/psiphon-tunnel-core => github.com/uoosef/psiphon
require (
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/Psiphon-Labs/psiphon-tunnel-core v0.0.0-00010101000000-000000000000
github.com/bepass-org/ipscanner v0.0.0-20240202184838-2a4a13151bb1
github.com/bepass-org/proxy v0.0.0-20240201095508-c86216dd0aea
github.com/go-ini/ini v1.67.0
github.com/refraction-networking/conjure v0.7.10-0.20231110193225-e4749a9dedc9
Expand All @@ -33,10 +34,11 @@ require (
github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61 // indirect
github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 // indirect
github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dchest/siphash v1.2.3 // indirect
github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273 // indirect
github.com/dgryski/go-farm v0.0.0-20180109070241-2de33835d102 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/gaukas/godicttls v0.0.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand All @@ -59,6 +61,8 @@ require (
github.com/pion/transport/v2 v2.2.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/quic-go/quic-go v0.40.1 // indirect
github.com/refraction-networking/ed25519 v0.1.2 // indirect
github.com/refraction-networking/gotapdance v1.7.7 // indirect
github.com/refraction-networking/obfs4 v0.1.2 // indirect
Expand All @@ -67,8 +71,10 @@ require (
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 // indirect
gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 // indirect
go.uber.org/mock v0.3.0 // indirect
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect
golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.13.0 // indirect
Expand Down
31 changes: 20 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func main() {
country = flag.String("country", "", "psiphon country code in ISO 3166-1 alpha-2 format")
psiphonEnabled = flag.Bool("cfon", false, "enable psiphonEnabled over warp")
gool = flag.Bool("gool", false, "enable warp gooling")
scan = flag.Bool("scan", false, "enable warp scanner(experimental)")
)

flag.Usage = usage
Expand All @@ -48,16 +49,21 @@ func main() {
createPrimaryAndSecondaryIdentities(*license)

//Decide Working Scenario
endpoints := []string{*endpoint, *endpoint}

if *scan {
endpoints = wiresocks.RunScan()
}

if !*psiphonEnabled && !*gool {
// just run primary warp on bindAddress
runWarp(*bindAddress, *endpoint, "./primary/wgcf-profile.ini", *verbose, true, true)
runWarp(*bindAddress, endpoints, "./primary/wgcf-profile.ini", *verbose, true, true)
} else if *psiphonEnabled && !*gool {
// run primary warp on a random tcp port and run psiphon on bind address
runWarpWithPsiphon(*bindAddress, *endpoint, *country, *verbose)
runWarpWithPsiphon(*bindAddress, endpoints, *country, *verbose)
} else if !*psiphonEnabled && *gool {
// run warp in warp
runWarpInWarp(*bindAddress, *endpoint, *verbose)
runWarpInWarp(*bindAddress, endpoints, *verbose)
}

//End Decide Working Scenario
Expand All @@ -68,15 +74,15 @@ func main() {
}
}

func runWarp(bindAddress, endpoint, confPath string, verbose, wait bool, startProxy bool) (*wiresocks.VirtualTun, int) {
func runWarp(bindAddress string, endpoints []string, confPath string, verbose, wait bool, startProxy bool) (*wiresocks.VirtualTun, int) {
// Setup channel to listen for interrupt signal (Ctrl+C)
var sigChan chan os.Signal
if wait {
sigChan = make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
}

conf, err := wiresocks.ParseConfig(confPath, endpoint)
conf, err := wiresocks.ParseConfig(confPath, endpoints[0])
if err != nil {
log.Fatal(err)
}
Expand All @@ -99,14 +105,14 @@ func runWarp(bindAddress, endpoint, confPath string, verbose, wait bool, startPr
return tnet, conf.Device.MTU
}

func runWarpWithPsiphon(bindAddress, endpoint, country string, verbose bool) {
func runWarpWithPsiphon(bindAddress string, endpoints []string, country string, verbose bool) {
// make a random bind address for warp
warpBindAddress, err := findFreePort("tcp")
if err != nil {
log.Fatal("There are no free tcp ports on Device!")
}

runWarp(warpBindAddress, endpoint, "./primary/wgcf-profile.ini", verbose, false, true)
runWarp(warpBindAddress, endpoints, "./primary/wgcf-profile.ini", verbose, false, true)

// Setup channel to listen for interrupt signal (Ctrl+C)
sigChan := make(chan os.Signal, 1)
Expand All @@ -122,23 +128,26 @@ func runWarpWithPsiphon(bindAddress, endpoint, country string, verbose bool) {
psiphonCtx.Done()
}

func runWarpInWarp(bindAddress, endpoint string, verbose bool) {
func runWarpInWarp(bindAddress string, endpoints []string, verbose bool) {
// run secondary warp
vTUN, mtu := runWarp("", endpoint, "./secondary/wgcf-profile.ini", verbose, false, false)
vTUN, mtu := runWarp("", endpoints, "./secondary/wgcf-profile.ini", verbose, false, false)

// run virtual endpoint
virtualEndpointBindAddress, err := findFreePort("udp")
if err != nil {
log.Fatal("There are no free udp ports on Device!")
}
addr, _ := wiresocks.ResolveIPPAndPort("engage.cloudflareclient.com:2408")
addr := endpoints[1]
if addr == "notset" {
addr, _ = wiresocks.ResolveIPPAndPort("engage.cloudflareclient.com:2408")
}
err = wiresocks.NewVtunUDPForwarder(virtualEndpointBindAddress, addr, vTUN, mtu+100)
if err != nil {
log.Fatal(err)
}

// run primary warp
runWarp(bindAddress, virtualEndpointBindAddress, "./primary/wgcf-profile.ini", verbose, true, true)
runWarp(bindAddress, []string{virtualEndpointBindAddress}, "./primary/wgcf-profile.ini", verbose, true, true)
}

func findFreePort(network string) (string, error) {
Expand Down
89 changes: 89 additions & 0 deletions wiresocks/scanner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package wiresocks

import (
"crypto/rand"
"fmt"
"github.com/bepass-org/ipscanner"
"github.com/go-ini/ini"
"log"
"net"
"time"
)

func canConnectIPv6(remoteAddr string) bool {
dialer := net.Dialer{
Timeout: 5 * time.Second,
}

conn, err := dialer.Dial("tcp6", remoteAddr)
if err != nil {
return false
}
defer conn.Close()
return true
}

func RunScan() (result []string) {
cfg, err := ini.Load("./primary/wgcf-profile.ini")
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}

// Reading the private key from the 'Interface' section
privateKey := cfg.Section("Interface").Key("PrivateKey").String()

// Reading the public key from the 'Peer' section
publicKey := cfg.Section("Peer").Key("PublicKey").String()

// new scanner
scanner := ipscanner.NewScanner(
ipscanner.WithWarpPing(),
ipscanner.WithWarpPrivateKey(privateKey),
ipscanner.WithWarpPeerPublicKey(publicKey),
ipscanner.WithUseIPv6(canConnectIPv6("[2001:4860:4860::8888]:80")),
ipscanner.WithUseIPv4(true),
ipscanner.WithMaxDesirableRTT(500),
ipscanner.WithCidrList([]string{
"162.159.192.0/24",
"162.159.193.0/24",
"162.159.195.0/24",
"188.114.96.0/24",
"188.114.97.0/24",
"188.114.98.0/24",
"188.114.99.0/24",
"2606:4700:d0::/48",
"2606:4700:d1::/48",
}),
)
scanner.Run()
var ipList []net.IP
for {
ipList = scanner.GetAvailableIPS()
if len(ipList) > 2 {
scanner.Stop()
break
}
time.Sleep(1 * time.Second)
}
for i := 0; i < 2; i++ {
result = append(result, ipToAddress(ipList[i]))
}
return
}

func ipToAddress(ip net.IP) string {
ports := []int{500, 854, 859, 864, 878, 880, 890, 891, 894, 903, 908, 928, 934, 939, 942,
943, 945, 946, 955, 968, 987, 988, 1002, 1010, 1014, 1018, 1070, 1074, 1180, 1387, 1701,
1843, 2371, 2408, 2506, 3138, 3476, 3581, 3854, 4177, 4198, 4233, 4500, 5279,
5956, 7103, 7152, 7156, 7281, 7559, 8319, 8742, 8854, 8886}

// Pick a random port number
b := make([]byte, 8)
n, err := rand.Read(b)
if n != 8 {
panic(n)
} else if err != nil {
panic(err)
}
return fmt.Sprintf("%s:%d", ip.String(), ports[int(b[0])%len(ports)])
}
24 changes: 14 additions & 10 deletions wiresocks/udpfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,44 @@ func NewVtunUDPForwarder(localBind, dest string, vtun *VirtualTun, mtu int) erro
return err
}

destAddr, err := net.ResolveUDPAddr("udp", dest)
if err != nil {
return err
}

listener, err := net.ListenUDP("udp", localAddr)
if err != nil {
return err
}

rconn, err := vtun.Tnet.Dial("udp", dest)
rconn, err := vtun.Tnet.DialUDP(nil, destAddr)
if err != nil {
return err
}

var remoteAddr *net.UDPAddr
var clientAddr *net.UDPAddr
go func() {
buffer := make([]byte, mtu)
oob := make([]byte, mtu)
n := 0
for {
n, _, _, remoteAddr, err = listener.ReadMsgUDP(buffer, oob)
n, cAddr, err := listener.ReadFrom(buffer)
if err != nil {
continue
}

rconn.Write(buffer[:n])
clientAddr = cAddr.(*net.UDPAddr)

rconn.WriteTo(buffer[:n], destAddr)
}
}()
go func() {
buffer := make([]byte, mtu)
for {
n, err := rconn.Read(buffer)
n, _, err := rconn.ReadFrom(buffer)
if err != nil {
fmt.Println("Error reading from connection:", err)
continue
}
if remoteAddr != nil {
listener.WriteMsgUDP(buffer[:n], nil, remoteAddr)
if clientAddr != nil {
listener.WriteTo(buffer[:n], clientAddr)
}
}
}()
Expand Down

0 comments on commit bec011c

Please sign in to comment.