flatray.com | 戻る
更新日時: 2023-10-15
Windowsでsshのポートフォワーディング+自動再接続を実現するプログラム
Windows で ssh のポートフォワーディングを利用するため、長らく
PortForwarder( オリジナル 、 2015年版
)を利用させていただきましたが、新しい署名アルゴリズム(ECDSA, EdDSA
等)の鍵を扱えないなどさすがに古くて困るようになってきました。
代替品を探しましたがちょうどいいものがなさそうなので、 Windows 10 /
Windows 11 の標準機能のみで実装してみました。
プログラム
- auto-pf.ps1 : プログラム本体
- ssh-add.bat : ssh-add
の実行をちょっとだけ便利にするバッチファイル
- 注意: Windows 10 / Windows 11 標準提供のサービスの ssh-agent
は、Windowsを再起動しても登録した鍵を記憶したままなので、これを使うのは初回登録時や鍵を変更する時だけになりそうです。
- auto-pf.ico : Bing Image Creator
で生成したアイコンです。 auto-pf.ps1
と同じフォルダに設置するとタスクトレイのアイコンとして使用されます。(好みのものに差し替えてくれて結構です)
対象ユーザ
こんな人にお勧めです。
- PortForwarder のポートフォワーディングを便利に使っている/いた。
- PortForwarder で新しい(今時の) OpenSSH の機能を利用したい。
- PortForwarder
のように対話的に接続先を選択できなくてもいい。
- ポートフォワーディング用のプログラムやターミナルを Windows
のタスクバーに表示させたくない。(タスクトレイに格納したい)
- ssh 接続が切断した時に自動再接続してほしい。
- ソフトウェアの新規導入に厳しい(が Windows
標準機能ならそうでもない)組織で使いたい。
- プログラムの中身を精査したい。改造したい。
- たまにハングしても笑って許せる。
ゴール(目標)
- PortForwarder の代替品となる。(置き換え可能なものを目指す)
- タスクトレイに収納される。(タスクバーを消費しない)
- SSHエージェントが利用可能。
- 1つのプログラムで複数のサーバと接続可能。
- 簡単操作。
- 十分新しい OpenSSH の機能を利用可能。
- 新しい署名アルゴリズム(ECDSA, EdDSA 等)の鍵を扱える。
- 自動再接続。
- PortForwarder
は接続が切断すると手動で再起動する必要があり、その点を改善したい。
仕様・実装
- Windows 10 / Windows 11 で標準提供される OpenSSH を利用する。
- 十分新しい OpenSSH なので新しい機能を利用可能。
- ssh 機能を外部コマンドに任せるため、このプログラム自体の ssh
機能が古くなることはない。
- ポートフォワーディングなど ssh の設定は .ssh/config で行う。
- 必要に応じて他の ssh コマンドを利用可能。
- WSL, Cygwin, MSYS2, putty (付属の plink.exe) など自分が普段利用する
sshコマンドや
SSHエージェントを使うことで、自分の環境との親和性向上が期待できる。
- ssh の設定をプログラム内に記述することも可能。
- 簡単操作。
- アイコンのダブルクリックで起動しすぐにポートフォワーディングを開始。(接続先を一々選択する必要なし)
- 二重起動した時は、先に動作しているプロセスを終了するか選択可能。(設定変更時やプログラムハングアップ時に利用可能)
- SSHエージェントを利用可能。(プログラム実行時にパスフレーズを入力する必要なし)
- 実行中はタスクトレイに収納され、タスクバーを消費しない。(必要に応じて画面表示可能)
- 接続状況をツールチップや画面で確認可能。
- 1つのプログラムで複数の接続先を同時に処理可能。
- PortForwarder は接続先毎に起動する必要があった点を改善。
- 接続先の指定は .ssh/config
のコメントに記載する。(または別途設定ファイルを用意、オプションで指定、プログラム内に記述など)
- 自動再接続。
- autossh のように、接続の切断などで
sshコマンドが終了したら sshコマンドを自動で再起動し再接続する。
- 特に Windows機がスリープから復帰した時に便利。
- 接続時にバルーンで通知。
- 参考にしたプログラムに機能があったので実装。(ただし標準では無効。オプションで有効化)
- Windows の標準機能だけで実装。
- Windows が標準提供する OpenSSH, PowerShell, .NET
だけで動作する。
- プログラムは複雑ではなく、短い(方だと思います個人的には)。
- オープンソース。
- MITライセンス。
- PowerShell スクリプトなので誰でも内容を確認可能。
- どうぞお好きに利用してください。
開発・動作確認環境
- Windows 10 (22H2)
- Windows 10 の「設定」でインストール可能な OpenSSH
(
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
)
- Windows 10 標準の PowerShell (version 5.1)
- Windows 11 (22H2)
- Windows 11 の「設定」でインストール可能な OpenSSH
(
OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3
)
- Windows 11 標準の PowerShell (version 5.1)
準備
Windows用 OpenSSH
クライアントのインストール
Windows 10 / Windows 11 の設定画面からインストールできます。
今回はこちらを使っています。
本件ではクライアントだけで十分です。サーバをインストールする必要はありません。
Microsoft の「OpenSSH
をインストールする」
あるいは GitHub にある最新版 を インストール
してください。
それ以外の ssh クライアント・エージェントでも大丈夫でしょう。 (putty
の plink.exe での動作を確認しています)
ssh-agent の設定
上記でインストールした OpenSSH の ssh-agent は Windows
のサービスとして提供されており、標準では無効になっているので、これを有効にします。
- 「コントロールパネル」→「管理ツール」→「サービス」
- 「OpenSSH Authentication
Agent」というサービスを右クリック→「プロパティ」を選んで(あるいはダブルクリックして)設定画面を開く。
- 「スタートアップの種類」を「自動」にして「適用」をクリック。
- 「開始」を押してサービスを起動。
- 「OK」を押して設定画面を閉じる。
.ssh/config
PortForwarder では OpenSSH の .ssh/config
と同等の設定ファイルを作成・利用していました。
このプログラムでは基本的に Windows 10 / Windows 11 で標準提供される
OpenSSH を利用するので、 ssh の設定ファイルは
%USERPROFILE%\.ssh\config
(例:
c:\Users\ユーザ名\.ssh\config
)となります。
ここにポートフォワーディングに必要な設定を記述してください。
設定例
PortForwarder の設定ファイルそのままでもおそらく問題ありませんが、
ssh
コマンドを対話的に利用したい場合はポートフォワーディング用のホスト名を別途用意した方が便利でしょう。
接続先のホスト名が SERVER で、普通に ssh
コマンドでログインするためのエントリがこうだとします。
Host SERVER
User YourName
これに対してポートフォワーディングするための設定は例えば次のように記述します。
# auto-pf RemoteName
Host SERVER-pf
HostName SERVER
User YourName
LocalForward localhost:5901 localhost:5901
- Host
で指定する名前にポートフォワーディングを意味する「-pf」を付ける。
- 元のエントリと区別するためなので他の文字列でもいい。
- 通常の ssh
コマンドでのログインを使わないのであれば「-pf」を付けて区別する必要は特にない。
- HostName で実際のホスト名を指定する。
- その他 LocalForward や RemoteForward
等のポートフォワーディング用の設定を追記する。
- Host 行の直前に「#
auto-pf」で始まるコメントを書くと、自動接続の対象となる。
- RemoteName
は自分にとって分かりやすい名前を付ける。コンソールやツールチップの出力に利用される。
- 付けない場合は Host の名前が利用される。
- キーワード「auto-pf」はオプションで変更可能。(後述)
- 複数のエントリで同じ RemoteName
を指定するとプログラムは正常動作しないので注意。(接続先情報をこの名前で管理するため)
接続するサーバが複数ある場合は、同じ要領で複数設定してください。
.ssh/config にコメントを書きたくない場合は、「#
auto-pf」と「Host」の行だけ書いた別のファイルを作成して -config
オプションで指定してください。
(プログラムの実装としては、指定されたファイルの「#
auto-pf」の行とその直後の「Host」の行を見て接続先を決めます。
それとは独立して sshコマンドは %USERPROFILE%\.ssh\config
を参照して接続します。 なので接続先を決めるファイルと
sshの設定ファイルは別でも構いません)
ssh-add.bat
- ssh-add.bat を適当なフォルダに設置する。(文字コードを SJIS
にしないと文字化けするかもしれません。自分の環境に合わせてください)
- 最後の ssh-add.exe
の行に書いてある秘密鍵のパスを自分の環境に合わせる。
- デスクトップなど自分の都合のいい場所にショートカットを作成する。
auto-pf.ps1
- auto-pf.ps1 を適当なフォルダに設置する。
- デスクトップなど自分の都合のいい場所にショートカットを作成する。
- ショートカットを右クリック→「プロパティ」を選択。
- 「リンク先」の先頭に以下を挿入。(末尾の -file
と元のファイル名の間にスペースを入れてください)
conhost powershell -NoProfile -ExecutionPolicy Unrestricted -file
- conhost
を明示的に指定するのは、このプログラムは従来の「Windowsコンソールホスト
=
conhost」をタスクトレイに収納できるが、新しい「Windowsコンソールホスト」は互換性がなく収納できないため。
- オプションの引数にスペースが入ってもいいように -file
を指定しています。
- 必要に応じて末尾にオプションを追加する。(後述)
sshコマンド
(必要があれば後述の ssh-add.bat で鍵を登録後) .ssh/config の Host
に書いたホスト名を指定してコンソール上で ssh
コマンドを実行し、パスフレーズの確認なしでログインできることを確認してください。
- ログイン先を追加・変更する時は特に注意してください。
- 適切な鍵が
SSHエージェントに登録されてないとパスフレーズの入力が必要となり本プログラムでは利用できません。
- 新規接続先だと以下のようなメッセージが表示されるので yes と入力し
.ssh/known_hosts に情報を保存してください。
The authenticity of host '[example.com]:22 (AAA.BBB.CCC.DDD:22)' can't be established.
ED25519 key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
使い方(運用)
ssh-add.bat
- ショートカットをダブルクリックで実行する。
- 既に鍵が登録されていればそれが表示されるので、確認の後 Ctrl+C
等で終了してください。
- 鍵が登録されてなければパスフレーズを入力してください。
auto-pf.ps1
- ダブルクリックで実行するとタスクトレイに収納されます。
- 一瞬ターミナルが表示されるのがイヤな人は、今回参考にしたページ(後述)を参照し
VBSスクリプトを導入してください。
- タスクトレイ内のアイコンをマウスオーバーすると、最後に接続した日時とプログラムを起動してからの総接続回数がツールチップで表示されます。
- ツールチップの表示はオプションで変更可能。(後述)
- アイコンを左クリックすると、ターミナルが表示され接続履歴が表示されます。もう一度左クリックするとターミナルが非表示となります。
- アイコンを右クリックすると「Exit」というメニューが表示されます。選択するとプログラムが終了します。
- このプログラムから起動した sshコマンドも合わせて終了します。
- ssh の接続が切断される等で ssh.exe が終了すると
5秒以内に再接続します。
- ショートカットのコマンドライン引数や、プログラムのカスタマイズ項目を変更した場合は、一度終了して再実行してください。
auto-pf.ps1 のオプション
-auto (0|1)
: 接続先を設定ファイルから読み出すかどうか。
- デフォルト: 1 (読み出す)
- 0
を指定した場合、プログラム先頭の「カスタマイズ」と書いてある部分での ssh
設定が必須。
-baloon (0|1)
: 接続時にバルーンを表示するかどうか。
-config CONFIG_FILE
: 接続先を記載した設定ファイル。
- デフォルト: OpenSSH のコンフィグファイル
%USERPROFILE%\.ssh\config
=
c:\Users\ユーザ名\.ssh\config
-connect [RemoteName:]SERVER[,[RemoteName:]SERVER,...]
:
接続先を指定する。
- デフォルト: なし
- このオプションを指定すると設定ファイルから接続先を読み出さない。
- 接続先をカンマで区切って複数列挙可能。
- 接続先は RemoteName:SERVER
のように名前とホスト名をコロンで連結するか、単純に SERVER
とホスト名のみを指定する。
- RemoteName は設定ファイルの「auto-pf」の後に指定する RemoteName
と同じ。省略すると SERVER が名前に利用される。
- auto-pf.ps1
のショートカットを複数用意してそれぞれ接続先を変更する時などに使える。
-errorfile (FILENAME|none)
: エラーログファイル。
- デフォルト:
%USERPROFILE%\auto-pf.error.txt
=
c:\Users\ユーザ名\auto-pf.error.txt
- FILENAME に none を指定すると出力されない。
-keyword KEYWORD
:
設定ファイルから接続先を特定するために使うコメント行のキーワード。
-logfile (FILENAME|none)
:
ログファイル。sshコマンド終了理由などが記録される。
- デフォルト:
%USERPROFILE%\auto-pf.log.txt
=
c:\Users\ユーザ名\auto-pf.log.txt
- FILENAME に none を指定すると出力されない。
-pidfile FILENAME
: PIDを出力するファイル名。
- デフォルト:
%USERPROFILE%\auto-pf.pid.txt
=
c:\Users\ユーザ名\auto-pf.pid.txt
-ssh 'SSH_COMMAND SSH_OPTION'
:
sshコマンドとオプションを指定する。
- デフォルト:
'ssh.exe -A -N -T'
- 特に空白を含む場合はシングルクォーテーションで囲んでください。
-tooltip (FORMAT|notime|none)
: ツールチップの書式。
-wait SECOND
:
再接続(sshプロセスチェック)の実行間隔。秒で指定。
接続先の選択アルゴリズムとssh設定の記述先について
- -connect も -auto 0 も指定しない:
- 接続先: 設定ファイル内のコメントを元に決定。
- ssh設定: 設定ファイル。
- -connect を指定:
- 接続先: -connect
で指定したホストのみ。(設定ファイルやプログラム内の設定は利用しない)
- ssh設定: 設定ファイル。
- -auto 0 を指定:
- 接続先:
プログラム内に記述したホストのみ。(設定ファイルは利用しない)
- ssh設定:
プログラム内に記述した設定が優先されるが、同一ホスト名での設定が設定ファイルにある場合はそちらも反映される。
注意: -connect と -auto 0
を同時に指定しないでください。(正常動作しません)
テスト
お好みで実験してみてください。
- Windows をスリープ・復帰させる。
- タスクマネージャで sshコマンドを終了する。
- サーバ側で sshdプロセスを kill する。
- etc.
正常に起動しない場合は
エラーメッセージが出ているか確認してください。
- PowerShell のコンソールを起動する。
- 次のように入力し実行:
powershell -NoProfile -ExecutionPolicy Unrestricted -file \PATH\TO\auto-pf.ps1
- 正常動作すれば、タスクトレイへの格納以外の機能が利用できます。
- エラーメッセージが出ている場合は調査対応してください。
sshポートフォワーディング以外の使い方
元にしたプログラムは「定期的にコマンドを実行する」もので、
function timer_function
の中身を変更すれば色々使えます。
今回参考にしたサイト
上記を参考に、 ssh
プロセスのチェックや(再)起動などを追加実装しました。
本当にありがとうございます。
(以上)