備忘録的プログラミングリファレンス

ユーザー(ロール)管理

 PostgreSQL では、ユーザー管理は一括してロールで行います。バージョン 8.1 以降では、ユーザーによる PostgreSQL データベースへの直接認証はできなくなりました。

 PostgreSQL におけるユーザー管理、ユーザーの登録やデータベースへの接続認証はロールによって管理します。ロールは、OS 上のユーザーとは異なり、PostgreSQL 内部の概念です。

 ロールは、データ操作における認証と PostgreSQL への接続を管理するもので、ユーザーとグループの意味を含んでいます。
 ロールにはグループの概念はなく、ロールにロールを包含させることでグループのような管理を行います。複数のロールを管理するロールを作成することで、グループ管理と同様の機能を実現します。この点が、従来のユーザー管理との大きな違いです。

 データベースとのデータのやりとり(アクセス)には、「 認証 → データベースごとアクセス制限 → データの操作制限 」といったことが自動でチェックされます。

 ロールによって設定できるのは、アクセス制限やデータ操作制限です。

 PostgreSQLのロールは、データベース・クラスタ(インスタンス)ごとに設定され、クラスタ内で共有されます。データベースごとにロールの設定はできません。

 この点は、ロール管理において注意すべき点です。

 認証に関しては、pg_hba.conf ファイルによって外部接続による認証を許可するのか、ローカルのみに許可するのか、全く許可しないかといった設定ができます。

 ロールには以下のような特性を含みます。

ロールの特性

  • 1つのロールに、複数のロール、ロールグループを設定できる。
  • データベースごとに、ロールによるアクセス制限を設定できる(CREATE ROLE 時に設定)。認証形式については、pg_hba.conf ファイルの認証方式を設定する。
  • データの操作制限は、ロールによる閲覧、更新、新規作成、削除といった操作を制限ができる(GRANT 文によって設定する)。カラムごとにも制限も可能。このことをポリシーを設定すると呼ばれたりする。
    レコードごとのロールによる操作制限は、RLS(Row Level Security)によって設定できる。

 ロールに関する、認証、アクセス制限、データ操作制限は複数の設定方法にまたがっています。最初は混乱することでしょう。

- ad -

スーパーユーザー postgres について

 多くの場合 PostgreSQL の初期管理者ロールはpostgresに設定されています。postgresロールはスーパーユーザーとも呼ばれます。

 このpostgresユーザーは PostgreSQL のインストール時に OS 上のユーザーとしても作成されています。そのため、以下のように端末からsuコマンドでログインができます。

su でユーザー切り替え
$ sudo su postgres
..

 初期の状態では postgres ユーザーにパスワードは設定されていませんが、sudo でログインすることができます。PostgreSQL の初期設定は、この postgres ユーザーで行います。

 公開サーバーとして運用する場合、postgres ユーザーにパスワードを設定しない、あるいは外部からのログインを制限するなどのセキュリティ対策が不可欠です。

 postgres ユーザーは PostgreSQL の起動ユーザーとして使用されている可能性があるため、安易に削除すると PostgreSQL が起動できなくなることがあります。 削除を検討する際は、慎重な検討が必要です。

 初期のデータベースクラスタは、本格的な運用には適さない場合があります。必要に応じて、新しいデータベース・クラスタ(インスタンス)を新規に作成することも可能です。

 初期の認証設定ファイル(pg_hba.conf)では、スーパーユーザーに対してPeer認証が設定されており、ログインした上でPostgreSQLへの接続が許可されます。 Peer認証の詳細については、関連ドキュメントのログイン認証とロールセクションをご参照ください。

ロールについて

 OS 上のユーザーで PostgreSQL データベースに接続できます。これは、PostgreSQL のロールと同じ名称のユーザーが OS 上にあり、pg_hba.conf ファイルで Peer 接続による認証が設定されているためです。

 例えば、以下のように OS の端末で user_a ユーザーに切り替え後に psql でログインしたとします。

postgres で psql にログイン
-- ユーザー user_a で psql にログイン --
user_a@user-PC:/home/user_a$ psql
psql (10.16 (Ubuntu 10.16-0ubuntu0.18.04.1))
Type "help" for help.

user_a=#

 すんなりとログインできる場合は、ユーザー名 user_a と同じ名称がロールでも管理されており、Peer 接続で認証が許可されているためです。

 もしもOS上のユーザーで psql にログインできない場合は、PostgreSQL に該当するロールが登録されていないためです。ロールを追加するには以下のロール(ユーザー)の追加を参照してください。

 ロールはユーザーの読み替えと思われますが扱いは別物です。PostgreSQL では、登録されたロールで接続・データ操作を行います。
 PostgreSQL の「pg_hba.conf」は、データベースに接続するロールの照合設定用のファイルです。Peer 設定では、OSにログイン中のユーザーとロールとを照合します。

 「pg_hba.conf」ファイルは、Ubuntu では「/etc/postgresql/10/main/pg_hba.conf」にあります。

 ロールはユーザーとグループのように明確に分かれていません。ユーザー、グループ、ロールは別物と憶えておいた方がよいでしょう。
 ロールでは継承という方法を使って、あるロールを複数のロールで継承するという方法でグループのような形をとります。

- ad -

ユーザー(ロール)の確認・一覧

 ロールの一覧は、psql の \du コマンドを実行します。PostgreSQL でのユーザー一覧とはこのロール一覧のことを指します。

$ psql
...

=# \du
...
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

 データベース・クラスタごとにロールが管理されているため、上記の場合はデフォルトインストールにおいてのデータベース・クラスタでのロールの一覧になります。

 内容は以下になります。

属性値概要
Superuserスーパーユーザーであることを示す。すべてのデータベースとそのデータにアクセスできる
Create roleロールの作成許可
Create DBデータベースの作成許可
Replicationデータベースのバックアップの許可
Bypass RLS行単位のデータの参照、編集のための RLS( Row Level Security )機能を許可

 SQL コマンドでも確認できます。SQL コマンドではシステムカタログのテーブル pg_roles を参照します。

=# SELECT * FROM pg_roles WHERE rolname NOT LIKE 'pg_%';
...
 rolname  | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
----------+----------+------------+---------------+-------------+-------------+------
 postgres | t        | t          | t             | t           | t           | t              |           -1 | ********    |               | t            |           |  10
(1 row)

 項目内容は以下です。

項目名タイプ概要
rolnamenameロール名
rolsuperboolスーパーユーザ
rolinheritboolロール権限の継承
rolcreateroleboolロール追加作成の権限
rolcreatedbboolデータベース作成の権限
rolcanloginboolログインの可/不可
rolreplicationboolレプリケーション用のロール
rolconnlimitint4同時接続の最大数(-1は無制限)
rolpasswordtextパスワード(********で表示)
rolvaliduntiltimestamptzパスワードの有効期限(NULL...有効期限なし)
rolbypassrlsboolセキュリティポリシーを無視
rolconfigtext[]実行設定のデフォルト値
oidoidロールID

 「pg_user」、「pg_shadow」でも登録されたロールを参照できます。

=# SELECT * FROM pg_user;

 「pg_shadow」は、システム上のルートユーザーからのみ参照できます。

=# SELECT * FROM pg_shadow;

ロール(ユーザー)の追加

 PostgreSQL でのロールの追加は、SQLコマンドで使う方法と createuser コマンドを使う方法があります。
 どちらのコマンドもスーパーユーザー、例えば「postgres」、またはロール作成権限をもったロールでログインして実行します(-Uオプションを使う方法もあります)。

SQLコマンドによるロール追加
$ sudo su postgres
..
$ psql
...
=# CREATE ROLE new_name;

 もしも、OS上のユーザーと同じ名称のロールを追加する場合は以下のようにします。以下の例では、ユーザー user_a のためのロールを追加しています。LOGIN オプションを追加しないと Peer 接続ができません。

SQLコマンドによる user_a ロール追加
$ sudo su postgres
..
=# CREATE ROLE user_a WITH LOGIN;

 これで、user_a から psql にログインすることができます。

 オプションを設定することもできます。オプションは、以下のように WITH で設定します。

オプションを付加

オプション付きでロールの作成
=# CREATE ROLE new_name WITH SUPERUSER LOGIN PASSWORD 'password';

オプションには以下があります。

オプション名摘要デフォルト値
SUPERUSER | NOSUPERUSERスーパーユーザーNOSUPERUSER
CREATEDB | NOCREATEDBデータベース作成NOCREATEDB
CREATEROLE | NOCREATEROLEロール(ユーザー)の管理NOCREATEROLE
INHERIT | NOINHERIT継承するか/しないかINHERIT
LOGIN | NOLOGINログイン認証の可/不可NOLOGIN
REPLICATION | NOREPLICATIONデータのバックアップの許可/不可NOREPLICATION
BYPASSRLS | NOBYPASSRLS行単位セキュリティ(RLSポリシー)NOSUPERUSER
CONNECTION LIMIT connlimit最大同時接続数-1 無制限
[ ENCRYPTED ] PASSWORD 'password'パスワードの設定
VALID UNTIL 'timestamp'ロールのパスワードが無効になる日時を設定
IN ROLE rolename [, ...]作成するロールを既存のロールに追加する
ROLE rolename [, ...]既存のロールを作成するロールに追加する
ADMIN rolename [, ...]作成するロールに、ロールの追加、削除の権限を付与して、既存のロールを追加。

* [, ...] は複数の設定ができます

 INHERIT | NOINHERIT は、親のロールからデータ操作権限を継承するか/しないかの設定です。ロールより親がない場合は NOINHERIT でよいでしょう。
 親がある場合は、INHERIT にしておかないとデータ操作権限は継承されません。

 ロールの権限の変更は以下の「ロール権限の変更」を参照してください。

 PostgreSQL よりも外部からの接続の場合にはロールやその認証の設定が必要です。
 例えばシステムにログインしているユーザー、web サーバーから www-data や suExec などの実行ユーザーで PostgreSQL に接続するとそのユーザー名でログインを試みます。
 これらの場合は、システムのユーザー名や web サーバーから接続する実行ユーザー名のロールがなければなりません。ほとんどの場合はインストール時にデフォルトで用意されています。 もしもロールが用意されていなければユーザー名と同じ名称のロールを作成しておきます。

 以下のように端末からロールを追加することもできます。しかし、この方法ではスーパーユーザーの権限、データベースを作成する権限、ロールを追加する権限などのオプションは設定しておらず、作成されたロールは認証によるログインができないために、外部からのデータベース接続ができませんので注意してください。

createuserコマンドによるロール追加
$ createuser -U postgres new_role

ロール権限の変更

 作成したロールの権限を変更するには SQL の ALTER role コマンドを使います。

ログイン可能に変更
=# ALTER ROLE new_name WITH LOGIN;

 データベースの作成を可能にするには以下のようにします。

データベースの作成可
=# ALTER ROLE new_name WITH CREATEDB;

ロールのパスワード設定

 データベースの接続時の認証にパスワードを必要とする場合には以下のように設定します。

パスワードの追加、変更
ALTER ROLE new_name WITH PASSWORD 'password';

ロールの削除

 ロールの削除は、SQL コマンドのロールの削除で行う方法と dropuser コマンドを使う方法があります。

SQLコマンドによるロール削除
=# DROP ROLE new_name;
dropuserコマンドによるロール削除
$ dropuser -U postgres new_name

- ad -

ロールのグループ管理

PostgreSQL ではグループ用のロールはないです。グループ化する方法として、ロールにロールを追加することでグループを構築します。

グループとしてのロールの確認

 pg_auth_membersカタログを確認します。

postgres=# SELECT (select pg_authid.rolname as auth_name from pg_authid where pg_authid.oid = pg_auth_members.roleid),(select pg_authid.rolname as members from pg_authid where pg_authid.oid = pg_auth_members.roleid),(select pg_authid.rolname as grantor_member from pg_authid where pg_authid.oid = pg_auth_members.roleid),admin_option FROM pg_auth_members;
...
auth_name       |       members        |    grantor_member    | admin_option
----------------------+----------------------+----------------------+--------------
pg_read_all_settings | pg_read_all_settings | pg_read_all_settings | f
pg_read_all_stats    | pg_read_all_stats    | pg_read_all_stats    | f
pg_stat_scan_tables  | pg_stat_scan_tables  | pg_stat_scan_tables  | f
(3 rows)

グループとしてのロールを作成

 グループ用ロールの作成はユーザー用のロール作成と同じです。グループとして利用するという前提でロールを作成します。 このロールにロールを追加することでグループ化します。ロールに所属するロールをメンバロールといいます。

 例えば、new_groupロールにuser_nameロールを追加するとします。まずは、new_groupロール、user_nameロールを作成します。 user_nameは一人のユーザーとして扱います。

SQLコマンドによるグループ用ロールとユーザー用ロールの作成
$ psql
...
=# CREATE ROLE new_group;
=# CREATE ROLE user_name WITH INHERIT;

 user_nameは、INHERITによって所属するnew_groupロールの権限を継承します。 このことでnew_groupの権限がそのロールに所属するロールに反映されます。

 user_nameをnew_groupに追加します。

SQLコマンド グループへのロール追加
=# GRANT new_group TO user_name;

グループ用ロールの削除

 グループ用ロールを削除するにはDROPコマンドを使用します。所属していたメンバロールの継承していた権限は無くなります。

SQLコマンド グループからロールを削除
=# REVOKE new_group FROM user_name;

データベース、テーブルの操作権限とロール

データベース、テーブル、ビューなどにロールによる閲覧、挿入、削除などの操作権限を追加する方法については、「データベース、テーブルの操作権限とロール」を参照してください。

 外部からPostgreSQLのデータ操作には、PostgreSQLへのログイン認証、ロールの設定、テーブルごとのロール設定がチェックされます。
 ログイン認証、ロールの設定、テーブルごとの設定については「ログイン認証とロール」を参照して下さい。

ロール名のデータベース作成

 システム上のユーザー名をロール名として使うこともできます。その場合、システムのユーザーでpsqlコマンドを実行するとユーザー名のデータベースにログインします。

user_name@ubuntu-PC:~$ psql
...
psql (10.12 (Ubuntu 10.12-0ubuntu0.18.04.1))
Type "help" for help.

user_name=>

 ただし、ユーザー名(ロール名)のデータベースがない場合にpsqlコマンドだけではエラーが発生します。

$ psql
↓
エラー表示

 ユーザー名(ロール名)のデータベースを作成しおく必要があります。

# CREATE DATABASE user_name OWNER user_name;