Apache が提供する情報を制限する ServerTokens 編

サーバの防衛の基本として、「攻撃者に多くの情報を提供しない」というものがあります。

現実に当てはめれば『独り暮らし』『平日の午前中は留守が多い』『セコムしてません』などの情報は 極力知られない方が良い、というのと同じですね。

今回は 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 のセッションの情報を取り出す関数

PostgreSQL には SQL でセッションの情報を取得する関数が 色々と定義されています。 簡単に紹介していきたいと思います。

version()

接続した PostgreSQL サーバのバージョンの文字列を返します。

db1=# SELECT version();
                                                version            
-------------------------------------------------------------------
 PostgreSQL 8.3.5 on i386-redhat-linux-gnu, compiled by GCC gcc (GC
(1 row)

current_database()

接続した データベースの名前を返します。

$ psql db1 postgres

db1=# SELECT current_database();
 current_database
------------------
 db1
(1 row)

current_schema()

現在のスキーマ名を返します。

接続した直後は、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)

検索パスにスキーマを複数指定した場合は、先頭のスキーマが 現在のスキーマとなります。

current_schemas(boolean)

検索パス内のスキーマを返します。 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)

session_user

データベースに接続したユーザ名を返します。

$ 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 と 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 を含め、ユーザ系は特殊で、括弧 () を付けずに 呼び出す必要があるので注意しましょう。

Google サイト内検索

Amazonアソシエイト