サーバの防衛の基本として、「攻撃者に多くの情報を提供しない」というものがあります。
現実に当てはめれば『独り暮らし』『平日の午前中は留守が多い』『セコムしてません』などの情報は 極力知られない方が良い、というのと同じですね。
今回は Web サーバ Apache の情報制限です。
CentOS などでは、 Apache をインストールすると デフォルトでは ServerTokens ディレクティブは次のように "OS" が設定されています。 (設定ファイルは /etc/httpd/conf/httpd.conf です)
ServerTokens OS
この場合、Webサーバにアクセスすると次のような値が戻ります。
HTTP/1.1 403 Forbidden
Date: Tue, 02 Feb 2010 05:36:28 GMT
Server: Apache/2.2.3 (CentOS)
Accept-Ranges: bytes
Content-Length: 5043
Connection: close
Content-Type: text/html; charset=UTF-8
Server: を見ると "Apache/2.2.3 (CentOS)" のように バージョン番号から OS まで 出力してしまっています。
これでは、仮に 2.2.3 に重大なセキュリティホールがあった場合、狙ってくださいと 言ってるようなものですよね。
というわけで、これを表示させないように変更します。
ServerTokens ProductOnly
このように設定すると、表示が "Apache" だけになります。
HTTP/1.1 403 Forbidden
Date: Tue, 02 Feb 2010 05:38:45 GMT
Server: Apache
Accept-Ranges: bytes
Content-Length: 5043
Connection: close
Content-Type: text/html; charset=UTF-8
ServerTokens ディレクティブの デフォルト値は "Full" で、 これ以上は隠せないようです。
ちなみにこの設定は ServerSignature の表示内容にも影響します。 ServerSignature については、また次回。
PostgreSQL には SQL でセッションの情報を取得する関数が 色々と定義されています。 簡単に紹介していきたいと思います。
接続した PostgreSQL サーバのバージョンの文字列を返します。
db1=# SELECT version();
version
-------------------------------------------------------------------
PostgreSQL 8.3.5 on i386-redhat-linux-gnu, compiled by GCC gcc (GC
(1 row)
接続した データベースの名前を返します。
$ psql db1 postgres db1=# SELECT current_database(); current_database ------------------ db1 (1 row)
現在のスキーマ名を返します。
接続した直後は、postgresql.conf の search_path パラメータの 定義に依存した値を返します。 検索パスが空の場合は NULL を返します。
db1=# SELECT current_schema();
current_schema
----------------
public
(1 row)
CREATE TABLE などをする際に、スキーマ名を明示的に 定義しない場合、このスキーマ名が設定されます。
検索パスは set で変えることができます。
db1=# set search_path = 'hogehoge'; db1=# SELECT current_schema(); current_schema ---------------- hogehoge (1 row) db1=# set search_path = 'public','hogehoge'; db1=# SELECT current_schema(); current_schema ---------------- public (1 row)
検索パスにスキーマを複数指定した場合は、先頭のスキーマが 現在のスキーマとなります。
検索パス内のスキーマを返します。 boolean に true をセットすると暗黙のスキーマも返します。
db1=# SELECT current_schemas(false); current_schemas ----------------- {postgres,public} (1 row) db1=# SELECT current_schemas(true); current_schemas ----------------- {pg_catalog,postgres,public} (1 row)
データベースに接続したユーザ名を返します。
$ psql db1 postgres db1=# SELECT session_user; session_user -------------- postgres (1 row) db1=# \q $ psql db1 hogehoge db1=# SELECT session_user; session_user -------------- hogehoge (1 row)
current_user と user は同じです。
current_user は、現在実行しているユーザ名を返します。 通常は session_user と同じですが、 SECURITY DEFINER 属性が付いた関数を実行した場合に 返す値が違ってきます。 SECURITY DEFINER 属性は、関数を作成したユーザの権限で 実行するオプションです。
$ psql db1 postgres db1=# SELECT session_user, current_user; session_user | current_user --------------+-------------- postgres | postgres (1 row)
SECURITY DEFINER 属性を付けた関数 test1() と 付けていない test2() を hogehoge ユーザで作成してみます。
$ psql db1 hogehoge db1=# SCREATE FUNCTION test1() RETURNS name AS 'SELECT current_user;' SECURITY DEFINER LANGUAGE SQL ; CREATE FUNCTION db1=# SCREATE FUNCTION test2() RETURNS name AS 'SELECT current_user;' LANGUAGE SQL ; CREATE FUNCTION
これを postgres ユーザで実行します。
$ psql db1 postgres db1=# select test1(); test1 ----------- hogehoge (1 row) db1=# select test2(); test1 ----------- postgres (1 row)
異なる値を返しました。 このように実際に実行している権限を確認する場合に current_user を使用します。
また、session_user を含め、ユーザ系は特殊で、括弧 () を付けずに 呼び出す必要があるので注意しましょう。