Skip to content

Instantly share code, notes, and snippets.

@jiahuif
Created October 16, 2017 06:00
Show Gist options
  • Save jiahuif/5114abf068ee07bdf0e38d2cd29601f3 to your computer and use it in GitHub Desktop.
Save jiahuif/5114abf068ee07bdf0e38d2cd29601f3 to your computer and use it in GitHub Desktop.
golang: tunnel tcp over socks5
package main
import (
"flag"
"io"
"net"
"time"
log "github.com/sirupsen/logrus"
"golang.org/x/net/proxy"
)
func pipe(src io.Reader, dst io.WriteCloser, result chan<- int64) {
defer dst.Close()
n, _ := io.Copy(dst, src)
result <- int64(n)
}
func main() {
local := flag.String("local", "127.0.0.1:8388", "address to listen")
socks5 := flag.String("proxy", "127.0.0.1:1080", "socks5 proxy")
target := flag.String("target", "www.google.com:80", "forwarding target")
flag.Parse()
lis, err := net.Listen("tcp", *local)
if err != nil {
log.WithError(err).Fatal("cannot listen")
}
for {
conn, err := lis.Accept()
if err != nil {
log.WithError(err).Warn("cannot accept")
}
go func(conn net.Conn) {
defer conn.Close()
dailer, err := proxy.SOCKS5("tcp", *socks5, nil, &net.Dialer{
Timeout: 60 * time.Second,
KeepAlive: 30 * time.Second,
})
if err != nil {
log.WithError(err).Warn("cannot initialize socks5 proxy")
return
}
c, err := dailer.Dial("tcp", *target)
if err != nil {
log.WithError(err).WithField("target", *target).Warn("cannot dial")
return
}
up, down := make(chan int64), make(chan int64)
go pipe(conn, c, up)
go pipe(c, conn, down)
<-up
<-down
return
}(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment