From 22ef96fc67f94b187024751e71c6d605e545f9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atakan=20=C3=96zg=C3=BCn?= Date: Thu, 4 Dec 2025 04:16:40 +0300 Subject: [PATCH] vpn --- go.mod | 1 + go.sum | 2 + main.go | 202 ++++++++++++++++++++++++++++++++------------------------ 3 files changed, 119 insertions(+), 86 deletions(-) diff --git a/go.mod b/go.mod index ac31f25..be5268e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( ) require ( + github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index ac2b142..30eaa39 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/main.go b/main.go index fc49d4a..a66612b 100644 --- a/main.go +++ b/main.go @@ -1,16 +1,17 @@ package main import ( - "bufio" "context" "flag" "fmt" + "io" "log" - "os" + "net" "strings" "sync" "time" + "github.com/armon/go-socks5" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/network" @@ -21,9 +22,9 @@ import ( "github.com/multiformats/go-multiaddr" ) -const protocolID = "/onion-chat/1.0.0" +const protocolID = "/onion-proxy/1.0.0" -// IPFS'in resmi Relay sunucuları (Halka açık ve güvenilir) +// IPFS Statik Relay Listesi var relayNodes = []string{ "/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", "/ip4/147.75.76.67/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", @@ -31,7 +32,8 @@ var relayNodes = []string{ } func main() { - rendezvousString := flag.String("r", "gizli-tunel-sifresi", "Buluşma noktası için gizli kelime") + rendezvousString := flag.String("r", "gizli-tunel-sifresi", "Buluşma noktası için şifre") + proxyPort := flag.String("proxy", "", "Client modu: Yerel SOCKS5 portu (Örn: 1080)") flag.Parse() ctx := context.Background() @@ -56,46 +58,40 @@ func main() { libp2p.EnableHolePunching(), libp2p.EnableNATService(), libp2p.EnableRelay(), - - // MANUEL RELAY AYARI (Hata çözen kısım) - // Hazır fonksiyon yerine yukarıdaki listeyi kullanıyoruz. libp2p.EnableAutoRelay(autorelay.WithStaticRelays(staticRelays)), - libp2p.ForceReachabilityPrivate(), ) if err != nil { log.Fatal(err) } - fmt.Printf("[*] Düğüm Başladı ID: %s\n", h.ID()) + fmt.Printf("[*] Düğüm ID: %s\n", h.ID()) fmt.Println("[*] Küresel ağa bağlanılıyor (Bootstrapping)...") - // 3. DHT Başlat (ModeClient) + // 3. DHT Başlat kademliaDHT, err := dht.New(ctx, h, dht.Mode(dht.ModeClient)) if err != nil { log.Fatal(err) } - if err = kademliaDHT.Bootstrap(ctx); err != nil { log.Fatal(err) } - // 4. Bootstrap Düğümlerine Bağlan + // 4. Bootstrap var wg sync.WaitGroup for _, peerAddr := range dht.DefaultBootstrapPeers { peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr) wg.Add(1) go func() { defer wg.Done() - if err := h.Connect(ctx, *peerinfo); err != nil { - } + h.Connect(ctx, *peerinfo) }() } wg.Wait() fmt.Println("[+] IPFS Ağına Bağlanıldı.") - // 5. RELAY ADRESİ BEKLEME DÖNGÜSÜ - fmt.Print("[*] Bir Relay sunucusundan yer ayrılması bekleniyor...") + // 5. Relay Bekleme + fmt.Print("[*] Relay bekleniyor...") for { hasRelay := false for _, addr := range h.Addrs() { @@ -105,88 +101,122 @@ func main() { } } if hasRelay { - fmt.Println("\n[+] Relay Tüneli Hazır! Artık erişilebilirsin.") + fmt.Println("\n[+] Relay Tüneli Hazır!") break } fmt.Print(".") time.Sleep(time.Second * 1) } - // 6. Stream Handler - h.SetStreamHandler(protocolID, handleStream) + // ========================================== + // ROLLERE GÖRE AYRIŞMA (SERVER vs CLIENT) + // ========================================== - // 7. Discovery (Keşif) + // EXIT NODE (SERVER) MANTIĞI: + // Gelen tüm stream isteklerini SOCKS5 sunucusuna yönlendir. + socksConf := &socks5.Config{} + socksServer, err := socks5.New(socksConf) + if err != nil { + panic(err) + } + + h.SetStreamHandler(protocolID, func(s network.Stream) { + fmt.Println("\n[->] Tünelden yeni bir internet isteği geldi!") + // Gelen libp2p akışını doğrudan SOCKS5 sunucusuna teslim et + // SOCKS5 sunucusu internete bağlanıp cevabı stream'e geri yazacak. + socksServer.ServeConn(s) + }) + + // Discovery Başlat routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT) dutil.Advertise(ctx, routingDiscovery, *rendezvousString) - fmt.Printf("[*] '%s' frekansında yayın yapılıyor.\n", *rendezvousString) + fmt.Printf("[*] '%s' kanalında dinleniyor.\n", *rendezvousString) - // 8. Arkadaşı Ara ve Bağlan - go func() { - for { - peerChan, err := routingDiscovery.FindPeers(ctx, *rendezvousString) - if err != nil { - panic(err) - } - - for peer := range peerChan { - if peer.ID == h.ID() { - continue - } - - fmt.Printf("[?] Bulunan Peer: %s. Bağlanılıyor...\n", peer.ID) - - ctxConnect, cancel := context.WithTimeout(ctx, time.Second*30) - err := h.Connect(ctxConnect, peer) - cancel() - - if err != nil { - fmt.Printf("\x1b[31m[!] HATA: %s\x1b[0m\n", err) - continue - } - - fmt.Printf("[+] BAĞLANTI BAŞARILI! Tünel Kuruldu: %s\n", peer.ID) - - stream, err := h.NewStream(ctx, peer.ID, protocolID) - if err != nil { - fmt.Println("Stream hatası:", err) - continue - } - - rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) - go readData(rw) - go writeData(rw) - return - } - time.Sleep(time.Second * 3) - } - }() - - select {} -} - -func handleStream(s network.Stream) { - fmt.Println("\n[!] Biri tünelimize giriş yaptı!") - rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s)) - go readData(rw) - go writeData(rw) -} - -func readData(rw *bufio.ReadWriter) { - for { - str, err := rw.ReadString('\n') - if err != nil { - return - } - fmt.Printf("\x1b[32m%s\x1b[0m: %s", "Gelen", str) + // CLIENT (KULLANICI) MANTIĞI: + // Eğer -proxy 1080 bayrağı verildiyse, yerel portu dinle ve trafiği tünele at. + if *proxyPort != "" { + go startLocalProxy(ctx, h, routingDiscovery, *rendezvousString, *proxyPort) } + + select {} // Sonsuz bekleme } -func writeData(rw *bufio.ReadWriter) { - stdReader := bufio.NewReader(os.Stdin) +// startLocalProxy: Tarayıcıdan gelen trafiği yakalar ve tünele atar +func startLocalProxy(ctx context.Context, h network.Network, discovery *routing.RoutingDiscovery, rendezvous, port string) { + fmt.Println("------------------------------------------------") + fmt.Printf("[CLIENT MODU] Yerel Proxy Başlatıldı: 127.0.0.1:%s\n", port) + fmt.Println("Tarayıcının SOCKS5 ayarını buraya yönlendir.") + fmt.Println("Çıkış Düğümü (Exit Node) aranıyor...") + fmt.Println("------------------------------------------------") + + var targetPeer peer.AddrInfo + found := false + + // 1. Çıkış Düğümü Bul (Sadece bir tane bulmak yeterli) + for !found { + peerChan, err := discovery.FindPeers(ctx, rendezvous) + if err != nil { + panic(err) + } + for p := range peerChan { + if p.ID == h.LocalPeer() { + continue + } + // Bulunan kişiye bağlanmayı dene + if err := h.DialPeer(ctx, p.ID); err == nil { + fmt.Printf("[+] Çıkış Düğümü Bulundu ve Bağlandı: %s\n", p.ID) + targetPeer = p + found = true + break + } + } + if !found { + time.Sleep(time.Second * 1) + } + } + + // 2. Yerel TCP Portunu Dinle (Örn: 1080) + listener, err := net.Listen("tcp", ":"+port) + if err != nil { + log.Fatal(err) + } + for { - fmt.Print("> ") - sendData, _ := stdReader.ReadString('\n') - rw.WriteString(sendData) - rw.Flush() + // Tarayıcıdan gelen isteği kabul et + conn, err := listener.Accept() + if err != nil { + log.Println("Accept hatası:", err) + continue + } + + // Her yeni istek için tünel üzerinden yeni bir stream aç + go func(browserConn net.Conn) { + defer browserConn.Close() + + // Çıkış düğümüne stream aç + stream, err := h.NewStream(ctx, targetPeer.ID, protocolID) + if err != nil { + log.Println("Tünel açma hatası (Arkadaşın düştü mü?):", err) + return + } + defer stream.Close() + + // Veriyi İki Yönlü Kopyala (Pipe) + // Browser -> Tünel -> Arkadaş -> İnternet + // İnternet -> Arkadaş -> Tünel -> Browser + var wg sync.WaitGroup + wg.Add(2) + + go func() { + io.Copy(stream, browserConn) + wg.Done() + }() + go func() { + io.Copy(browserConn, stream) + wg.Done() + }() + + wg.Wait() + }(conn) } } \ No newline at end of file