O dialer SOCKS fornece o transporte; o pacote SSH realiza o aperto de mão SSH sobre ele. Chamar ssh.Dial depois criaria uma conexão separada em vez de usar esse transporte.

Uma função auxiliar numa aplicação que já usa x/net/proxy e x/crypto/ssh pode devolver o cliente SSH configurado:

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
}

Os nomes dos pacotes aqui são golang.org/x/net/proxy e golang.org/x/crypto/ssh. proxyAddr identifica o ouvinte SOCKS; sshAddr identifica o servidor final como host:port.

Forneça em config o usuário SSH habitual da aplicação, os métodos de autenticação e HostKeyCallback. O pacote knownhosts pode construir esse callback a partir de um arquivo known_hosts confiável. Passe o nome do host de destino para NewClientConn para que a comparação da chave do host use a identidade SSH pretendida.

O argumento nil não seleciona credenciais SOCKS. Para destinos SSH públicos permitidos, uma entrada sem conta da lista de proxies SOCKS5 pode fornecer proxyAddr se permitir o host e a porta SSH reais. Quando necessário, passe um proxy.Auth com a conta do proxy; a autenticação SSH permanece em config.

NewClient recebe os fluxos de canais e pedidos recebidos devolvidos por NewClientConn e trata essa mecânica do cliente. Feche o cliente SSH devolvido quando o trabalho terminar. O tratamento de conexões em produção também precisa de marcação limitada e de uma política de aperto de mão; esta função auxiliar apenas ilustra a entrega do transporte.

Artigos relacionados