ssh でフロントとバックエンドへの接続を簡単にしたい。
ssh でIP浪費するのもめんどくさい話だし。
バックエンドへの接続をもう少し楽にできたら良いんだけど。
ユーザー名でバックエンドへの接続を切り分ける
発想としていくつかある。
フロント┬────── Backend 0 ├────── Backend 1 └────── Backend 2
フロント側にアレコレする
フロントにSSHログインする場合:踏み台経由の多段ログイン
sshd_config を使う場合
sshd_config の Match を使ってフォワードする。
Match user takuya ForceCommand ssh -t backend-host
authorized_keys を使う場合
authorized_keys に登録する公開鍵に次のように書く。
Command ssh -t backend-host ssh-rsa AAAAAAAAAAAA
LDAPを使う。
LDAPの認証エントリに sshd_config/authorized_keys と同等のこと記述したらいい。
2回の認証を省略したい。
そもそも認証状態を転送できないのか? LDAPを使えばワンちゃん。Backend側がフロント側のPAMに聞きに行けばいいんだけど、依存関係が増えてもうめんどくさい。
ポート転送をかける:転送分だけポートが必要
- フロント:2201 を Backend01 22
- フロント:2202 を Backend02 22
すぐに思いつくのはポートフォワード。でもVhostに振り分けたいって要望がある時点で、ポートを開けたりIPを触りたくない前提があるわけだから、此の解決策は手軽なゆえに、多くの人は規制により使えないことが多いと思う。
NFSでマウント:ファイルを編集するだけなら
- NFSでフロント側からBackendをつなぐ
- Backendにはログインしない。
- 主にファイル編集だけなら有用
- ChrootDirectory と組み合わせて戦える
- 同一ホスト内のLXCならなおさら有効?
NFS マウント/Chroot
BackendがLXCで同一ホスト内なら、SSHログイン後の Chroot Directory や Home をアレコレすることでなんとかなる。
実はこれは意外とオススメ。NFSでマウントして触らせておくのはバックエンドサーバーのプロセスをそのまま触られないので結構バランスする。
Chroot設定。
Match Group sftpuser ChrootDirectory /var/backend/01
NFS マウント
sudo mount Backend01:/var/www /var/backend/01
もしくは、これらのマウントを sshfs で起動するスクリプトをログイン(bashrc/sshd_config/authorize_keys)に仕込めばいい。
リバースプロキシ
sshpiperd が使えるらしい
クライアント側で操作する。
クライアント側で -t オプションを付ける
クライアント側でバックエンドへの転送を、フロント側のSSHサーバーに指定をする。
ssh front-host -t ssh backend-host
クライアント側のconfig で -W オプションをつける
.ssh/config
Host backend Hostname backend Port 22 ProxyCommand ssh -W %h:%p frontend
ポート転送を掛ける
ポート転送をしてフロント側とバックエンドへの接続用に、フロント側にポートを開ける。
などで指定すればいけそう。
その他使える設定ファイル。
その他の解決方法
今回はネットワークの3レイヤあたりは余り考慮せず7レイヤをメインで考慮したのでこれらの解決策は余り検討しなかった。
SNI出来ないの?
OpenSSHの此のスレッドのこの辺り(Name based SSH proxy )で議論されてる。
I hope we do not introduce a cleartext SNI into the SSH protocol. This leaks far too much sensitive metadata for passive monitors. TLS has cleartext SNI, and it is quite difficult to figure out how to protect it from passive monitors
やろうと思えば出来るけど、SSHのプロトコルにないもんを作るのはSSHプロトコルの定義からの見直しになりそうだし、そもそもSNIはクリアテキストになってんじゃないの?そんなの実装したくねーわって丁寧な言葉で書かれてる。たぶんコレが全て答え。そのため、どうしてもやりたいなら stunnel を使う必要がある。
参考資料
https://www.infiniteloop.co.jp/blog/2016/05/user-namebase-ssh-reverse-proxy/
http://hogem.hatenablog.com/entry/2015/06/08/233000
https://github.com/tg123/sshpiper
http://yudai.arielworks.com/memo/2010/12/15/225715