Golangでssh Proxy経由でのssh接続を行わせる(多段プロキシ)

Golangでsshへの接続を行う際、ssh proxyはどうやってやるんだろうと思ったんで調べてみた。
実装は結構簡単で、以下のように一度Proxyにsshでログイン後、ログイン対象サーバへの接続をProxyで作成してやるという流れでいけるようだ。

■ssh_term_proxy.go(抜粋。動作するコードはこちら)

	// proxy1の情報
	proxy1Host := "proxy1.host.local"
	proxy1Port := "22"
	proxy1User := "user"
	proxy1Pass := "password"

	// targetの情報
	targetHost := "target.host.local"
	targetPort := "22"
	targetUser := "user"
	targetPass := "password"

	// sshClientConfigの作成(proxy1)
	proxy1SshConfig := &ssh.ClientConfig{
		User:            proxy1User,
		Auth:            []ssh.AuthMethod{ssh.Password(proxy1Pass)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// sshClientConfigの作成(target)
	targetSshConfig := &ssh.ClientConfig{
		User:            targetUser,
		Auth:            []ssh.AuthMethod{ssh.Password(targetPass)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// Proxy1へのsshClientの作成
	proxy1Client, err := ssh.Dial("tcp", net.JoinHostPort(proxy1Host, proxy1Port), proxy1SshConfig)
	if err != nil {
		fmt.Println(err)
	}

	// Proxy1経由でのtargetへの接続を実施
	proxy1Conn, err := proxy1Client.Dial("tcp", net.JoinHostPort(targetHost, targetPort))
	if err != nil {
		fmt.Println(err)
	}

	// TargetへのsshClientを作成
	pConnect, pChans, pReqs, err := ssh.NewClientConn(proxy1Conn, net.JoinHostPort(targetHost, targetPort), targetSshConfig)
	if err != nil {
		fmt.Println(err)
	}
	client := ssh.NewClient(pConnect, pChans, pReqs)
Sponsored Links

マルチプロキシ(多段プロキシ)もできることを確認した。
以下、サンプルコード。

■ssh_term_multiple_proxy.go(動作コードはこちら)

	// proxy1の情報
	proxy1Host := "proxy1.host.local"
	proxy1Port := "22"
	proxy1User := "user"
	proxy1Pass := "password"

	// proxy2の情報
	proxy2Host := "proxy2.host.local"
	proxy2Port := "22"
	proxy2User := "user"
	proxy2Pass := "password"

	// targetの情報
	targetHost := "target.host.local"
	targetPort := "22"
	targetUser := "user"
	targetPass := "password"

	// sshClientConfigの作成(proxy1)
	proxy1SshConfig := &ssh.ClientConfig{
		User:            proxy1User,
		Auth:            []ssh.AuthMethod{ssh.Password(proxy1Pass)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// sshClientConfigの作成(proxy2)
	proxy2SshConfig := &ssh.ClientConfig{
		User:            proxy2User,
		Auth:            []ssh.AuthMethod{ssh.Password(proxy2Pass)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// sshClientConfigの作成(target)
	targetSshConfig := &ssh.ClientConfig{
		User:            targetUser,
		Auth:            []ssh.AuthMethod{ssh.Password(targetPass)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// Proxy1へのsshClientの作成
	proxy1Client, err := ssh.Dial("tcp", net.JoinHostPort(proxy1Host, proxy1Port), proxy1SshConfig)
	if err != nil {
		fmt.Println(err)
	}

	// Proxy1経由でのProxy2への接続を実施
	proxy1Conn, err := proxy1Client.Dial("tcp", net.JoinHostPort(proxy2Host, proxy2Port))
	if err != nil {
		fmt.Println(err)
	}

	// Proxy2へのsshClientを作成
	pConnect, pChans, pReqs, err := ssh.NewClientConn(proxy1Conn, net.JoinHostPort(proxy2Host, proxy2Port), proxy2SshConfig)
	if err != nil {
		fmt.Println(err)
	}
	proxy2Client := ssh.NewClient(pConnect, pChans, pReqs)

	// Proxy2経由でのtargetへの接続を実施
	proxy2Conn, err := proxy2Client.Dial("tcp", net.JoinHostPort(targetHost, targetPort))
	if err != nil {
		fmt.Println(err)
	}

	// TargetへのsshClientを作成
	p2Connect, p2Chans, p2Reqs, err := ssh.NewClientConn(proxy2Conn, net.JoinHostPort(targetHost, targetPort), targetSshConfig)
	if err != nil {
		fmt.Println(err)
	}
	client := ssh.NewClient(p2Connect, p2Chans, p2Reqs)

 

多段プロキシとかが必要環境は多くはないと思うけど、とりあえず↑のようにしてやればできる。
地味にProxyCommandが必要無いのが個人的には気に入ってる。

 


Written by blacknon

インフラエンジニア(…のつもり)。 仕事で使うならクライアントはWindowsよりはUNIXの方が好き。 大体いつも眠い。

This article has 1 comments

  1. Pingback: Golangでhttp Proxy経由でのssh接続を行わせる | 俺的備忘録 〜なんかいろいろ〜

Leave a Comment

メールアドレスが公開されることはありません。

*