tomoyotitle.png

Chapter 12: ユーザ認証の強化

12.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 を読み込みモードでオープンすることを禁止することができるのでパスワードを平文のまま保存しています。その他のサンプルについては 12.3. 認証プログラムの例を参照してください。以下のエントリが例外ポリシーで指定されている場合を考えます:

initialize_domain /usr/sbin/sshd from any

この指定により、SSHログイン時のログインシェルのドメインは <kernel> /usr/sbin/sshd /bin/bash のようになります。なお、このドメインに対して keep_domain ディレクティブが指定されていないことを確認してください。このドメインに対しては、 auth1 スクリプトの実行だけを認め、その他のプログラムの実行を認めないようにしてください:

file execute /bin/auth1 exec.realpath="/bin/auth1"

これ以降、SSHログインをした後、ログインしたユーザは追加のログイン認証を経なければ先へ進めなくなります。もし、攻撃者による不正なログインであった場合、追加のログイン認証のメカニズムを知ることができないことでしょう。上記のスクリプトにはあなたか望む突拍子もないメカニズムを使用することができます。

追加のログイン認証を経た後のドメインには、通常の権限を与えることができます。また、例えば以下のように例外ポリシーで指定することで、それ以上ドメイン遷移を行わないようにすることもできます:

keep_domain any from <kernel> /usr/sbin/sshd /bin/bash /bin/auth1 /bin/bash
keep_domain-cerberus.png

12.2. 管理者権限の分割

この階層化構造を利用することにより、 root ユーザの権限を分割することも可能です。 /bin/auth1 のパスワード部分を変更して /bin/auth2 として保存します。 /bin/auth1 を通過することで実行されるシェルに対しては全ての動作を認めるように設定し、 /bin/auth2 を通過することで実行されるシェルに対しては限られた動作(例えばWebサーバの管理)のみを認めるように設定します:

split-domain.png

12.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

これらの認証プログラムはシステムの現在時刻に基づいて生成されるトークンを利用します。 gettoken を実行することで表示されたトークンを checktoken を実行して入力することにより認証が成功します。このサンプルプログラムはアルゴリズムが貧弱であるため、実際のシステムに適用する場合にはカスタマイズをするべきです。

groovy

この認証プログラムはパスワードの入力を求めるプロンプトを表示しますが、実際にはパスワードはチェックしません。代わりに、 /tmp/.lockme というファイルの有無をチェックし、そのファイルが存在しない場合のみ認証が成功します。これは、ブルートフォース攻撃を防ぐのに利用できます。このサンプルプログラムは攻撃者が見つけやすい場所にあるファイルを使っているため、実際のシステムに適用する場合にはカスタマイズをするべきです。

honey

この認証プログラムは、正しいパスワードを正しい時間間隔で入力した場合にのみ認証が成功します。これは、ブルートフォース攻撃を防ぐのに利用できます。

mailauth

この認証プログラムは、ワンタイムパスワードを生成し、そのパスワードを mail コマンドを利用してユーザに送信します。ユーザが受け取ったメールに書かれているワンタイムパスワードを入力することにより、ユーザ認証が成功します。このプログラムを使うには、メールサーバが必要になります。

timeauth

この認証プログラムは、 honey を他のスクリプト型プログラムのインタプリタとして利用できるように修正したものです。

また、追加のユーザ認証を行う場合、以下のサンプルプログラムも役に立つかもしれません。

falsh

これは、内部コマンドを持たないシェルです。ログインシェルとして使われる /bin/bash のようなプログラムには kill コマンドのような内部コマンドが多数含まれているため、たとえ外部コマンドの実行が TOMOYO Linux により制限されていたとしても、攻撃者は内部コマンドを用いて(例えばプロセスを強制終了させるなどの)悪事を働くことができてしまいます。追加のユーザ認証を行う場合には、攻撃者がシェルの内部コマンドを悪用するのを防ぐために、このプログラムをログインシェルとして使うことができます。

proxy

これは、単純なポート転送プログラムです。このプログラムをクライアント側で実行することで特定のポート番号からサーバに接続要求を送ることが可能になり、サーバ側のファイアウォール(例えば iptables )で接続元ポート番号に基づくフィルタリングを行うことが可能になります。