一、端口转发器
-
为了规避限制性出口控制或利用系统绕过网络分段,下面实现一个端口转发器
-
一个服务发布在公网上,客户端进来的请求需要转发到另一个本地端口,或者另一台主机;
-
或者一个公共服务需要转到多台内部服务上,轮询,按优先级等;
-
或者一个服务请求进来之前需要做请求检查,例如安全功能参数等检查,类似网关功能,只有验证通过的请求才能发送给实际服务器。
-
package main import ( "io" "log" "net" "time" ) func handler(src net.Conn) { defer src.Close() dst, err := net.DialTimeout("tcp", "192.168.135.128:8080", time.Second*6) if err != nil { log.Fatalln("Unable to connect to out host") } defer dst.Close() log.Printf("real addr:%s\n", dst.RemoteAddr()) if err := Transport(src, dst); err != nil { log.Fatalf("exchange err:%s", err) } log.Printf("data exchange over") } func Transport(rw1, rw2 io.ReadWriter) error { errc := make(chan error, 1) go func() { errc <- copyBuffer(rw1, rw2) }() go func() { errc <- copyBuffer(rw2, rw1) }() err := <-errc if err != nil && err == io.EOF { err = nil } return err } func copyBuffer(dst io.Writer, src io.Reader) error { _, err := io.Copy(dst, src) return err } func main() { l, err := net.Listen("tcp", "0.0.0.0:9999") if err != nil { log.Fatalln(err) } for { conn, err := l.Accept() if err != nil { log.Fatalln(err) } log.Printf("get a conn") go handler(conn) } }