我有一个SSH隧道,该隧道拨入服务器端点并在端口1080
上启动远程侦听器。我的目标是将所有TCP通信从该端口动态转发到隧道的客户端。虽然我可以接受TCP流,但无法在SSH隧道的客户端上找到一种方法Dial
。看来我传递的dialer
是隧道的serverConn
服务器SSH端。当我尝试remote, err := dialer.DialTCP("tcp4", local.RemoteAddr().(*net.TCPAddr), addr)
时,我在远端获得了流量拨号。我想找到一种在反向隧道上拨出客户端的方法。
我不是希望将特定端口转发到本地的特定目的地,而是希望进行更多类似于ssh -D
选项的动态端口转发。我自己在管理TCP流量的目的地,这不是问题。
我尝试从传递的ssh.NewClient
创建serverConn
,但是它需要执行SSH握手,并且Iam仅在端口1080
上接收原始TCP,因此它不是有效的SSH客户。谢谢。
func main(){
type Dialer interface {
DialTCP(net string, laddr, raddr *net.TCPAddr) (net.Conn, error)
}
// SSH server connection
sshConfig := &ssh.ClientConfig{
User: "tester",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// Connect to SSH remote server using serverEndpoint (port 22)
serverConn, err := ssh.Dial("tcp", serverEndpoint.String(), sshConfig)
if err != nil {
log.Fatalln(fmt.Printf("Dial INTO remote server error: %s", err))
}
// Listen on remote server port (port 1080)
listener, err := serverConn.Listen("tcp",
remoteEndpoint.String())
if err != nil {
log.Fatalln(fmt.Printf("Listen open port ON remote server error: %s", err))
}
defer listener.Close()
acceptSLoop(listener, serverConn)
}
func acceptSLoop(listener net.Listener, sshClient *ssh.Client) {
fmt.Printf("Listener: %s\n", listener.Addr().String())
defer listener.Close()
for {
clientConn, err := listener.Accept()
fmt.Printf("local addr %s\n", clientConn.LocalAddr())
if err != nil {
log.Fatal(err)
}
fmt.Printf("New connection found on %s\n", listener.Addr().String())
listenSConnection(clientConn, sshClient, config)
}
}
func listenSConnection(SClientConn net.Conn, sshClient
*ssh.Client) {
// In a regular SSH I need to do
// sshConn, chans, reqs, err :=
ssh.NewServerConn(SClientConn, // config will be
passed in ..)
//
// But since it's TCP handoff I am passing socket data
directly
handleSConn(SClientConn, sshClient)
}
func handleSConn(local net.Conn, dialer Dialer) {
defer local.Close()
// Both of those establish socket from "remote" ssh side (Server) not "local" ssh side (client)
remote, err := dialer.DialTCP("tcp4", local.RemoteAddr().(*net.TCPAddr), addr)
//remote, err := net.Dial("tcp4", addr.String())
// transfer bytes from local SOCKS to remote desired endpoint over SSH
transfer(local, remote)
}
// in - local SOCKS conn, out - remote desired endpoint
func transfer(in, out net.Conn) {
//.... working
}