Closed monok-o closed 2 years ago
I wrote an example of DNS proxy through ss client and server for your reference.
package main
import (
"context"
"log"
"net"
"os"
"time"
"github.com/wzshiming/shadowsocks"
_ "github.com/wzshiming/shadowsocks/init"
)
func main() {
ctx := context.Background()
// Start remote server of Shadowsocks
ssServer, err := shadowsocks.NewSimplePacketServer("ss://aes-128-cfb:123456@127.0.0.1:0")
if err != nil {
log.Println("NewSimplePacketServer", err)
os.Exit(1)
}
// Print remote listening address
ssServer.ProxyPacket = func(ctx context.Context, network, address string) (net.PacketConn, error) {
pc, err := net.ListenPacket(network, address)
if err != nil {
return nil, err
}
log.Println("ss server to target address", pc.LocalAddr())
return pc, nil
}
err = ssServer.Start(ctx)
if err != nil {
log.Println("Start", err)
os.Exit(1)
}
// Create local client of Shadowsocks
ssClient, err := shadowsocks.NewPacketClient(ssServer.ProxyURL())
if err != nil {
log.Println("NewPacketClient", err)
os.Exit(1)
}
// Print local listening address
ssClient.ProxyPacket = func(ctx context.Context, network, address string) (net.PacketConn, error) {
pc, err := net.ListenPacket(network, address)
if err != nil {
return nil, err
}
log.Println("ss client to server", pc.LocalAddr())
return pc, nil
}
// Create DNS client
resolverClient := net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
// Use local client of Shadowsocks to connect to remote DNS server
client, err := ssClient.ListenPacket(context.Background(), "udp", ":0")
if err != nil {
return nil, err
}
addr, err := net.ResolveUDPAddr("udp", address)
if err != nil {
return nil, err
}
return &wrap{PacketConn: client, remoteAddr: addr}, nil
},
}
// Send DNS query
for i := 0; i != 3; i++ {
time.Sleep(1 * time.Second)
addresses, err := resolverClient.LookupHost(ctx, "google.com")
if err != nil {
log.Println("LookupHost", err)
os.Exit(1)
}
log.Println(addresses)
}
}
type wrap struct {
net.PacketConn
remoteAddr net.Addr
}
func (t wrap) RemoteAddr() net.Addr {
return t.remoteAddr
}
func (t *wrap) Write(b []byte) (n int, err error) {
return t.PacketConn.WriteTo(b, t.remoteAddr)
}
func (t *wrap) Read(b []byte) (n int, err error) {
n, addr, err := t.PacketConn.ReadFrom(b)
if err != nil {
return 0, err
}
if addr.String() == t.remoteAddr.String() {
return n, nil
}
return t.Read(b)
}
Hey hey, I don't really understand how to connect to a server with this library, I mean I don't understand what to do this "shadowsocks.PacketClient". I'm trying to understand with the documentation but to be honest I'm a bit new with Go and also shadowsocks, it would be really nice if it's possible to give a little example.
What I'm trying to do looks like this: UDP client -> shadowsocks client -> shadowsocks server -> UDP server
Sorry for bothering with this question.
Thank you!