SOCKS가 연 연결을 Go의 SSH 클라이언트에 넘기기
x/net/proxy로 SSH 목적지에 연결한 뒤, 그 결과인 net.Conn 위에서 x/crypto/ssh를 초기화합니다.
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 패키지는 신뢰하는 known_hosts 파일로 그 callback을 만들 수 있습니다. 대상 호스트명을 NewClientConn에 넘겨 호스트 키 비교가 의도한 SSH 신원을 쓰도록 합니다.
nil 인자는 SOCKS 자격 증명을 선택하지 않습니다. 허용된 공용 SSH 대상이라면 SOCKS5 프록시 목록의 계정 없는 항목이 실제 SSH 호스트와 포트를 허용할 때 proxyAddr을 제공할 수 있습니다. 필요하면 프록시 계정이 담긴 proxy.Auth를 넘기세요. SSH 인증은 config에 그대로 남습니다.
NewClient는 NewClientConn이 돌려준 수신 채널과 요청 스트림을 받아 그 클라이언트 메커니즘을 처리합니다. 작업이 끝나면 반환된 SSH 클라이언트를 닫으세요. 운영 환경의 연결 처리는 제한된 다이얼링과 핸드셰이크 정책도 필요합니다. 이 도우미 함수는 전송 계층의 인계만 보여 줍니다.