2014年12月7日日曜日

Apacheモジュールのアップデート時にrestartは必要か

Apacheのモジュールをアップデートしたときに通常は再起動を行っていますが、そもそも再起動が必要なのか、gracefulだけで大丈夫だったりしないかということを調べてみました。

Apacheのモジュールロードのタイミング

モジュールをロードするコードはこのあたりだろうか。

https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c
https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c

Apache からは APR の apr_dso_load() を使っているみたいなので、APRの方を覗いてみる。
https://github.com/apache/apr/blob/1.5.1/dso/unix/dso.c

複数のOSをサポートするために #ifdef が多用されててちょっと見にくいが、Linux環境であれば dlopen() が使用されるようだ。

さて、dlopen() が使用されるということが分かったので、呼び出し元に戻る。
最初に提示したコードは load_module() の中に記述されている。
これはどこからコールされているのかというと、同じ mod_so.c の中にある。



AP_INIT_TAKE2は引数を二つもつディレクティブで、
RSRC_CONFは, の外に記述するという意味のようです。
最後の EXEC_ON_READ は名前からも推測できますが、設定が読み込まれたときに実行されます。
実行するのは二つ目の引数である load_module() です。

設定が読み込まれたときに実行されると言うことは、graceful でも大丈夫な気がします。

モジュールをアップデートしてみる

graceful でも大丈夫そうということが分かったので、実際に試してみます。
mod_hello という簡単なモジュールを作ってみます。
上記のGistの mod_hello は Hello という設定がコンフィグに出てくると、第一引数の文字列をエラーログに出力するだけのものです。
インストールは apxs で行います。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la 
httpd.conf に設定を追加します。
+LoadModule hello_module modules/mod_hello.so
+Hello world
Apache を起動します。
$ sudo apache2ctl start
 * Starting apache2 ...
[Sun Dec 07 16:11:41.528152 2014] [:notice] [pid 24998] Hello world
エラーログに "Hello world" と表示されました。
続いて、モジュールを書き換えてみます。

mod_hello.c の21行目を "Hello %s" から "Hell %s" にしてみます。
再度、モジュールをコンパイル・インストールし、graceful してみます。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la
$ sudo apache2ctl graceful
 * Gracefully restarting apache2 ...
[Sun Dec 07 16:30:57.456100 2014] [:notice] [pid 25436] Hell world
変わりました。

結論

  • モジュールをアップデートするときは graceful で十分

参考文献

追記(2015/02/01)

mod_proxy では設定が反映されなかったりすることもあるそうで、graceful だと不十分な場合もあるようです。
共有メモリを使うようなモジュールだと古い設定がそのまま使われるとかありそうなので、モジュールの中身次第では注意が必要そうです。

2014年12月6日土曜日

Gentoo で FIDO U2F Security Keyを使う


Yubicoのオンラインストアで FIDO U2F Security Key を買ってみました。
他にもFIDO U2Fに対応しているものとしては、高機能なヤツとか小さいヤツとかあり、OpenPGPに対応していると書かれているのでちょっと惹かれましたが、入門としては一番安いヤツでいいかなと思い、これを選びました。

U2Fの使い方については「Googleの二段階認証にセキュリティキーを使う」が分かりやすいですが、Linux環境で動作させる手段は記述がありませんでしたので追加で調べました。

1. 事前準備

まず、と言ってもこれ一つだけですが、ChromiumからSecurity Keyにアクセスできるようにしなければなりません。
YubicoのSecurity Keyは hiddev で提供されます。
これへアクセス出来るように udev ルールを記述する必要があります。

https://github.com/Yubico/libu2f-host/blob/master/70-u2f.rules

udev ルールは上記のGithubに上がっています。
systemd を使用している環境であれば、これで動くらしいです。

私は Gentoo で OpenRC を使用しているので上記のルールでは動作しませんでした。


上記のようにパーミッションとグループについて設定するようにしました。
Security Keyを利用するユーザは plugdev に入っている前提です。

このルールを /etc/udev/rules.d/ に放り込めば準備完了です。

2. 使用する

Google の認証に使用してみます。

https://security.google.com/settings/security/securitykey/add

Security Keys を追加するページにChromiumでアクセスし、案内に従って操作するだけです。
問題なければ、最終的に完了ボタンが押せるようになります。
udev のルールに不備がある場合は、「次にセキュリティキーを挿入してタップしてください」というメッセージが出続けると思います。


せっかくなので Gentoo Advent Calendar 2014 の6日目に登録しました。