MENU

【PostgreSQL】第4回 データベースへの接続認証を理解しよう

~これは、雑魚技術者の勉強記録~

f:id:g071067:20200613191805p:plain

おつかれさまです。

 前回までで、ひととおりオブジェクト全般の作成ができるようになり、ユーザーと権限を絡めた制御を実戦するなどしました。
以降、より業務的で実用性のあるレプリケーション構成の紹介へ進みたいのですが、そのためにも、
クライアント認証などデータベース接続部分の仕組みに触れておく必要がありまして・・・ということだったかと思います。
 今回は、データベース接続部分の紹介をさせていただきます。同時に、レプリケーション環境構築の準備の一部ともなります。

シリーズ

tecsak.hatenablog.com

<第4回の概要>

4-1.データベースへの接続概要
 クライアントから接続を試み、目的のデータベースに到達するまでの概要を捉えます。

4-2.環境の複製
 データベースサーバー以外からのアクセスを試みるため、クライアントとしての環境を
 作成します。別途、別回にてレプリケーション環境としても使用してゆくものです。

4-3.ユーザー(ロール)管理としての接続制御
 一部復習となりますが、属性および権限のなかで接続に関するものを検証します。

4-4.接続と認証
 postgresql.confにて制御される、クライアント接続の許容設定について見ていきます。

4-5.クライアント認証
 pg_hba.confにて制御される、接続の方式に関する設定について見ていきます。

4-1.データベースへの接続概要

 利用者がデータを参照できるまでの過程について、あらためて整理したいと思います。

 まず、前回までの内容を振り返りますが、ユーザー(ロール)について「属性」というものがあり、特に接続に関しては"ログイン権限"属性というものが存在しました。
ただ、これまでの回ですと、一方的に権限付与を行い、実践として本当にログインが出来る・出来ないまでには踏み込みませんでした。

 また、データベースの利用について、データベースとは物理的な仕切りであると説明し、データベースへの接続を司るものは実質として権限でしかないとしました。
特にデータベースに対する接続に関しては"connect"権限がPUBLICキーワードにデフォルトで付与されており、一方的に接続が可能としてきました。
(接続以外ですと、"create temp tabe"権限(PUBLICキーワードにデフォルト)およびスキーマ作成権限の2つを加えた、合計3点がデータベース単位で取扱可能な権限ということでした)
実践として、とあるデータベース内でスキーマおよびテーブルのcreateおよびselectを試み、ユーザー・権限を踏まえテーブルが参照可能であることの確認をしました。

 マニュアルに従いますと、この前回までに実施したデータベース以下オブジェクトとユーザーの関係についての分野を「ロール(以降、ユーザーと表現します) の管理」と呼んでいます。
加えて、「接続と認証」「クライアント認証」と呼ばれる過程があり、これら全てを踏まえてデータベースに到達可能と表現することができます。各過程ごとに説明・検証していきたいと思います。

f:id:g071067:20201011114035p:plain

4-2.環境の複製

 これまで、データベースの接続にあたっては、DBサーバーにログインし、psqlを用いて行ってきました。本稿では、他サーバー・環境からの接続も想定したいと思います。
 現状、第1回にて作成した1サーバー環境にて動作検証を行ってまいりましたが、ここで複製したいと思います。
これは、今後の投稿にて紹介予定のレプリケーション環境にもなるものでして、ほぼ同じ構成が必要なことから、複製が可能であれば複製→固有名詞の書き換え、とした方法が容易です。

 本稿では、#2をクライアントと見立てて、#1への接続を試みることとします。複製につきクライアント役である#2にはpsqlなど#1で出来たクライアントとしての環境が整っている状況となります。
別途、アプリや開発環境な感じで接続を試みてみたい場合は、各種クライアントツールを導入してみてください。当方の現場では、pgAdmin IIIの利用が多いようですが、他にもいくつかあります。

ホスト名 本稿での役割 備考
std_PostgreSQL_db01 DBサーバー
#1と呼ぶこととします
192.168.56.11
-bash-4.2$ uname -n
std_PostgreSQL_db01
-bash-4.2$
std_PostgreSQL_db02 クライアント
#2と呼ぶこととします
192.168.56.12
-bash-4.2$ uname -n
std_PostgreSQL_db02
-bash-4.2$

4-3.ユーザー(ロール)管理としての接続制御

 前回までで紹介済の事項となりまして、あらためて説明する内容はありません。
実践だけさらっと行ってみます。ログイン権限属性とconnect権限の着脱です。

▼本稿検証用のユーザー・データベース作成

 本件検証用のユーザー(conn_test_user1、2)を2つと、データベース(conn_test_db)を作成します。

conn_test_user2ユーザーは、ログイン権限属性無しにて作成としてみました。以前にも
ログイン権限属性無しでの作成は行いましたので完全な復習となります。
(その際は、権限有無がどのような形で表記なされるかを試すためだったかと思います)

あらためて、今回ログインを試みて、conn_test_user2のログインが失敗となれば想定どおりです。

-bash-4.2$ createdb  conn_test_db
-bash-4.2$
-bash-4.2$ createuser conn_test_user1 -P
新しいロールのためのパスワード:
もう一度入力してください:
-bash-4.2$
-bash-4.2$ createuser conn_test_user2 -P -L
新しいロールのためのパスワード:
もう一度入力してください:
-bash-4.2$
-bash-4.2$ psql -c "\l conn_test_db"
                                    データベース一覧
     名前     |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権
--------------+----------+------------------+----------+-------------------+------------
 conn_test_db | postgres | UTF8             | C        | C                 |
(1 行)

-bash-4.2$
-bash-4.2$ psql -c "\du conn_test_user*"
                  ロール一覧
    ロール名     |       属性       | メンバー
-----------------+------------------+----------
 conn_test_user1 |                  | {}
 conn_test_user2 | ログインできない | {}

-bash-4.2$

▼ログイン

 conn_test_user2ユーザーによるログインのみ不可となることを確認します。

-bash-4.2$ psql -d conn_test_db -U conn_test_user1
\q
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=> \q
-bash-4.2$
-bash-4.2$ psql -d conn_test_db -U conn_test_user2
psql: FATAL:  role "conn_test_user2" is not permitted to log in
-bash-4.2$
-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=> \c - conn_test_user2
FATAL:  role "conn_test_user2" is not permitted to log in
以前の接続は保持されています。
conn_test_db=> \q
-bash-4.2$

はい。
期待値どおりです。

▼ログイン権限属性付与

 conn_test_user2ユーザーにログイン権限属性を付与します。

-bash-4.2$ psql -c "alter user conn_test_user2 LOGIN"
ALTER ROLE
-bash-4.2$
-bash-4.2$ psql -c "\du conn_test_user*"
            ロール一覧
    ロール名     | 属性 | メンバー
-----------------+------+----------
 conn_test_user1 |      | {}
 conn_test_user2 |      | {}

-bash-4.2$

ログインできない旨が表示されていたのが、消えました。

▼ログイン  今度はログインできることでしょう。conn_test_user2ユーザーのログイン動作を
再度実施します。

-bash-4.2$ psql -d conn_test_db -U conn_test_user2
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> \q
-bash-4.2$
-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> \c - conn_test_user2
データベース "conn_test_db" にユーザ"conn_test_user2"として接続しました。
conn_test_db=>
conn_test_db=> \q
-bash-4.2$

順当です。

▼CONNECT権限はく奪(conn_test_user1ユーザーよりconn_test_dbデータベースに対して)

 LOGIN権限属性に次いで、CONNECT権限を見てみます。
まずは現状を参照してみましょう。

bash-4.2$ psql -c "\l conn_test_db"
                                    データベース一覧
     名前     |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権
--------------+----------+------------------+----------+-------------------+------------
 conn_test_db | postgres | UTF8             | C        | C                 |
(1 行)

-bash-4.2$

しーん。アクセス権欄は空っぽです。
特になにも伺えません。 いつものことか・・・

ということで、そのあとの動作もいつもながらでしょうか?
一旦、対ユーザー向けに、はく奪を慣行します。conn_test_user1ユーザーに対するrevokeです。

-bash-4.2$ psql -c "revoke connect on database conn_test_db from conn_test_user1"
REVOKE
-bash-4.2$
-bash-4.2$ psql -c "\l conn_test_db"
                                         データベース一覧
     名前     |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権
--------------+----------+------------------+----------+-------------------+-----------------------
 conn_test_db | postgres | UTF8             | C        | C                 | =Tc/postgres         +
              |          |                  |          |                   | postgres=CTc/postgres
(1 行)

-bash-4.2$
-bash-4.2$ psql -c "\du conn_test_user*"
            ロール一覧
    ロール名     | 属性 | メンバー
-----------------+------+----------
 conn_test_user1 |      | {}
 conn_test_user2 |      | {}

-bash-4.2$

はいはい、引き続きよく分からない仕様ですが、権限付与の状況が表示されるようになりました。

ここで、アクセス権の表記について説明を付記しておきます。
繰り返しになりますが、対データベースにおける権限は3つでした。それぞれ次のとおりです。
  C:CREATE
  c:connect
  T:TEMP

 conn_test_user1ユーザーの表記はありませんね(いつもながら)。
 スーパーユーザーであるpostgresユーザーは3つ全て付与されている状況です。
 そして、左辺が空欄のものについて、復習となりますがPUBLICキーワードということでした。
どうやらcが付いていますね。 ということは、現状ですとconn_test_user1ユーザーで引き続きconn_test_dbデータベースへの接続が可能なのではないでしょうか?

まあまあ、一旦試してみますね。

▼ログイン

-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

どう見ても、ログインできてますね。およそ、第3回のPUBLICキーワードに関する検証と同じ流れ
になりそうな予感。
ということで、対PUBLICに対して、はく奪を試みましょうか。

▼CONNECT権限はく奪(PUBLICキーワードよりconn_test_dbデータベースに対して)

 PUBLICキーワードよりはく奪します。

-bash-4.2$ psql -c "revoke connect on database conn_test_db from PUBLIC"
REVOKE
-bash-4.2$
-bash-4.2$ psql -c "\l conn_test_db"
                                         データベース一覧
     名前     |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権
--------------+----------+------------------+----------+-------------------+-----------------------
 conn_test_db | postgres | UTF8             | C        | C                 | =T/postgres          +
              |          |                  |          |                   | postgres=CTc/postgres
(1 行)

-bash-4.2$

左辺空欄の行よりcが消えました。
これで実現されるでしょう。再度ログイン確認いたします。

▼ログイン

 ログイン不可であることを確認します。

-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql: FATAL:  permission denied for database "conn_test_db"
DETAIL:  User does not have CONNECT privilege.
-bash-4.2$

OKです!
第3回と被ってますね。

▼CONNECT権限付与(conn_test_user1および2ユーザーへconn_test_dbデータベースに対して)

 引き続きテスト用ユーザーを使いたく、一旦付与された状態へもどします。PUBLICキーワードに対してではなく、ユーザー個別に付与してしまいます。

-bash-4.2$ psql -c "grant connect on database conn_test_db to conn_test_user1"
GRANT
-bash-4.2$
-bash-4.2$ psql -c "grant connect on database conn_test_db to conn_test_user2"

GRANT
-bash-4.2$
-bash-4.2$ psql -c "\l conn_test_db"
                                            データベース一覧
     名前     |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |         アクセス権
--------------+----------+------------------+----------+-------------------+----------------------------
 conn_test_db | postgres | UTF8             | C        | C                 | =T/postgres               +
              |          |                  |          |                   | postgres=CTc/postgres     +
              |          |                  |          |                   | conn_test_user1=c/postgres+
              |          |                  |          |                   | conn_test_user2=c/postgres
(1 行)

-bash-4.2$

各ユーザーにcが付きました。

▼ログイン

  念のため、試します。

-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$
-bash-4.2$ psql -d conn_test_db -U conn_test_user2
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user2
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$
-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \c - conn_test_user2
データベース "conn_test_db" にユーザ"conn_test_user2"として接続しました。
conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user2
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

スイスイ~ OKです。
ですが、何かスイスイと行き過ぎているような・・・

以前にも1度触れていまして、放置してきたのですが
・ユーザーの作成時にパスワードを指定しているのに、ログイン時に聞かれない
・無条件にユーザー間のスイッチが出来ている

これらの仕組みについて、以降で説明する「クライアント認証」が担っていまして、説明・検証もそちらに回します。

本項としてはこれにて終了です。

4-4.接続と認証

 postgresql.confファイルにて制御される過程となります。下記2点の設定項目の説明を通じて、当過程の役割を理解いただけると思います。

listen_addresses

 クライアントからの接続を許容するTCP/IPアドレスを指定します。0.0.0.0は全てのIPv4アドレスを許容、空欄ですとUnixドメインソケットのみ許容となります。
業務として、APサーバーからの接続のみしか起こりえない!!などと明らかでしたら、特にPostgreSQLとして制御に介入する必要は無く、開放で問題ないかもしれません。

port

 そのままですが、該当するデータベースクラスタのポート番号です。デフォルトは5432です。

ほかに、「接続と認証」のなかで接続に関わるものとして同時接続数などありますが、本稿での説明は割愛させていただきます。

▼とりあえず接続

 接続してみます。 以下は、これまでどおりのログインです。

-bash-4.2$ psql -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

▼ログイン(-hオプションによるホスト名指定とTCP/IP接続)

あらためて、追加でhオプションも用いて、ホスト名を指定してのログインを試みます。

-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql: サーバに接続できませんでした: 接続を拒否されました
        サーバはホスト "std_PostgreSQL_db01" (fe80::5f5b:1ebd:d7f1:fe75) で稼動しており、
        また、ポート 5432 で TCP/IP 接続を受け付けていますか?
-bash-4.2$

怒られました。
これはPostgreSQLの中ではわりと知られたメッセージでして、TCP/IP接続がうまく行えていない旨を示すものです。
設定面で疑うとすれば、listen_addressesもしくはportの不適切が考えられます。

今回、ログインにはポート番号を指定しておらず、デフォルトにて実施しておりますので、疑われるのはlisten_addressesでしょう。
ということで、postgresql.confの該当箇所を見てみます。

-bash-4.2$ grep listen_addresses $PGDATA/postgresql.conf
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
-bash-4.2$

現状はコメントアウトで以て、設定なし=localhost がデフォルト設定されており、ループバックのみを許可している状況となります。
これに、-hオプションでも指定した、ホスト名であるstd_PostgreSQL_db01を設定して応答するよう設定変更したいと思います。

-bash-4.2$ grep listen_addresses $PGDATA/postgresql.conf
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
listen_addresses = 'std_PostgreSQL_db01'
-bash-4.2$
-bash-4.2$ pg_ctl reload
サーバにシグナルを送信しました
-bash-4.2$

あらためて1行追加しました。
その後、設定のreloadを行い反映を行っております。reloadの場合、DB再起動を伴いません。

それでは、再度ログインを試します。

-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql: FATAL:  no pg_hba.conf entry for host "fe80::5f5b:1ebd:d7f1:fe75%eno16777984", user "conn_test_user1", database "conn_test_db", SSL off
-bash-4.2$

再び怒られました。 が、メッセージが変わりましたね!

なにやら、pg_hba.conf の単語が見えまして・・・
設定が入っていないといった文面に見えますね。

ひとまず、「接続と認証」の過程はクリアしておりまして、TCP/IPとしてはうまくいっています。

後続の、pg_hba.confが司る「クライアント認証」の過程を次より説明・検証してまいります。

現状、失敗のまま次項に持ち越します。

4-5.クライアント認証

 pg_hba.confファイルにて制御される過程となります。
接続方式(TYPE)、データベース(DATABASE)、ユーザー(USER)、クライアントのアドレス(ADDRESS)、認証方式((METHOD)の関係を制御するものです。

 ファイルの記述方式は極めて単純で、左記項目をスペース区切りで1行に表現するだけです。"all"や"0.0.0.0/0"の表現を用いて全面的に許可することも可能です。
 許可されるべきものを記述し、記述に該当しない接続が認められない仕組みです。
さらに、先頭行ほど優先度が高く、最下行まで順に条件判断されます。条件が合致され次第許可となり、それ以降の条件は考慮されません。

 こちらも、「接続と認証」同様、明らかなシステム構成で運用される場合は、PostgreSQLとしての介入はそれほど複雑でなくても問題無いかもしれません。

▼前項からのつづき・・・ログイン(-hオプションによるホスト名指定とTCP/IP接続)

 psqlコマンドの-hオプションの有無に関わらず同じデータベースに接続を試みているのですが、
ここで1点! 接続方式がUNIXドメインソケットからTCP/IP接続に変わっています。
実は、-hオプションにて、接続先の指定とともに接続方式がTCP/IP接続へと変わっています。
(マニュアルによると、-hにUnixドメインソケット用のディレクトリを指定するとUNIXドメインソケット接続になるようです)

ここでは、題意に従いサーバー側の設定変更にてTCP/IP接続を許容する形で対応したいと思います。
ということで、pg_hba.confの出番です!!
一旦、pg_hba.confファイルの中身を確認しますね。

-bash-4.2$ tail -15 $PGDATA/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                trust
#host    replication     postgres        127.0.0.1/32            trust
#host    replication     postgres        ::1/128                 trust
-bash-4.2$

行頭多数行がコメントによる説明文で埋め尽くされているため、tailにて失礼します。

有効な行(コメントでない行)は3行ありますね。

はじめに、TYPE欄を見ていただきたいのですが、接続方式を示す項目ということで
次のような設定値を指定可能です。

設定値 意味
local Unixドメインソケットを使用する接続に対応するよう設定します
host TCP/IPを使用した接続に対応するよう設定します

これを踏まえて、3行を読んでみます。
 1行目:今回、TCP/IP接続につきTYPE=local である当行は条件対象外です。1行目だけの状況でしたら、Unixドメインソケットでのみログイン可能ということになります。
 2行目以降: TYPE=host ということで許容となりますが、ADDRESSの条件がいずれもそぐわないため、最終的には許容されず、
    ログイン失敗となった模様です。127.0.0.1および::1/128はループバックですが、std_PostgreSQL_db01とは異なりまして、許容対象外となります。
そうですね、
hostについて、次のような行を追加してみましょうか。

# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    conn_test_db    conn_test_user1 std_PostgreSQL_db01     trust
host    conn_test_db    conn_test_user2 std_PostgreSQL_db01     trust
-bash-4.2$ grep std_PostgreSQL_db01 $PGDATA/pg_hba.conf
host    conn_test_db    conn_test_user1 std_PostgreSQL_db01     trust
host    conn_test_db    conn_test_user2 std_PostgreSQL_db01     trust
-bash-4.2$
-bash-4.2$ pg_ctl reload
サーバにシグナルを送信しました
-bash-4.2$

2行追加、およびreloadしました。

それでは、再度ログインを試みます。

-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

できました。

▼#2からの接続

 次いで、#2から接続してみましょう。コマンドは#1のときと変わらず、ログイン元のみ変わると
どうなる!?

-bash-4.2$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-bash-4.2$
-bash-4.2$ uname -n
std_PostgreSQL_db02
-bash-4.2$
-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql: FATAL:  no pg_hba.conf entry for host "192.168.56.12", user "conn_test_user1", database "conn_test_db", SSL off
-bash-4.2$

失敗です。
メッセージの内容は可読性があり理解しやすいですね。記述された組み合わせがpg_hba.confにエントリされていないということです。
192.168.56.12はstd_PostgreSQL_db02です。これに関する記述がpg_hba.confに全く含まれていません。

先ほど、本検証用のデータベースであるconn_test_dbに対しADDRESSにstd_PostgreSQL_db01のみを設定しました。 
再度、今度はstd_PostgreSQL_db02の設定も追加てみますね。

-bash-4.2$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-bash-4.2$ uname -n
std_PostgreSQL_db01
-bash-4.2$
-bash-4.2$ grep std_PostgreSQL_db0 $PGDATA/pg_hba.conf
host    conn_test_db    conn_test_user1 std_PostgreSQL_db01     trust
host    conn_test_db    conn_test_user1 std_PostgreSQL_db02     trust
host    conn_test_db    conn_test_user2 std_PostgreSQL_db01     trust
host    conn_test_db    conn_test_user2 std_PostgreSQL_db02     trust
-bash-4.2$
-bash-4.2$ pg_ctl reload
サーバにシグナルを送信しました
-bash-4.2$

いざ、再チャレンジ!

-bash-4.2$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-bash-4.2$ uname -n
std_PostgreSQL_db02
-bash-4.2$
-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \c - conn_test_user2
データベース "conn_test_db" にユーザ"conn_test_user2"として接続しました。
conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user2
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

成功です~

▼パスワード・スイッチについて

 最後に、パスワード入力が求められない、スイッチが無条件でスイスイと可能となる状況
について見てみましょう。

これは認証方式によるものです。認証方式はMETHOD欄が受け持ちます。
現在、METHOD=trustでして、接続を無条件で許可する設定となっております。スイスイ進める原因はこの設定にあります。

METHODをいじってみましょう。はじめに、主だった設定を紹介します。

設定値 意味
trust 接続を無条件で許可します。
reject 接続を無条件に拒否します。
password クライアントに対して認証時に平文のパスワードを要求します。
md5 クライアントに対して認証時に二重MD5ハッシュ化パスワードを要求します。

認証方式は複数存在し、認証の世界に入ると深いものがありますが、PostgreSQLとしておよその認証方式に対応しています。
ここでは、とりあえずpasswordとしてみたいと思います。
代表で、conn_test_user2ユーザーについて変更してみます。

-bash-4.2$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-bash-4.2$ uname -n
std_PostgreSQL_db01
-bash-4.2$
-bash-4.2$ grep std_PostgreSQL_db0 $PGDATA/pg_hba.conf
host    conn_test_db    conn_test_user1 std_PostgreSQL_db01     trust
host    conn_test_db    conn_test_user1 std_PostgreSQL_db02     trust
host    conn_test_db    conn_test_user2 std_PostgreSQL_db01     password
host    conn_test_db    conn_test_user2 std_PostgreSQL_db02     password
-bash-4.2$
-bash-4.2$ pg_ctl reload
サーバにシグナルを送信しました
-bash-4.2$

まあ、本機能の最低限の検証としては、#1も#2も関係ありませんが
3行目で#1からの接続に対しパスワード必須を、4行目で#2からの接続に対しパスワード必須を
それぞれ定義している形となります。

割愛となりますが、代表で#2よりログインを試みます。

-bash-4.2$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-bash-4.2$ uname -n
std_PostgreSQL_db01
-bash-4.2$
-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=> \q
-bash-4.2$
-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user2
ユーザ conn_test_user2 のパスワード:
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user2
(1 行)

conn_test_db=>
conn_test_db-> \q
-bash-4.2$
-bash-4.2$ psql -h std_PostgreSQL_db01 -d conn_test_db -U conn_test_user1
psql (9.6.3)
"help" でヘルプを表示します.

conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user1
(1 行)

conn_test_db=>
conn_test_db=> \c - conn_test_user2
ユーザ conn_test_user2 のパスワード:
データベース "conn_test_db" にユーザ"conn_test_user2"として接続しました。
conn_test_db=>
conn_test_db=> select current_database(), current_user;
 current_database |  current_user
------------------+-----------------
 conn_test_db     | conn_test_user2
(1 行)

conn_test_db=>
conn_test_db=> \q
-bash-4.2$

conn_test_user2ユーザーへのログインに関してのみ、パスワードが聞かれています。
2行目はtrustのままですからね。

これは、直接のログインのみならず、スイッチでも同様となっています。
期待値どおりではないでしょうか。


 認証にあたり、いくつかの過程が存在し、慣れるまでは複雑かもしれません。
前述しましたが、必ずしも全てにおいて厳格な設定が必要とも限りませんので、実業務での管理負荷は想定よりも下回るのではないかと思います。
 裏では独自のプロトコルでサーバープロセスがクライアントと対話を行っているのですが、利用にあたっては設定ファイルの使い方を押さえておけばOKな状況となっております。

 復習半分となった今回は、簡単でしたかね!!

 次回以降、レプリケーション環境の構築検証に進みたいと思います。その際、#1のデータが#2へレプリカとして転送されることとなり、以降は2台で検証してゆくこととなります。

 おつかれさまでした。ありがとうございました。