ラベル apache の投稿を表示しています。 すべての投稿を表示
ラベル apache の投稿を表示しています。 すべての投稿を表示

2012年5月30日水曜日

mod_log_sql でアクセスログをMySQLに保存する

Apacheのmod_log_sqlモジュールを使うとアクセスログをデータベースに保存することができます。

mod_authn_dbdの場合と同様にOSはubuntu serverで、MySQLはRDSのインスタンスを使用しました。

MySQLの設定

RDSのインスタンスにてログ保存用のデータベースを作成しておきます。
create database logs;
create user apache identified by 'パスワード';
grant all on logs .* to apache;

mod_log_sqlのインストール

ubuntuのapt-getでインストールされるバージョンは古いので(確か1.10?)、ソースから1.99をインストールします。まずapt-getでapxs2をインストールします。
sudo apt-get install apache2-prefork-dev
mod_log_sql をインストールします。ソースとパッチをダウンロードし、makeしてインストールします。
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99.tar.gz
$ tar -xzvf mod_log_sql-1.99.tar.gz
$ cd mod_log_sql-1.99
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99.diff
$ patch -p0 < mod_log_sql-1.99.diff
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99-2.diff
$ patch -p0 < mod_log_sql-1.99-2.diff
$ ./configure --with-apxs=/usr/bin/apxs2
$ make
$ sudo make install

以下の内容で/etc/apache2/mods-available/log_sql.loadを作成します。
LoadModule log_sql_module /usr/lib/apache2/modules/mod_log_sql.so
LoadModule log_sql_mysql_module /usr/lib/apache2/modules/mod_log_sql_mysql.so
モジュールをロードするよう設定します。
$ sudo a2enmod log_sql

ログ出力の設定

apacheの設定にて以下の記述を追加します。この設定では、access_logテーブルにデータを保存します。テーブルが存在しない場合には初回のアクセスログ記録時に作成されます。
LogSQLLoginInfo mysql://apache:パスワード@RDSのエンドポイント/logs
LogSQLCreateTables on
LogSQLTransferLogFormat AbHhmRSsTUuv
LogSQLTransferLogTable access_log
LogSQLDBParam port 3306
LogSQLMachineID web1 
LogSQLTransferLogFormatでログ出力対象の項目を指定しています。詳細はこちらのドキュメントにあります。パフォーマンスへの影響が気になるようであれば、不要な項目は取得しない方がよいかもしれません。
また、複数のWebサーバからログを保存する場合には、LogSQLMachineIDにてマシンごとのIDを指定することができます。

この設定で作成されるaccess_logテーブルは以下のようになります。
FieldTypeNullKeyDefault
idchar(19)YESNULL
agentvarchar(255)YESNULL
bytes_sentint(10) unsignedYESNULL
child_pidsmallint(5) unsignedYESNULL
cookievarchar(255)YESNULL
machine_idvarchar(25)YESNULL
request_filevarchar(255)YESNULL
referervarchar(255)YESNULL
remote_hostvarchar(50)YESNULL
remote_lognamevarchar(50)YESNULL
remote_uservarchar(50)YESNULL
request_durationsmallint(5) unsignedYESNULL
request_linevarchar(255)YESNULL
request_methodvarchar(10)YESNULL
request_protocolvarchar(10)YESNULL
request_timechar(28)YESNULL
request_urivarchar(255)YESNULL
request_argsvarchar(255)YESNULL
server_portsmallint(5) unsignedYESNULL
ssl_ciphervarchar(25)YESNULL
ssl_keysizesmallint(5) unsignedYESNULL
ssl_maxkeysizesmallint(5) unsignedYESNULL
statussmallint(5) unsignedYESNULL
time_stampint(10) unsignedYESNULL
virtual_hostvarchar(255)YESNULL
当然ですが、、LogSQLTransferLogFormatにかかわらずテーブル構造は同じで、どの列に値が入るが変わります。

これら以外にもCookieやHTTPヘッダを記録することもできるようです。

ファイルに保存したアクセスログを取り込む手間がないはよいのですが、アクセスの都度、DBにアクセスが発生するので、パフォーマンスが求められるようなサイトで使用するのは難しいかもしれません。全くチューニングしない状態で、apache benchで簡単に測定しただけですが、実際、mod_log_sqlを使うとスループットがかなり低下しました。

mod_authn_dbd + MySQL (RDS) でBasic認証

MySQLに保存したユーザ情報を使用して、ApacheでBasic認証を行う方法です。

データベースに格納したユーザー情報を使って認証を行うためのモジュールは、Apacheの1.3系と2系でも違いますし、いろいろあってどれを使うべきなのかわかりづらいです。はじめに、Apacheクックブック 第2版に載っていたmod_authn_dbiを使おうとしたのですが、全く情報がなくmod_authn_dbdにたどり着きました。

サーバはubuntu server、DBはAmazon RDS(Relational Database Service)のMySQLで試しました。RDS上のMySQLを使うからといって特別なことはなく、mysqlコマンドでリモート接続して、データベースおよび接続するユーザーを作成し、権限を付与しておきます。

mod_authn_dbdは標準でインストールされていたのですが、MySQL用dbdドライバーがインストールされていなかったので、apt-getでインストールします。
sudo apt-get install libaprutil1-dbd-mysql
a2enmodでauthn_dbdを有効にします。
sudo a2enmod authn_dbd
Apacheの設定ファイルにて、認証の設定を行います。
DBDriver mysql
DBDParams host=<RDSエンドポイント>,user=<ユーザーID>,pass=<パスワード>,dbname=<DB名>
DBDPersist On
DBDKeep 5
DBDMax 10
DBDMin 3
DBDExptime 600
<Directory /var/www>
    AuthBasicProvider dbd
    AuthDBDUserPWQuery "SELECT encrypt(password) FROM users WHERE user = %s"
    AuthName "Please Enter Your Password"
    Authtype Basic
    require valid-user
</Directory>
DBDParamsで接続先DBを指定し、AuthDBDUserPWQueryで認証時にユーザのパスワードを取得するSQLを指定します。%sの部分にユーザIDが入ります。また、DBDPersist をOnにするとコネクションをプールします。

注意点というほどのことではありませんが、"DB***"というディレクティブは<Directory>のなかにはかけません。

Apacheを再起動して、認証が正しく行われることを確認します。Internal Server Errorが発生するなど問題がある場合にはApacheのエラーログを確認します。