This commit is contained in:
Atakan Özgün
2025-12-04 04:16:40 +03:00
parent b7af675930
commit 22ef96fc67
3 changed files with 119 additions and 86 deletions

1
go.mod
View File

@@ -9,6 +9,7 @@ require (
) )
require ( require (
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
github.com/benbjohnson/clock v1.3.5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect

2
go.sum
View File

@@ -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= 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/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/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 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=

176
main.go
View File

@@ -1,16 +1,17 @@
package main package main
import ( import (
"bufio"
"context" "context"
"flag" "flag"
"fmt" "fmt"
"io"
"log" "log"
"os" "net"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/armon/go-socks5"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht" dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/network"
@@ -21,9 +22,9 @@ import (
"github.com/multiformats/go-multiaddr" "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{ var relayNodes = []string{
"/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", "/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/ip4/147.75.76.67/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", "/ip4/147.75.76.67/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
@@ -31,7 +32,8 @@ var relayNodes = []string{
} }
func main() { 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() flag.Parse()
ctx := context.Background() ctx := context.Background()
@@ -56,46 +58,40 @@ func main() {
libp2p.EnableHolePunching(), libp2p.EnableHolePunching(),
libp2p.EnableNATService(), libp2p.EnableNATService(),
libp2p.EnableRelay(), 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.EnableAutoRelay(autorelay.WithStaticRelays(staticRelays)),
libp2p.ForceReachabilityPrivate(), libp2p.ForceReachabilityPrivate(),
) )
if err != nil { if err != nil {
log.Fatal(err) 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)...") 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)) kademliaDHT, err := dht.New(ctx, h, dht.Mode(dht.ModeClient))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err = kademliaDHT.Bootstrap(ctx); err != nil { if err = kademliaDHT.Bootstrap(ctx); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// 4. Bootstrap Düğümlerine Bağlan // 4. Bootstrap
var wg sync.WaitGroup var wg sync.WaitGroup
for _, peerAddr := range dht.DefaultBootstrapPeers { for _, peerAddr := range dht.DefaultBootstrapPeers {
peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr) peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
if err := h.Connect(ctx, *peerinfo); err != nil { h.Connect(ctx, *peerinfo)
}
}() }()
} }
wg.Wait() wg.Wait()
fmt.Println("[+] IPFS Ağına Bağlanıldı.") fmt.Println("[+] IPFS Ağına Bağlanıldı.")
// 5. RELAY ADRESİ BEKLEME DÖNGÜSÜ // 5. Relay Bekleme
fmt.Print("[*] Bir Relay sunucusundan yer ayrılması bekleniyor...") fmt.Print("[*] Relay bekleniyor...")
for { for {
hasRelay := false hasRelay := false
for _, addr := range h.Addrs() { for _, addr := range h.Addrs() {
@@ -105,88 +101,122 @@ func main() {
} }
} }
if hasRelay { if hasRelay {
fmt.Println("\n[+] Relay Tüneli Hazır! Artık erişilebilirsin.") fmt.Println("\n[+] Relay Tüneli Hazır!")
break break
} }
fmt.Print(".") fmt.Print(".")
time.Sleep(time.Second * 1) 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:
routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT) // Gelen tüm stream isteklerini SOCKS5 sunucusuna yönlendir.
dutil.Advertise(ctx, routingDiscovery, *rendezvousString) socksConf := &socks5.Config{}
fmt.Printf("[*] '%s' frekansında yayın yapılıyor.\n", *rendezvousString) socksServer, err := socks5.New(socksConf)
// 8. Arkadaşı Ara ve Bağlan
go func() {
for {
peerChan, err := routingDiscovery.FindPeers(ctx, *rendezvousString)
if err != nil { if err != nil {
panic(err) panic(err)
} }
for peer := range peerChan { h.SetStreamHandler(protocolID, func(s network.Stream) {
if peer.ID == h.ID() { fmt.Println("\n[->] Tünelden yeni bir internet isteği geldi!")
continue // 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' kanalında dinleniyor.\n", *rendezvousString)
// 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)
} }
fmt.Printf("[?] Bulunan Peer: %s. Bağlanılıyor...\n", peer.ID) select {} // Sonsuz bekleme
}
ctxConnect, cancel := context.WithTimeout(ctx, time.Second*30) // startLocalProxy: Tarayıcıdan gelen trafiği yakalar ve tünele atar
err := h.Connect(ctxConnect, peer) func startLocalProxy(ctx context.Context, h network.Network, discovery *routing.RoutingDiscovery, rendezvous, port string) {
cancel() 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 { if err != nil {
fmt.Printf("\x1b[31m[!] HATA: %s\x1b[0m\n", err) panic(err)
}
for p := range peerChan {
if p.ID == h.LocalPeer() {
continue 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)
}
}
fmt.Printf("[+] BAĞLANTI BAŞARILI! Tünel Kuruldu: %s\n", peer.ID) // 2. Yerel TCP Portunu Dinle (Örn: 1080)
listener, err := net.Listen("tcp", ":"+port)
stream, err := h.NewStream(ctx, peer.ID, protocolID)
if err != nil { if err != nil {
fmt.Println("Stream hatası:", err) log.Fatal(err)
}
for {
// Tarayıcıdan gelen isteği kabul et
conn, err := listener.Accept()
if err != nil {
log.Println("Accept hatası:", err)
continue continue
} }
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) // Her yeni istek için tünel üzerinden yeni bir stream aç
go readData(rw) go func(browserConn net.Conn) {
go writeData(rw) 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 return
} }
time.Sleep(time.Second * 3) 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()
}() }()
select {} wg.Wait()
} }(conn)
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)
}
}
func writeData(rw *bufio.ReadWriter) {
stdReader := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
sendData, _ := stdReader.ReadString('\n')
rw.WriteString(sendData)
rw.Flush()
} }
} }