Діалер SOCKS забезпечує транспорт; пакет SSH виконує поверх нього рукостискання SSH. Виклик ssh.Dial після цього створив би окреме з'єднання замість використання цього транспорту.

Допоміжна функція в програмі, яка вже використовує x/net/proxy і x/crypto/ssh, може повернути налаштований SSH-клієнт:

func dialSSHViaSOCKS(proxyAddr, sshAddr string,
    config *ssh.ClientConfig) (*ssh.Client, error) {
    dialer, err := proxy.SOCKS5("tcp", proxyAddr, nil, proxy.Direct)
    if err != nil {
        return nil, err
    }

    conn, err := dialer.Dial("tcp", sshAddr)
    if err != nil {
        return nil, err
    }

    transport, channels, requests, err :=
        ssh.NewClientConn(conn, sshAddr, config)
    if err != nil {
        conn.Close()
        return nil, err
    }

    return ssh.NewClient(transport, channels, requests), nil
}

Назви пакетів тут — golang.org/x/net/proxy і golang.org/x/crypto/ssh. proxyAddr позначає слухач SOCKS; sshAddr позначає кінцевий сервер у вигляді host:port.

Передайте в config звичайного користувача SSH програми, методи автентифікації та HostKeyCallback. Пакет knownhosts може побудувати цей callback із довіреного файлу known_hosts. Передайте ім'я хоста призначення в NewClientConn, щоб зіставлення ключа хоста використовувало потрібну ідентичність SSH.

Аргумент nil не вибирає жодних облікових даних SOCKS. Для дозволених публічних SSH-призначень запис без облікового запису зі списку проксі SOCKS5 може дати proxyAddr, якщо він дозволяє фактичний хост і порт SSH. За потреби передайте proxy.Auth з обліковим записом проксі; автентифікація SSH залишається в config.

NewClient приймає вхідні потоки каналів і запитів, які повертає NewClientConn, і керує цією клієнтською механікою. Закривайте повернений SSH-клієнт, коли його робота завершується. Обробка з'єднань у виробництві також потребує обмеженого додзвону та політики рукостискання; ця допоміжна функція лише ілюструє передавання транспорту.

Схожі статті