Home  >  Article  >  Backend Development  >  How can I implement SSH port forwarding in Go?

How can I implement SSH port forwarding in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-11-05 02:12:02791browse

How can I implement SSH port forwarding in Go?

Simple SSH Port Forwarding in Go

In this article, we'll delve into creating and closing a basic TCP port forward over SSH using Go, specifically for newcomers to Go and statically typed languages. We'll provide a clear and concise solution by breaking down the process into comprehensible steps.

Background and Goal

We aim to replicate the functionality of a terminal command like "ssh -L 9000:localhost:9999 username@server" programmatically using Go. This command establishes a port forward from the local port 9000 to the remote port 9999 on the specified server.

Solution Outline

To achieve this, we'll create a local listener on port 9000 and set up an SSH client connection with the remote server. When the local port receives a request, we'll establish a connection to the remote port and forward the data back and forth.

Code Breakdown

<code class="go">package main

import (
    "io"
    "log"
    "net"
    "golang.org/x/crypto/ssh"
)

var (
    username         = "root"
    password         = "password"
    serverAddrString = "192.168.1.100:22"
    localAddrString  = "localhost:9000"
    remoteAddrString = "localhost:9999"
)

func forward(localConn net.Conn, config *ssh.ClientConfig) {
    sshClientConn, err := ssh.Dial("tcp", serverAddrString, config)
    if err != nil {
        log.Fatalf("ssh.Dial failed: %s", err)
    }
    sshConn, err := sshClientConn.Dial("tcp", remoteAddrString)
    go func() { _, err = io.Copy(sshConn, localConn) }()
    go func() { _, err = io.Copy(localConn, sshConn) }()
}

func main() {
    config := &ssh.ClientConfig{
        User: username,
        Auth: []ssh.AuthMethod{
            ssh.Password(password),
        },
    }
    localListener, err := net.Listen("tcp", localAddrString)
    if err != nil {
        log.Fatalf("net.Listen failed: %v", err)
    }
    for {
        localConn, err := localListener.Accept()
        if err != nil {
            log.Fatalf("listen.Accept failed: %v", err)
        }
        go forward(localConn, config)
    }
}</code>

Explanation

  • We create a local listener on port 9000 (localAddrString).
  • When a connection is made to the local port, we establish an SSH client connection to the server (sshClientConn).
  • We then connect to the remote port on the server (sshConn).
  • Separate goroutines are used to copy data from the local connection to the SSH connection and vice versa.
  • This allows data to be forwarded between the local and remote ports.

The above is the detailed content of How can I implement SSH port forwarding in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn