それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

バックエンドへのssh のユーザー名で接続先を振り分ける(SSHプロキシ的な踏み台サーバーの作成

ssh でフロントとバックエンドへの接続を簡単にしたい。

ssh でIP浪費するのもめんどくさい話だし。

バックエンドへの接続をもう少し楽にできたら良いんだけど。

ユーザー名でバックエンドへの接続を切り分ける

発想としていくつかある。

フロント┬────── Backend 0
    ├────── Backend 1
    └────── Backend 2

フロント側にアレコレする

フロントにSSHログインする場合:踏み台経由の多段ログイン

  • authorized_keys をつかう
  • /etc/sshd/sshd_config を使う
  • LDAPなどを使う

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でマウント:ファイルを編集するだけなら

  1. NFSでフロント側からBackendをつなぐ
  2. Backendにはログインしない。
  3. 主にファイル編集だけなら有用
  4. ChrootDirectory と組み合わせて戦える
  5. 同一ホスト内の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

ポート転送を掛ける

ポート転送をしてフロント側とバックエンドへの接続用に、フロント側にポートを開ける。

などで指定すればいけそう。

その他使える設定ファイル。

  • ForceCommand
  • ~/.ssh/environment
  •  ~/.ssh/rc
  • /etc/ssh/sshrc

その他の解決方法

今回はネットワークの3レイヤあたりは余り考慮せず7レイヤをメインで考慮したのでこれらの解決策は余り検討しなかった。

  • SSL で CONNECT でSocksプロキシを使う
  • stunnel を使う
  • openVPNを使う
  • ssh/tun-tap を使う。

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

http://tsuchinoko.dmmlabs.com/?p=1387

Name based SSH proxy