Chapter 10: ユーザ認証の強化
10.1. 不正なSSHログイン
例えばSSHのブルートフォース攻撃やインターネットに接続されている他のサーバの脆弱性を攻撃することで不正にログインされる場合があります。 TOMOYO Linux を用いてドメインを階層化することにより、追加のユーザ認証を行う防御層を配備することが可能になります。 TOMOYO Linux であれば、好きな回数だけログイン認証を強制することができます。以下のようなスクリプトを考えてみましょう:
#! /bin/sh -p read -r -s -e -p "Password: " password sleep 2 if [ "$password" = "123456" ]; then exec $SHELL else echo "Authentication failed." fi
このスクリプトを auth1 と呼ぶことにします。 auth1 を実行可能にして /bin/ ディレクトリに置いてください。これはサンプルのスクリプトですが、強制アクセス制御機能により auth1 を読み込みモードでオープンすることを禁止することができるのでパスワードを平文のまま保存しています。その他のサンプルについては 10.3. 認証プログラムの例を参照してください。以下のエントリが例外ポリシーで指定されている場合を考えます:
initialize_domain /usr/sbin/sshd
この指定により、SSHログイン時のログインシェルのドメインは <kernel> /usr/sbin/sshd /bin/bash のようになります。なお、このドメインに対して keep_domain ディレクティブが指定されていないことを確認してください。このドメインに対しては、 auth1 スクリプトの実行だけを認め、その他のプログラムの実行を認めないようにしてください:
allow_execute /bin/auth1
これ以降、SSHログインをした後、ログインしたユーザは追加のログイン認証を経なければ先へ進めなくなります。もし、攻撃者による不正なログインであった場合、追加のログイン認証のメカニズムを知ることができないことでしょう。上記のスクリプトにはあなたか望む突拍子もないメカニズムを使用することができます。
追加のログイン認証を経た後のドメインには、通常の権限を与えることができます。また、例えば以下のように例外ポリシーで指定することで、それ以上ドメイン遷移を行わないようにすることもできます:
keep_domain <kernel> /usr/sbin/sshd /bin/bash /bin/auth1 /bin/bash
10.2. 管理者権限の分割
この階層化構造を利用することにより、 root ユーザの権限を分割することも可能です。 /bin/auth1 のパスワード部分を変更して /bin/auth2 として保存します。 /bin/auth1 を通過することで実行されるシェルに対しては全ての動作を認めるように設定し、 /bin/auth2 を通過することで実行されるシェルに対しては限られた動作(例えばWebサーバの管理)のみを認めるように設定します:
10.3. 認証プログラムの例
以下のスクリプトは上記で使用したものと同じですが、パスワードをハッシュ値で保存するようにしています:
echo "password" | sha1sum
c8fed00eb2e87f1cee8e90ebbe870c190ac3848c -
#!/bin/sh -p hash="c8fed00eb2e87f1cee8e90ebbe870c190ac3848c -" read -r -s -e -p "Password: " password hash_attempt="$(echo "$password" | sha1sum)" sleep 2 if [ "$hash_attempt" = "$hash" ]; then exec $SHELL else echo "Authentication failed" fi
ユーザ認証プログラムのサンプルを以下に示します。ただし、これらのプログラムは独自のユーザ認証プログラムを作成する際の参考にしてもらうために用意されているものです。アルゴリズムが貧弱で実際のシステムにそのまま適用するには不向きなものも含まれています。以下のプログラムのソースコードは subversion レポジトリからダウンロードできます。
candy | この認証プログラムは、親プロセス(例えば /bin/bash )が起動されてから10秒以内に開始して、かつ正しいパスワードを入力した場合にのみ認証が成功します。このプログラムが時間内に開始されなかった場合、正しいパスワードを入力しても先へ進むことはできません。攻撃者は正しいパスワードを入力しても先へ進めないことを知らないため、ブルートフォース攻撃を防ぐのに役に立ちます。 |
chaplet | この認証プログラムは、チャレンジとして文字列を表示し、チャレンジ文字列中に含まれる数値のみをレスポンスとして入力した場合にのみ認証が成功します。このサンプルプログラムはアルゴリズムが貧弱であるため、実際のシステムに適用する場合にはカスタマイズをするべきです。 |
checktoken/gettoken | これらの認証プログラムはシステムの現在時刻に基づいて生成されるトークンを利用します。 |
groovy | この認証プログラムはパスワードの入力を求めるプロンプトを表示しますが、実際にはパスワードはチェックしません。代わりに、 /tmp/.lockme というファイルの有無をチェックし、そのファイルが存在しない場合のみ認証が成功します。これは、ブルートフォース攻撃を防ぐのに利用できます。このサンプルプログラムは攻撃者が見つけやすい場所にあるファイルを使っているため、実際のシステムに適用する場合にはカスタマイズをするべきです。 |
honey | この認証プログラムは、正しいパスワードを正しい時間間隔で入力した場合にのみ認証が成功します。これは、ブルートフォース攻撃を防ぐのに利用できます。 |
mailauth | この認証プログラムは、ワンタイムパスワードを生成し、そのパスワードを |
timeauth | この認証プログラムは、 |
また、追加のユーザ認証を行う場合、以下のサンプルプログラムも役に立つかもしれません。
falsh | これは、内部コマンドを持たないシェルです。ログインシェルとして使われる /bin/bash のようなプログラムには |
proxy | これは、単純なポート転送プログラムです。このプログラムをクライアント側で実行することで特定のポート番号からサーバに接続要求を送ることが可能になり、サーバ側のファイアウォール(例えば |