PostgreSQLとは何ですか?

postgresとしても知られるPostgreSQLは、多くのWebサイトやアプリケーションのデータを処理するために使用される一般的なデータベース管理システムです。

このガイドでは、PostgreSQLデータベースを保護するためのいくつかの方法について説明します。 これにより、データの不正または悪意のある使用を防ぐことができます。

Ubuntu 12.04 VPSでこのチュートリアルの手順を完了しますが、ほとんどすべての最新のディストリビューションは同様の方法で機能するはずです。

インストール

現在PostgreSQLをまだインストールしていない場合は、次のコマンドを使用してインストールできます。

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

これで、データベースソフトウェアがシステムにインストールされます。

ピア認証

デフォルトでは、PostgreSQLはLinuxユーザーアカウントをPostgreSQLアカウントに関連付けることで認証を処理します。 これは「ピア」認証と呼ばれます。

インストール時に、Postgresはシステムへのアクセスに使用できる「postgres」と呼ばれるLinuxユーザーを作成します。 次のように入力して、このユーザーに変更できます。

sudo su - postgres

ここから、次のように入力してシステムに接続できます。

psql

パスワードなしで接続する方法に注目してください。 これは、Postgresがユーザー名で認証されているためです。

データベースソフトウェアへのアクセス以外の目的でLinuxの「postgres」ユーザーを使用しないでください。 これは重要なセキュリティ上の考慮事項です。

次のように入力して、PostgreSQLとpostgresユーザーを終了します。

\q
exit

リモート接続を許可しない

潜在的な攻撃ベクトルを削除する簡単な方法の1つは、データベースへのリモート接続を許可しないことです。 これは、UbuntuリポジトリからPostgreSQLをインストールするときの現在のデフォルトです。

ホストベースの認証ファイルを調べることで、リモート接続が許可されていないことを再確認できます。

sudo nano /etc/postgresql/9.1/main/pg_hba.conf
local   all             postgres                                peer
local   all             all                                     peer
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

上記の出力からコメントを削除しました。

ご覧のとおり、最初の2つのセキュリティ行は、適用されるスコープとして「ローカル」を指定しています。 これは、Unix/Linuxドメインソケットを使用していることを意味します。

次の2つの宣言はリモートですが、それらが適用されるホスト(127.0.0.1 /32および::1/128)を見ると、これらはローカルマシンを指定するインターフェイスであることがわかります。

データベースにリモートでアクセスする必要がある場合はどうなりますか?

リモートの場所からPostgreSQLにアクセスするには、SSHを使用してデータベースマシンに接続し、そこからデータベースへのローカル接続を使用することを検討してください。

SSH経由でPostgreSQLにtunnelアクセスして、クライアントマシンがローカルであるかのようにリモートデータベースに接続できるようにすることもできます。 SSHを介してPostgreSQLをトンネリングする方法についてはこちらをご覧ください。

もう1つのオプションは、SSL証明書を使用してアクセスを構成することです。 これにより、暗号化された情報の転送が可能になります。 このリンクを使用して、PostgreSQLでSSLを設定する方法を学ぶことができます。

PostgreSQL内のセキュリティ

プロンプトへのアクセスを保護することは重要ですが、PostgreSQL環境内でデータを保護することも重要です。 PostgreSQLは、「ロール」を使用してこれを実現します。

PostgreSQLにログインして、このセクションに従ってください。

sudo su - postgres
psql

アプリケーションごとに個別の役割を作成する

必要に応じてユーザーとデータを確実に分離できるようにする1つの方法は、アプリケーションごとに個別の役割を割り当てることです。

新しい役割を作成するには、次のように入力します。

CREATE ROLE role_name WITH optional_permissions;

割り当てることができる権限を確認するには、次のように入力します。

\h CREATE ROLE

次のように入力して、任意の役割の権限を変更できます。

ALTER ROLE role_name WITH optional_permissions;

次のように入力して、現在の役割とその属性を一覧表示します。

\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 hello     | Create DB                                      | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}
 testuser  |                                                | {}

新しいユーザーを作成し、PostgreSQLを利用するすべての新しいアプリケーションに適切な権限を割り当てます。

ユーザーを機能から分離する

ロールは、権限を処理するための柔軟な方法です。 それらはユーザーとグループのいくつかの側面を共有し、どちらかのように機能させることができます。 ロールは、他のロールのメンバーシップを持つことができます。

これにより、権限に対処するための独自の方法がいくつか提供されます。

ユーザーにloginロール(上記で説明したアプリケーションロールなど)を割り当ててから、 access ロールのメンバーシップを割り当てて、データに対して実際の機能を実行できます。

この特権の分離により、各ユーザーがよりきめ細かいレベルで実行できることを管理できます。

これをテストするために、2つのロールを作成しましょう。

CREATE ROLE login_role WITH login;
CREATE ROLE access_role;
\du
                             List of roles
  Role name  |                   Attributes                   | Member of 
-------------+------------------------------------------------+-----------
 access_role | Cannot login                                   | {}
 login_role  |                                                | {}
 postgres    | Superuser, Create role, Create DB, Replication | {}

ご覧のとおり、2つの新しい役割があり、そのうちの1つはログインできません。

これで、「access_role」が所有するデータベースを作成できます。

CREATE DATABASE demo_application WITH OWNER access_role;

これで、データベースに接続して権限をロックダウンし、「access_role」にのみテーブルを作成させることができます。

\c demo_application
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO access_role;

これをテストするには、ユーザーを「login_role」に変更し、テーブルを作成してみます。

SET ROLE login_role;
CREATE TABLE test_table(
	name varchar(25));
ERROR: permission denied for schema public

最後に、「login_role」をメンバーとして「access_role」に追加できます。 これにより、「access_role」と同じ機能にアクセスできるようになります。

ロールを「postgres」にリセットし、「access_role」内に「login_role」メンバーシップを付与してから、プロセスを再試行します。

RESET ROLE;
GRANT access_role TO login_role;
SET ROLE login_role;
CREATE TABLE test_table(
	name varchar(25));
CREATE TABLE

これは機能します。

これで、「login_role」を使用してログインし、データベースを管理できます。 これにより、このデータベースで作業する機能を簡単に追加または取り消すことができます。

結論

この記事で説明する方法は、独自のセキュリティ戦略を開発するための出発点にすぎません。 セキュリティのニーズは、さまざまなデータベースユーザーと、対応する必要のあるトラフィックの量と種類に応じて異なります。

実稼働システムにセキュリティ対策を実装する前に、セキュリティ対策のメリットとデメリットを調査することをお勧めします。 徹底的なテストを実施して、探しているコントロールが実装されていること、およびソフトウェアの合法的な使用を誤って制限していないことを確認することが不可欠です。

ジャスティン・エリングウッド