個人的に Goでsshのクライアントコマンド を作ってるのだけど、ssh接続で使用している処理が肥大化してメンテナンスが辛くなってきたので、ライブラリとして外出しすることにした。

以下のようなことが簡単にできるように作ってある。 細かい使い方については GoDoc を参照してもらえれば…(´・ω・`)。

  • ログインシェルへの接続(Ctrl+Cとかタブ補完もできる)
  • ターミナルログの取得(タイムスタンプ付与)
  • sshやhttp,socks5の多段プロキシ接続
  • x11 forwarding
  • port forwarding
  • pkcs11認証(Yubikeyとかの物理...

Goでsshのクライアントコマンドを作ってるのだが、それにx11 forwarding機能を実装したかったのでいろいろと調べてみた。 で、以下のような通信の流れになっているので、それを踏まえて実装してみた。

  1.  sshクライアント=>sshサーバ: sshクライアント側からsshサーバ側に、「SSH_MSG_CHANNEL_REQUEST」でx11-reqを送る(RFC4254)
  2.  sshサーバ: x11の初期化処理が行われる(sshサーバ側のDISPLAY環境変数にlocalhost:6000+x11ディスプレイ番号が入り、ポートが開く)
  3.  sshサーバ => sshクライ...

最近は、Goで自作してる sshクライアントコマンド(lssh) の機能追加を主にやってる(で、こっちあまり更新してない(´・ω・`))。

実はちょっと前、下のようなツールを見かけて、それと同じようなことが自作のsshクライアントやりたいと思って機能追加していたのだけど、それがやっとできるようになった。 これが何なのかというと、sshで複数のノードにパラレル接続して、そのままプロンプト上からインタラクティブにコマンドを流せるというツールで、便利そうだしすごくかっこよさげなのだ。

An interactive parallel ssh client featuring autocom...


Golangで、パイプからの標準入力を受け付けつつ、さらにキーボードからの入力を別に受付させたいということがあった。 で、前に シェルスクリプトの場合だと/dev/ttyから受け付けすることができる 、という内容について記述したことがあったが、それと同じようにすることで実現できるようだ。

sample_keyinput_and_pipe.go
package main import ( "fmt" "io" "log" "os" "time" "golang.org/x/crypto/ssh/terminal" ) fun...

自作のsshクライアントコマンドで~/.ssh/configを読み込んで処理させる機能を追加したかったのだが、ProxyCommandがネックになっていたため今まで実装を見送っていた。 で、久しぶりになんか情報ないかなと探してみたところ、net.Pipe()を利用したら処理できるという情報を見かけた。

ProxyCommandはローカルで実行するコマンドになるので、そのコマンドの出力をPipeで繋げていけばいいようだ。なるほど…(´・ω・`)。 というわけで、さっそく実装してみた。こんな感じのコードで.ssh/configから指定したホストの情報を取得して、かつProxyCommand...


ここ最近、仕事が変わったのと Rustでこさえてたツール の改修に手間取っててあまり触ってたなかったのだけど、ある程度一段落したので Goのsshクライアントの改修 に着手した。 で、sshでの接続方式というといくつかあると思うが、最近はYubikeyをPIVカードとして利用して、Yubikey内の秘密鍵を使ってssh接続するというやり方もあるので、それをGolangで実装しようと思いやってみた。

これ、実はかなり手間取ってしまい、結構時間がかかってしまった…。 Yubikey等のPIVカードに入ってる秘密鍵を使ってssh接続する場合、OpenSCなどのPKCS11を扱えるライブラ...


前回、goでssh-agentをForwardingする処理について書いたことがあったけど、認証自体は普通にパスワードで処理するように書いていた。で、ssh-agentで認証させることもできるようなので、サンプルコードを書いてみた。

以下、サンプル(一応 こちら にもあげている)。


自前で作ってるGolangで書いたsshクライアント に、ssh-agentの機能を追加できないかなと思い調べてみたところ、ライブラリがすでに用意されているようで結構簡単に実装できそうだということがわかった。 というわけで、ssh-agentで鍵を転送できるsshクライアント(ターミナル接続可能)のサンプルコードを書いてみる。

以下、そのコード。ソースは こちら にもあげている。


自前で作ってるGolang製のsshクライアントにssh port forwardingを追加したくなったので、まずはサンプルコードを書いてみることにした。 StackOverflowにちょうどいいサンプルがあったので参考にさせてもらったところ、ターミナルセッションとは別にsshの接続をする必要がありそうだ。ポートフォワード自体はio.Copyで対応できるようだ。

以下、サンプル( こちら にもおいてある)。