LoginSignup
3
1

More than 5 years have passed since last update.

LISTENできるポートをサーバ側で完全に制限できるsshリバースフォワーディングをnetcatで実現する(できませんでした!!!)

Last updated at Posted at 2018-10-27

グローバルIPアドレスを持っていないRaspberryPiに外部からsshしたいときなどに大活躍のssh -Rですが、サーバ側の一存でLISTENするポートを鍵ごとに制限する方法がopensshの本家には存在せず、SSH Reverse Port Forwarding で鍵ごとにlistenできるポートを制限するで紹介したパッチをあてて、permitremoteopenを使うと鍵ごとにbindできるポートを制限することは可能なのですが、これの話をしているのは世界中で作者と自分くらいなのでは?本家にマージされる可能性は限りなくゼロに近いので、他の方法を考えてみようと思います。

最初に思いついたのは1クライアントごとにコンテナでsshdを起動することなのですが、sshd + 1セッションで12MBくらいメモリを消費していたのでやめました。

次に、nc(netcat)をssh -Rのかわりにする方法を考えてみました。

サーバ上でncを実行し2222番でLISTENして、sshの標準入出力を通信路に使って、クライアント側で起動したncでクライアント側で起動しているsshd(22番)にアクセスします。
パイプだけだとデータの流れが一方通行なので、fifoを使ってクライアント側のncの標準出力をsshクライアントの標準入力に渡してやります。

クライアント側のコマンド
client$ cat fifo | (ssh user@ssh-server nc -l 2222) | nc localhost 22 > fifo

まるで自らの尾を喰らい続けるウロボロスのようですね。
Ouroboros.png

念の為, ncがちゃんとLISTENしているかどうか確認してみます。

サーバ側でncがLISTENしているかどうか確かめる
server$ sudo sockstat |grep 2222
user nc        32658 3  tcp4   *:2222                *:*

クライアントへのsshは, 普通にssh -Rしたときと一緒です。

サーバ側からクライアント側にsshする
server$ ssh user@localhost -p 2222

ここまでうまくいっていれば、あとは.ssh/authorized_keyscommand=nc -l 2222を設定しておけば、リバースフォワーディングのクライアントがどのポートでLISTENするのかをサーバ側の一存で決められるようになります。(なるはず。まだ試してない)

で、重要なことに気づいたんですが、ncを使っていると1セッションしかsshできない・・・
これではちょっと使い物にならない(シェルログインしながらscpとかしたいやん!)ので、別の方法を考えることにします・・・

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1