Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "net"
- "os"
- "os/signal"
- "syscall"
- "golang.org/x/crypto/ssh"
- "golang.org/x/crypto/ssh/terminal"
- )
- // @note:
- // proxy1 ... プロキシサーバ
- // target ... プロキシサーバ経由でログインするサーバ
- func main() {
- // 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)
- // -----------------------------------
- // ↓以降はプロキシの処理とは無関係なコード
- // -----------------------------------
- // Sessionを作成
- session, err := client.NewSession()
- defer session.Close()
- // キー入力を接続先が認識できる形式に変換する(ここがキモ)
- fd := int(os.Stdin.Fd())
- state, err := terminal.MakeRaw(fd)
- if err != nil {
- fmt.Println(err)
- }
- defer terminal.Restore(fd, state)
- // ターミナルサイズの取得
- w, h, err := terminal.GetSize(fd)
- if err != nil {
- fmt.Println(err)
- }
- modes := ssh.TerminalModes{
- ssh.ECHO: 1,
- ssh.TTY_OP_ISPEED: 14400,
- ssh.TTY_OP_OSPEED: 14400,
- }
- // 仮想端末のリクエスト
- err = session.RequestPty("xterm", h, w, modes)
- if err != nil {
- fmt.Println(err)
- }
- // sessionの標準入出力の処理
- session.Stdout = os.Stdout
- session.Stderr = os.Stderr
- session.Stdin = os.Stdin
- // ssh接続先でShellの起動
- err = session.Shell()
- if err != nil {
- fmt.Println(err)
- }
- // ターミナルサイズの変更検知・処理
- signal_chan := make(chan os.Signal, 1)
- signal.Notify(signal_chan, syscall.SIGWINCH)
- go func() {
- for {
- s := <-signal_chan
- switch s {
- case syscall.SIGWINCH:
- fd := int(os.Stdout.Fd())
- w, h, _ = terminal.GetSize(fd)
- session.WindowChange(h, w)
- }
- }
- }()
- err = session.Wait()
- if err != nil {
- fmt.Println(err)
- }
- }
Add Comment
Please, Sign In to add comment