カテゴリー別アーカイブ: オープンソース

nginxでbasic認証をhtaccessライクに設定できるモジュールを作成しました

今回nginxにてbasic認証を取り扱うファイルを公開ディレクトリに設置することで解釈してくれるモジュールを作成しました。
githubにて公開してあります。

このモジュールの振る舞いは端的にいうとapacheでいう.htaccessファイルに等しいです。
(機能的には認証のみに限定しておりますが)

インストール方法や設定ファイルのシンタックスなどについてはgithub上に公開してありますので参考にしてみてください。
設定ファイルなどはnginxの公式モジュールである、ngx_http_auth_basicと同様のものになるので、こちらも合わせて参照すると良いと思います。

nginxってbasic認証などを設定するときにはconfigurationファイルに設置してnginxを再起動するしかないんですね。
それだと結構手間になることも多いし、もしかしたら企業などにしてみたらnginxなどのミドルウェアの再起動を行える人間っていうのが限られてくることも少なく無いと思います。
ファイル設置でbasic認証を認識してくれるのであれば、多くの側面から取り回し軽くてよいかなと思って作成しました。

なおそもそも公式の見解としては、主に速度面からこのような設定ファイルをリクエスト毎にチェックするということを推奨していません。
当然そこら辺のボトルネックについては増加するということで、検証環境や開発環境などで利用すると良いかと思います。


nginx拡張モジュールをアップデートしました

先日作成しましたnginxの拡張モジュールを更新しました。
(前回の更新はこちらになります)

前回の拡張ではunixのshared memory segment上にデータを展開するようにしました。
これによって各プロセス間でユーザからのアクセス情報を共有できるといったものでした。

今回の対応では更にネットワーク上で構成された複数のnginxサーバでもデータを共有することを目的として、ネットワーク上のストレージ(今回の対応では実装としてはmemcachedを対象)に対応するようにしました。

一見ストレージとして memcached に格納できる様になっただけですが、内部的なコードはまた別の側面が改良されました。
当初は特定のストレージ、具体的にはプロセスのheap領域や前回対応したosの共有メモリセグメントにデータを置くという想定でしたが、ngxinのconfigurationファイルでストレージを指定できる方式にし、コードをほぼすべて書きなおしてあります。

これによって今現在指定できるストレージであるshmemとmemcachedに関してはソースコードが完全に分離できる形でインターフェースを切り分けています。
nginxが起動した時点でこのモジュールはconfigurationファイルを読み取り、指定されたストレージに基づいた初期化を行います。

実装としてはこのインタフェースは下記のような関数ポインタを定義した構造体として定義しており、このモジュール内部でのライフサイクルを定義しています。
例えばinit関数ポインタには各種ストレージを初期化する関数ポインタが代入されることを期待しており、update_entryでは各種ストレージ内部での更新処理を行う関数ポインタが代入されることを期待しております。

handler側ではこの構造体を元にライフサイクルを初期化〜破棄に関するまで定めており、適宜それぞれの箇所で関数を呼び出します。
ストレージ側の実装ではこれらのインタフェースを元に各種イベントにおける処理を実装することになります。

/**
 * function pointers. these behave like interface.
 */
typedef struct {
	int (*init)(ngx_cycle_t *cycle, ngx_http_access_filter_conf_t *afcf);
	void* (*get_entry)(char *key, ngx_http_access_filter_conf_t *afcf);
	storage_entry_t* (*get_data)(void *entry_p);
	void (*free_entry)(void *entry_p);
	int (*add_count)(char *key, void *data, ngx_http_access_filter_conf_t *afcf);
	int (*set_banned)(char *key, void *data, ngx_http_access_filter_conf_t *afcf);
	int (*update_entry)(char *key, void *entry_p, ngx_http_access_filter_conf_t *afcf);
	int (*create_entry)(char *key, ngx_http_access_filter_conf_t *afcf);
	int (*fin)(ngx_cycle_t *cycle, ngx_http_access_filter_conf_t *afcf);
} storage_accessor;

つまりこのnginxモジュールの中で更にストレージをモジュールとして扱い実装しており、これによりストレージは任意のものに差し替えられる拡張性を手に入れることになります。
これはすなわち、今後他のストレージを使用したいというような場合において、追加で実装したい時にはこのインタフェースで期待する関数を実装することだけで可能になります。


nginx拡張モジュールを作りました

nginxの拡張モジュールを作成してgithubにて公開しました。

DOSのような攻撃的なアクセスを制御するようなモジュールで、指定時間に指定回数のアクセスを検知すると、任意の時間403を返却するようになります。

正確に言うと以前から公開していたものなのですが、改良を加えております。以前のものはprocess固有の領域にユーザのアクセス情報を格納していたのですが、これだとworker processが増えた際にそれぞれのプロセスで処理したアクセス履歴を共有できません。
むしろ通常はworker processは複数に設定することが多いと思いますので、これはすごく大きな問題です。

なので今回ユーザからのアクセス情報をosのshared memory segmentに格納するように改良を加えました。
データ構造の変更やデータ更新時の排他制御などを付け加えた形になります。

直にメモリを操作するとか、排他制御とか、あとは開発する上でデバッガを用いたりしているので、開発過程でosの知識が身についたりして非常に嬉しい限りです。