PostgreSQLの認証設定

概要

マニュアル解説シリーズです。今回のお題はこちら。

PostgreSQL: Documentation: 12: 20.1. The pg_hba.conf File

認証について

はじめに

PostgreSQLサービスを使うには、まず

  • サーバーにアクセスできること(ネットワーク的に到達できること)
  • サーバーに接続できること(サービスが稼働していて、ポートなどが開いていること)
  • サービスがクライアントを認証し、PostgreSQLのユーザーとマッピングできること

が必要です。3つ目の項目がココで説明する内容です。最初の2つに問題がある場合は、ここで説明する以前の話になります。

※細かく言うと、他にOSが何らかのセキュリティ(SELinux/AppArmorなど)で弾くケースがありますが、今回は考慮しません。

クライアント認証とはサーバー側から見て、接続してきたモノがどこの誰かを識別することです。この人に違いないと思ったらユーザーとマッピングされますが、そうでない場合はエラーで弾かれるということです。

PostgreSQLの認証の種類

認証方法説明
trust認証接続できただけで特定のユーザーとして認証する
パスワード認証指定されたユーザーであることをパスワードで確認して認証する
GSSAPI認証ActiveDirectoryなどで使用されるKerberos認証で認証されたユーザーとして認証する。
GSSAPIはそこで使用されるAPIで、所謂シングルサインオン。
SSPI認証Windows認証で認証されたユーザーとして認証する(Kerberos含む)。
サーバー/クライアントともにWindowsのときだけ使用できる、所謂シングルサインオン。
IDENT認証identサーバーでクライアントが実行中のユーザーを取得して認証する。
大昔に利用されてたサーバーで現在は使われない
Peer認証ローカル接続のときだけ、クライアントの実行ユーザーを取得して認証する。Windowsでは使用できない。
OSのユーザー名とPostgreSQLのユーザー名が一致する必要がある
LDAP認証LDAPのデータを使って指定されたユーザーであることを確認して認証する。中身はパスワード認証と同じ。
RADIUS認証RADIUSのデータを使って指定されたユーザーであることを確認して認証する。中身はパスワード認証と同じ。
平文ではないものの通信が暗号化されない
証明書認証SSLで受け取ったクライアント証明書のCommon Nameで認証する。
PAM認証LinuxのPAMのデータを使って指定されたユーザーであることを確認して認証する。中身はパスワード認証と同じ。
BSD認証OpenBSDで使える認証方式。よく知らない。

かなり方式が多いので注意です。ただ、よく使用されるのは太字の3つ。他はセキュリティに難があったり、ユーザーの管理がPostgreSQL内のユーザーとのマッピング維持が大変だったりして、あまり使用されません。証明書認証は通信経路そのものが暗号化されており、今後利用の増加が見込まれるという意味での太字です。

Ubuntu18.04のデフォルト設定

Ubuntu18.04のpg_hba.confのデフォルト設定はこんな感じ。

# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

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

# で始まる行はコメントです。それ以外の行は、どんなIPから、どういう接続で誰がどのデータベースに接続しようとしていた場合、どういう認証方式を使用するかを表しています。あとは1行ずつ見ていきます。

local   all             postgres                                peer

これは

  • local=ローカル接続=Unixドメインソケットの接続
  • all=対象データベースは何でもいい
  • postgres=ユーザーがpostgres(管理者)

という条件を全て満たす場合、peer=Peer認証するという設定です。そういえば最初にpostgresユーザーでpsqlで繋いだときパスワード聞かれませんでしたよね。そのときはココの設定が効いていたということです。

local   all             all                                     peer

次の行は先程のユーザー設定列がall、誰でもいいになっただけです。つまり、ローカル接続ならどのデータベースでも誰でもPeer認証にする、という設定です。一般ユーザーを作った後、そのユーザーでpsqlを実行したときにパスワード聞かれませんでしたよね。そのときに使われた設定です。

host    all             all             127.0.0.1/32            md5

次の行はhostなので、ローカル接続ではないTCP/IPの接続であることを意味しています。データベースとユーザーはallなので何でもOKです。次のIPアドレスっぽいのが、クライアントのIPです。127.0.0.1はローカルホストを意味する特別なIPで、つまりTCP/IPで同じホストから繋いできたときは、誰でもどんなデータベースでも、md5=パスワード認証を行う、という意味になります。ただし、同じホストならローカル接続でPeer認証できるので、普通はこの設定を使うことはありません。

ただし、Peer認証はLinux上のユーザー名と一致しないと使えないので、Linuxのユーザー名と異なるユーザー名をPostgreSQL側に作成した場合には使用されます。

host    all             all             ::1/128                 md5

次の行はさっきの設定のIPv6版です。説明は省略します。

残りの行はレプリケーション用の接続設定なので、1つしかない今回は割愛します。

つまりどういう設定か…

ローカルホストからしか使えない設定になっています。
なので別のマシンから接続する場合は、認証設定を追加する必要があります。

ローカルホスト以外からのパスワード認証の追加

特定のIPv4ホストからの接続でパスワード認証を追加する

host    all             all             10.0.2.2/32            md5

こんな感じで、10.0.2.2(VirtualBoxのNATの仮想ルーターのIP)からTCP/IPで接続された場合、パスワード認証をかけることが出来ます。

特定のIPv4 LAN内の複数ホストからの接続でパスワード認証を追加する

host    all             all             192.168.0.0/24            md5

こんな感じで、192.168.0.1~192.168.0.254までのIPからTCP/IPで接続された場合、パスワード認証をかけることが出来ます。

設定ファイルを編集したら…

OSに用意された方法でサービスの再起動をしてください。

ローカルホスト以外からのSSLクライアント認証の追加

hostssl all all all cert map=cnmap

こんな感じで追加出来ます。SSLで接続する場合は、他のTCP/IP接続手段は消した方がいいでしょう。
cnmapというのは、Common Nameとユーザーをどうマッピングするかという設定を他のファイルに記述するのですが、そこで使用されるマッピングの名前です。

具体例を↓に書いたので、良かったら参考にしてください。あまり丁寧には書いてないですけど…。

まとめ

PostgreSQLの認証設定は種類が多く、デフォルトではローカルからの認証設定しか存在しない。
今回はそこにリモート接続からの認証設定を追加する方法を解説した。