概要
情報処理基礎演習をオンライン化しようとすると、UNIX コマンドを使った演習が幾つか問題になりました。学生の個人端末に ssh をインストールしてもらうことも考えましたが、多数の学生からの「うまく接続できません!」というサポート依頼をさばくことは絶望的です。そのため、ブラウザさえあればアクセスできるウェブベースのターミナルサーバを用意することを考えました。
と2つのソフトウェアを比較してみたところ、対話型のプログラム(例えば、telnet など)を実行できるなどの点で shellinabox の方が優れていましたので、shellinabox を採用しました。
負荷分散とセキュリティを考慮して、以下の構成をとります。
- shellinabox は、複数台のバックエンドサーバ上で実行する。
- フロントエンドサーバで、負荷分散とアクセス制御を行う reverse proxy を動かす。
バックエンドサーバに shellinabox をインストール
CentOS の場合
バックエンドサーバが CentOS の場合、shellinabox は EPEL のパッケージで配布されているので、まず EPEL のリポジトリを有効化しておくこと。
$ sudo yum install shellinabox
shellinaboxd は 4200/tcp で待ち受けるウェブサーバとして動作する。以下のように設定し、SSL を無効化しておく。
USER=shellinabox
GROUP=shellinabox
CERTDIR=/var/lib/shellinabox
PORT=4200
OPTS="--no-beep --disable-ssl --disable-ssl-menu -s /:LOGIN"
設定が完了したら、shellinaboxd を有効化・起動しておく。
$ sudo systemctl enable shellinaboxd
$ sudo systemctl start shellinaboxd
Debian の場合
バックエンドサーバが Debian の場合は、特に何も考えることなく apt でインストールできる。
$ sudo apt install shellinabox
shellinaboxd は 4200/tcp で待ち受けるウェブサーバとして動作する。以下のように設定し、SSL を無効化しておく。
SHELLINABOX_ARGS="--no-beep --localhost-only --disable-ssl --disable-ssl-menu --service /:LOGIN"
なお、以下のように --service
オプションで SSH 接続するサーバを指定すると、shellinaboxd が動作しているサーバにログインする代わりに、指定されたサーバに接続する ssh クライアントとして動作する。
SHELLINABOX_ARGS="--no-beep --localhost-only --disable-ssl --disable-ssl-menu --service /:SSH:node00.example.net"
したがって、shellinabox をバックエンドサーバにインストールする代わりに、フロントエンドサーバにインストールしておくという構成も考えられる。本稿の場合は、フロントエンドサーバの負荷を極力少なくするために、shellinabox はバックエンドサーバにインストールする構成を採った。
共通
この段階で、ブラウザで http://localhost:4200/ にアクセスすると、以下のようなログインプロンプトが表示されるはずである。実際にログインしてみて、shellinaboxd が正常に動作していることを確認しておく。
sample login:
ここまでの設定から、shellinaboxd は 4200/tcp を経由して世界中にログインプロンプトを公開するも同然のデーモンであるから、適切なアクセス制限が前段として必要なことが分かる。
負荷分散とアクセス制御を担当するフロントエンドサーバからの接続のみを受け付けるように iptables などを適切に設定しておく。
フロントエンドサーバで負荷分散とアクセス制御を行う設定
負荷分散(reverse proxy)とアクセス制御は、apache-2.4 で実現する。最初に必要なモジュールを有効化しておく。
$ sudo a2enmod proxy
$ sudo a2enmod proxy_balancer
$ sudo a2enmod lbmethod_byrequests
https://httpd.apache.org/docs/current/en/mod/mod_proxy_balancer.html の例に従って、以下のように設定する。
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://shellcluster>
BalancerMember http://node00.example.net:4200 route=0
BalancerMember http://node01.example.net:4200 route=1
BalancerMember http://node02.example.net:4200 route=2
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /shell/ balancer://shellcluster
ProxyPassReverse /shell/ balancer://shellcluster
<Location /shell/>
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shib-session
</Location>
上記設定の前半部分が負荷分散(reverse proxy)の設定で、後半部分がアクセス制御の設定である。shellinabox には、ユーザ名・パスワードの brute force attack などを抑止するための仕掛けが一切ないので、フロントエンド側でアクセス制御しておかねばならない。弊センターの場合、一定回数以上の認証失敗でロックアウトする仕組みが Shibboleth IdP に用意されているので、それを流用している。
制限
- フロントエンドでアクセス制御の認証を行なった上で、さらに shellinabox が表示するログインプロンプトにユーザ名・パスワードを入力しなければならない。
- X を必要とするプログラムは実行できない。
- vi や emacs -nw は実行可能だが、日本語を入力すると表示が乱れる。