Created
October 31, 2025 03:29
-
-
Save jason19970210/98ab8532e156af01ec40602e5a4b3b25 to your computer and use it in GitHub Desktop.
go-reverse-tunnel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "io" | |
| "log" | |
| "net" | |
| "os" | |
| "golang.org/x/crypto/ssh" | |
| ) | |
| // TODO: Initialize SSH Key pair at the first time | |
| func main() { | |
| // Load your SSH private key (for authentication) | |
| key, err := os.ReadFile("/Users/macbook/.ssh/id_ed25519") | |
| if err != nil { | |
| log.Fatalf("unable to read private key: %v", err) | |
| } | |
| signer, err := ssh.ParsePrivateKey(key) | |
| if err != nil { | |
| log.Fatalf("unable to parse private key: %v", err) | |
| } | |
| // Configure the SSH client | |
| config := &ssh.ClientConfig{ | |
| User: "<username>", | |
| Auth: []ssh.AuthMethod{ | |
| ssh.PublicKeys(signer), | |
| // ssh.Password(" "), | |
| }, | |
| // For demo purposes only; in production, use a proper host key callback | |
| HostKeyCallback: ssh.InsecureIgnoreHostKey(), | |
| } | |
| // Connect to the server with the static IP address | |
| serverAddr := "<server-ip>:8022" | |
| sshClient, err := ssh.Dial("tcp", serverAddr, config) | |
| log.Printf("ssh.Dial(\"tcp\", serverAddr, config)") | |
| if err != nil { | |
| log.Fatalf("Failed to dial SSH server: %v", err) | |
| } | |
| defer sshClient.Close() | |
| // Set up remote port forwarding: | |
| // Ask the server to listen on 0.0.0.0:<random-available-port> and forward connections to the client's local SSH server (localhost:22) | |
| remoteListener, err := sshClient.Listen("tcp", "0.0.0.0:0") | |
| log.Printf("sshClient.Listen(\"tcp\", \"0.0.0.0:0\")") | |
| if err != nil { | |
| log.Fatalf("Failed to set up remote listener: %v", err) | |
| } | |
| log.Printf("Reverse SSH tunnel established: server is listening on %s\n", remoteListener.Addr().String()) | |
| // Accept incoming connections on the remote listener | |
| for { | |
| remoteConn, err := remoteListener.Accept() | |
| if err != nil { | |
| log.Printf("Failed to accept incoming connection: %v", err) | |
| continue | |
| } | |
| go handleConnection(remoteConn) | |
| } | |
| } | |
| // handleConnection forwards the remote connection to the client's local SSH server. | |
| func handleConnection(remoteConn net.Conn) { | |
| log.Printf("handleConnection()") | |
| defer remoteConn.Close() | |
| // Connect to the local SSH server on the client machine | |
| localConn, err := net.Dial("tcp", "localhost:22") // client ssh port | |
| if err != nil { | |
| log.Printf("Failed to connect to local SSH server: %v", err) | |
| return | |
| } | |
| defer localConn.Close() | |
| // Start bi-directional copy of data between the two connections | |
| go func() { | |
| if _, err := io.Copy(localConn, remoteConn); err != nil { | |
| log.Printf("Error while copying from remote to local: %v", err) | |
| } | |
| }() | |
| if _, err := io.Copy(remoteConn, localConn); err != nil { | |
| log.Printf("Error while copying from local to remote: %v", err) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment