それマグで!

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

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

php で pam を使う(ってはいけない)

php から ログインに Linuxのユーザー名&パスワードを使ってみよう

Linux のログインには、PAMが使われるのが一般的。 PAM を使うことでLinuxのユーザー名で認証ができる。

今回は PHPの pam を使って認証してみる

ただし、このやり方は試験的にやってるのであっていかなる時も、公開用本番サーバーに適用してはいけない。

準備

準備するのは次のモノを準備する。

  • php-pam
  • php.ini
  • pam.d
  • shadow

php-pam のインストール

インストールはいつものとおり、拡張機能のインストール手順でやる。

curl https://pecl.php.net/get/pam-1.0.3.tgz | tar zxvf -
cd pam-1.0.3
phpize
./configure && make && make test
sudo make install

php.ini の設定を作る

php.ini の設定でextension をロードするように作ります。

sudo sh -c "echo extensions=pam.so > /etc/php/conf.d/pam.ini"

apache の再起動

ここで、Apacheの再起動。

再起動して pam がロードされたか確認する。

pam.d を作る

sudo sh -c "@include common-auth > /etc/pam.d/php"

PAM 側に PHP が利用できる pam の設定を書いておく。PHPがPAMに認証を訊くとき、どのように認証するかここで決める。

最後に apahce が shadow を読めるようにする

ココが危険なんだけどさ。。。

sudo usermod -aG shadow apache

Apache が /etc/shadow ファイルを閲覧できるようにする。

危険すぎて公開サーバーでやると大変な目に遭う。

最後に php から pamを使う

<?php 
$error = "";
$res = pam_auth("takuya_1st", "password", $error) ;

if ( $res ){
 echo "ok"
} else {
var_dump( $error );
}

これで全部できる。

でも、安全に使えない

Apacheに mod_php を入れている状態では、全てのphp コードが、 apacheユーザーで動作している。

だから、apacheユーザーに /etc/shadow の読取り権限を与えると、とても危険。

echo file_get_contents("/etc/shadow");

はい、読めます読めます。

まぁ、shadow ファイルからパスワードが漏れることはないんだけど。

shadow は万が一の危険のために、一般ユーザーから見えない場所に、隔離してハッシュ値を保存しています。

apache は mod_php で任意のプログラムを「容易」に実行できる。容易にshadow ファイルを読めてしまう。

だれでもphpファイルを自由に配置できるってことが多い状況下では

これでは、大変困りますね。安全障壁を1つ減らすのですから。

ハッシュが漏れたら危険なのは、レインボーテーブルの存在です。カンタンなパスワードだと突き止められてしまいます。

ではどうするか。

php でどうしてもやりたいなら php-cgi で setuid ですかね。それか suexec を掛けるしかない。

それか、諦めて、shadowパーミッションをつける。まぁハッシュテーブルだし漏れたとしても。即死レベルの危険じゃないし・・・。

それか、mysql をPAM 化して、 pdo コネクションを作って見る。

それか、true/falseを返すだけのシェルを作る。

php pam で検索すると、Stack overflow などにも pam 使えと気軽な感じに書いてあって、php'er のヤンチャぶりを感じました。