Guest User

Untitled

a guest
Aug 23rd, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.90 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "net"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9.  
  10. "golang.org/x/crypto/ssh"
  11. "golang.org/x/crypto/ssh/terminal"
  12. )
  13.  
  14. // @note:
  15. // proxy1 ... プロキシサーバ
  16. // target ... プロキシサーバ経由でログインするサーバ
  17. func main() {
  18. // proxy1の情報
  19. proxy1Host := "proxy1.host.local"
  20. proxy1Port := "22"
  21. proxy1User := "user"
  22. proxy1Pass := "password"
  23.  
  24. // targetの情報
  25. targetHost := "target.host.local"
  26. targetPort := "22"
  27. targetUser := "user"
  28. targetPass := "password"
  29.  
  30. // sshClientConfigの作成(proxy1)
  31. proxy1SshConfig := &ssh.ClientConfig{
  32. User: proxy1User,
  33. Auth: []ssh.AuthMethod{ssh.Password(proxy1Pass)},
  34. HostKeyCallback: ssh.InsecureIgnoreHostKey(),
  35. }
  36.  
  37. // sshClientConfigの作成(target)
  38. targetSshConfig := &ssh.ClientConfig{
  39. User: targetUser,
  40. Auth: []ssh.AuthMethod{ssh.Password(targetPass)},
  41. HostKeyCallback: ssh.InsecureIgnoreHostKey(),
  42. }
  43.  
  44. // Proxy1へのsshClientの作成
  45. proxy1Client, err := ssh.Dial("tcp", net.JoinHostPort(proxy1Host, proxy1Port), proxy1SshConfig)
  46. if err != nil {
  47. fmt.Println(err)
  48. }
  49.  
  50. // Proxy1経由でのtargetへの接続を実施
  51. proxy1Conn, err := proxy1Client.Dial("tcp", net.JoinHostPort(targetHost, targetPort))
  52. if err != nil {
  53. fmt.Println(err)
  54. }
  55.  
  56. // TargetへのsshClientを作成
  57. pConnect, pChans, pReqs, err := ssh.NewClientConn(proxy1Conn, net.JoinHostPort(targetHost, targetPort), targetSshConfig)
  58. if err != nil {
  59. fmt.Println(err)
  60. }
  61. client := ssh.NewClient(pConnect, pChans, pReqs)
  62.  
  63. // -----------------------------------
  64. // ↓以降はプロキシの処理とは無関係なコード
  65. // -----------------------------------
  66.  
  67. // Sessionを作成
  68. session, err := client.NewSession()
  69. defer session.Close()
  70.  
  71. // キー入力を接続先が認識できる形式に変換する(ここがキモ)
  72. fd := int(os.Stdin.Fd())
  73. state, err := terminal.MakeRaw(fd)
  74. if err != nil {
  75. fmt.Println(err)
  76. }
  77. defer terminal.Restore(fd, state)
  78.  
  79. // ターミナルサイズの取得
  80. w, h, err := terminal.GetSize(fd)
  81. if err != nil {
  82. fmt.Println(err)
  83. }
  84.  
  85. modes := ssh.TerminalModes{
  86. ssh.ECHO: 1,
  87. ssh.TTY_OP_ISPEED: 14400,
  88. ssh.TTY_OP_OSPEED: 14400,
  89. }
  90.  
  91. // 仮想端末のリクエスト
  92. err = session.RequestPty("xterm", h, w, modes)
  93. if err != nil {
  94. fmt.Println(err)
  95. }
  96.  
  97. // sessionの標準入出力の処理
  98. session.Stdout = os.Stdout
  99. session.Stderr = os.Stderr
  100. session.Stdin = os.Stdin
  101.  
  102. // ssh接続先でShellの起動
  103. err = session.Shell()
  104. if err != nil {
  105. fmt.Println(err)
  106. }
  107.  
  108. // ターミナルサイズの変更検知・処理
  109. signal_chan := make(chan os.Signal, 1)
  110. signal.Notify(signal_chan, syscall.SIGWINCH)
  111. go func() {
  112. for {
  113. s := <-signal_chan
  114. switch s {
  115. case syscall.SIGWINCH:
  116. fd := int(os.Stdout.Fd())
  117. w, h, _ = terminal.GetSize(fd)
  118. session.WindowChange(h, w)
  119. }
  120. }
  121. }()
  122.  
  123. err = session.Wait()
  124. if err != nil {
  125. fmt.Println(err)
  126. }
  127. }
Add Comment
Please, Sign In to add comment