OpenSSH クライアントの proxy -- 踏み台サーバを経由しての ssh
このような形にしている場合,DSAS にログインしようとする際は,一旦社内のサーバに ssh 接続する必要があって,小さなことですが一手間かかってしまいます.できればワンステップで接続できる方法が無いかと思って色々検索してみた(※)ところ,このページで
ProxyCommand
という設定項目を見つけました(見つけたのがボスの個人サイトなのは本当に偶然です(^^ ).
※
ProxyCommand
の記述は ssh_config(5)にあります.設定ファイルではコマンドラインオプションで指定できる以上のことが設定できる,ということに思い至らず,盲点でした.
ProxyCommand
は,OpenSSH の ssh(1) コマンドが直接ネットワーク接続を開くのではなく,指定されたコマンドを起動して,その標準入出力をネットワークの入出力の代わりに用います.起動されたコマンドは何とかして本来の目的の ssh サーバへの接続を作り,そのサーバから送られてきたデータ列を標準出力を通じて ssh クライアントに渡します.逆に ssh クライアントからサーバへ送られるデータは,このコマンドの標準入力に書き込まれますので,標準入力を受け取ったコマンドはそれを ssh サーバへ送り出します.つまり,端的に言うとネットワークと標準入出力のブリッジをしてくれるコマンドをProxyCommand
に指定すれば良いと言うことです.
ProxyCommand
に指定するコマンドとしては,connect.c がよく使われるようです.これは HTTP proxy や socks proxy に接続することができるので,一般的な Firewall の内側にいるホストから外へ ssh するときにはとても便利です.しかし今回のケースでは,外から社内のサーバ及び社内のサーバから DSAS へは直接 ssh できることが前提です.ですので「社内のサーバ」上で DSAS への ssh 接続を開いてそれを標準入出力にブリッジしてくれるコマンドがあれば,別に起動した「手元のマシン」から「社内のサーバ」に接続した ssh クライアントと組み合わせて,手元のマシン上に DSAS の ssh サーバへのネットワーク接続と標準入出力のブリッジした結果を作り出すことができます.今回「社内のサーバ」上で,DSAS の ssh サーバへの接続を標準入出力にブリッジするためのコマンドとして nc
(netcat(1)
)コマンドを使いました.今回の構成を図にすると
┏━━━手元━━━┓┏━━社内のサーバ━━┓┏━DSAS━┓ ┃ ┃┃ ┃┃ ┃ ┃ssh <===> ssh <------> sshd <====> nc <------> sshd ┃ ┗━━━━━━━━┛┗━━━━━━━━━━┛┗━━━━┛という形になります(
<==>
が標準入出力を表して,<--->
はネットワーク接続を表します).
これを実現するためには,
~/.ssh/config
に次の設定を追加します.
Host master.dsas.klab.org ProxyCommand ssh edge.intra.klab.org nc %h %pつまり,手元のマシン上で master.dsas.klab.org への ssh 接続(a)を起動すると edge.intra.klab.org へ ssh 接続(b)して nc コマンドを起動します.nc コマンドの引数には
%h
と %p
を指定していますが,これは (b) を起動する際に,(a) を起動したときの接続先のホスト名とポート番号に置き換えられます.つまり,この設定でしたら %h
は master.dsas.klab.org に,%p
は 22
に置き換えられます.
dsas.klab.org ドメインに複数のサーバがあって,それらへの接続を全て edge.intra.klab.org を踏み台にして接続したいのであれば,
Host *.dsas.klab.org ProxyCommand ssh edge.intra.klab.org nc %h %pのような記述もできます.こうしておけば master.dsas.klab.org への場合も,second.dsas.klab.org への場合も,この設定が適用されます.
この仕組みを使わずに,社内のサーバに一旦ログインした後改めて DSAS にログインする形の場合,どうしても「社内のサーバ」上に DSAS へログインするための鍵を設置するか,或いは「社内のサーバ」へログインする際に,ssh の Agent Forward の機能を使って,手元のマシン上の ssh-agent(1) に登録した鍵を「社内のサーバ」でも使えるようにする必要があります.
いずれの場合にせよ,DSAS 上で root になれる人の秘密鍵が社内のサーバ上で取得できることになるので,「社内のサーバ」と DSAS のセキュリティーレベルが同じに保たれている必要があります.会社の規模が小さい内はこの要件は概ね満たされていたのですが,規模が大きくなるにつれ社内サーバと DSAS の管理が分離されてくると,社内サーバと DSAS の扱いは明確に区別する必要が出てきました.セキュリティに関しては日々見直す必要がある,という良い例かと思います.