Aurora PostgreSQL接続時の「The authentication type 10 is not supported.」エラーに対応する
CX事業本部@大阪の岩田です
社内のチャットでAurora PostgreSQL接続時に発生した
org.postgresql.util.PSQLException: The authentication type 10 is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or subnet, and that it is using an authentication scheme supported by the driver.
というエラーの対応方法に質問があったので、対応方法等をブログにまとめておきます。
ブログのタイトルはAurora PostgreSQLとなっており、検証作業もAuroraで行いましたが、通常のRDS for PostgreSQLやPostgreSQLでもバージョン14以後であれば同様の考え方になるはずです。
結論
利用しているJDBCのバージョンが古いのでPostgreSQL JDBC ドライバーのバージョン42.2.0以後にバージョンを上げましょう。もし何らかの理由でJDBCのバージョンが上げられない場合はpassword_encryption
をmd5に設定した上で対象のDBユーザーのパスワードを再設定しましょう。
環境
今回検証に利用した環境は以下の通りです
- Aurora PostgreSQL: エンジンバージョン14.6
- DB クラスターのパラメータグループ: default.aurora-postgresql14
- rds.accepted_password_auth_method: md5+scram
- password_encryption: 指定なし → デフォルト値としてscram-sha-256が利用される
- ※参考 PostgreSQL 14 に関する技術情報
- クライアントのOS: Amazon Linux2 (4.14.214-160.339.amzn2.x86_64)
- Java: OpenJDK 1.7.0_321
- JDBCドライバ
- postgresql-42.1.4.jre7.jar
- postgresql-42.2.27.jre7.jar
概要
パスワードのハッシュ方式について
PostgreSQLはDBユーザーのパスワードのハッシュをサーバーに格納する方式としてscram-sha-256とmd5の2種類をサポートしています。※古いバージョンでは平文での格納も可能だったようです。
このハッシュ形式はpassword_encryptionというパラメータで設定されており、password_encryptionがmd5の場合、CREATE ROLEやALTER ROLEで設定されたパスワードはmd5形式で、password_encryptionがscramの場合はSCRAM-SHA-256でハッシュ化されます。
通常のPostgreSQL(非RDS)であればpg_authidを確認すればハッシュ形式が確認できます。
postgres=# select rolname,rolpassword from pg_authid ; rolname | rolpassword ---------------------------+--------------------------------------------------------------------------------------------------------------------------------------- ...略 scram | SCRAM-SHA-256$4096:hjOj1xgMBZjgk12E5CZluA==$JQOYWNm82TAOUowHcrGLDISUB5xZLesOEn1Y9yZNBUg=:rjeoQ1TgTn1d/qlqpNuIXpLX5hmcqED+mAHcFz2kAgA= md5 | md53062e1e11c64939824f4f249890f7157
クライアントが入力したパスワードが送信される方式について
PostgreSQLのクライアントが接続確立時にサーバーにパスワードを送信する方式は前述のscram-sha-256とmd5に加えてpassword(平文利用)という方式がサポートされています。実際に利用可能な方式はサーバー上でパスワードがどの形式でハッシュ化されているかに依存して以下のように決まります。
- サーバー上でパスワードがscram-sha-256でハッシュ化されている場合
- クライアントはscram-sha-256もしくはpasswordが利用可能
- サーバー上でパスワードがmd5でハッシュ化されている場合
- クライアントはmd5もしくはpassword
さらにpg_hba.confの設定により、特定のクライアントからの接続はscramのみ許可する といった設定も可能です。
RDSにおけるパスワードハッシュ化の形式
ここまでは通常のPostgreSQLの話でしたが、RDSでは追加の考慮事項があります。通常のPostgreSQLではpg_hba.confの設定によりmd5やscramの利用可否を細かく制御できますが、pg_hba.confが編集できないRDS環境においては代わりにrds.accepted_password_auth_method
によってクライアントが利用可能なハッシュ形式が制限できます。このパラメータは
md5+scram
scram-sha-256
の2種類から指定でき、scram-sha-256
を指定した場合、クライアントはハッシュ形式としてmd5が利用できなくなります。つまりRDS上でユーザーのパスワードがmd5でハッシュ化されている場合にrds.accepted_password_auth_method
がscram-sha-256
に設定されてしまうと、クライアントはRDSに接続できないことになります。
rds.accepted_password_auth_method
が md5+scram
に指定されている場合は、クライアントはmd5とscramの両方が利用可能です。よってRDS上でユーザーのパスワードがmd5でハッシュ化されている場合、scram-sha-256でハッシュ化されている場合、いずれの場合も対応可能です。
PostgreSQL 14からpassword_encryptionのデフォルト値がscram-sha-256
に
このようにクライアントが利用できるハッシュ形式に影響を与えるpassword_encryption
というパラメータですが、PostgreSQL 14からはscram-sha-256
がデフォルト値となりました。従来はmd5
がデフォルト値だったので、デフォルトの設定でPostgreSQLを利用している分にはクライアントが利用するハッシュ形式も必然的にmd5となっていましたが、PostgreSQL 14からはscram-sha-256
を利用することになります。が、ここに注意が必要で、古いクライアント(各種ライブラリやJDBCドライバ)はscram-sha-256
に対応しておらず、パスワードがscram-sha-256
でハッシュ化されたDBユーザーを利用してサーバーに接続できないことになります。
やってみる
ここまでの説明を踏まえつつ、冒頭のエラーについて検証していきましょう。
まずはpsqlからAuroraに接続して設定を確認しておきます。
postgres=> show password_encryption; password_encryption --------------------- scram-sha-256 (1 row) postgres=> CREATE EXTENSION rds_tools; CREATE EXTENSION postgres=> SELECT * FROM rds_tools.role_password_encryption_type(); rolname | encryption_type ----------------------+----------------- pg_database_owner | pg_read_all_data | pg_write_all_data | pg_monitor | pg_read_all_settings | pg_read_all_stats | pg_stat_scan_tables | pg_signal_backend | postgres | scram-sha-256 (9 rows)
password_encryption
はscram-sha-256
が設定されており、マスターユーザーであるpostgresのencryption_typeもscram-sha-256
となっています。
検証用にパスワードのencryption_typeがscram-sha-256
のユーザーを作成しておきます。
postgres=> CREATE ROLE scram WITH PASSWORD 'scram' LOGIN; CREATE ROLE postgres=> SELECT * FROM rds_tools.role_password_encryption_type(); rolname | encryption_type ----------------------+----------------- pg_database_owner | pg_read_all_data | pg_write_all_data | pg_monitor | pg_read_all_settings | pg_read_all_stats | pg_stat_scan_tables | pg_signal_backend | postgres | scram-sha-256 scram | scram-sha-256 (10 rows)
同様にencryption_typeがmd5
のユーザーも作成してます
postgres=> SET password_encryption=md5; SET postgres=> CREATE ROLE md5 WITH PASSWORD 'md5' LOGIN; CREATE ROLE postgres=> SELECT * FROM rds_tools.role_password_encryption_type(); rolname | encryption_type ----------------------+----------------- pg_database_owner | pg_read_all_data | pg_write_all_data | pg_monitor | pg_read_all_settings | pg_read_all_stats | pg_stat_scan_tables | pg_signal_backend | postgres | scram-sha-256 scram | scram-sha-256 md5 | md5 (11 rows)
検証用コード
設定が確認できたらJavaのコードからAuroraに接続して動作を確認していきます。今回は以下のコードで実験します。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.sql.SQLException; public class JdbcTest { public static void main(String[] args) { final String URL = "jdbc:postgresql://Auroraのエンドポイント:5432/template1"; final String USER = System.getenv("USER"); final String PASS = System.getenv("PASSWORD"); try( Connection conn = DriverManager.getConnection(URL, USER, PASS); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT now()"); ) { rs.next(); System.out.println(rs.getString(1)); } catch (SQLException e) { System.out.println(e); } } }
環境変数USERとPASSWORDに設定された情報を使ってAuroraに接続し、SELECT now()
を発行するだけのシンプルな処理です。
コードが準備できたのでコンパイルしてclassファイルを準備します
$ javac JdbcTest.java
古いJDBCドライバ × パスワードのencryption_typeがmd5のユーザーで接続してみる
まずは古いJDBCドライバとパスワードのencryption_typeがmd5のユーザーの組み合わせで試してみます。
$USER=md5 PASSWORD=md5 java -classpath postgresql-42.1.4.jre7.jar:./ JdbcTest 2023-03-24 13:58:37.544767+00
問題なく実行できました
古いJDBCドライバ × パスワードのencryption_typeがscram-sha-256のユーザーで接続してみる
続いて古いJDBCドライバとパスワードのencryption_typeがscram-sha-256のユーザーの組み合わせです
USER=scram PASSWORD=scram java -classpath postgresql-42.1.4.jre7.jar:./ JdbcTest Mar 24, 2023 2:00:47 PM org.postgresql.Driver connect SEVERE: Connection error: org.postgresql.util.PSQLException: The authentication type 10 is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or subnet, and that it is using an authentication scheme supported by the driver. at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:614) at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:222) at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194) at org.postgresql.Driver.makeConnection(Driver.java:450) at org.postgresql.Driver.connect(Driver.java:252) at java.sql.DriverManager.getConnection(DriverManager.java:571) at java.sql.DriverManager.getConnection(DriverManager.java:215) at JdbcTest.main(JdbcTest.java:16) org.postgresql.util.PSQLException: The authentication type 10 is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or subnet, and that it is using an authentication scheme supported by the driver.
エラーになりました。古いJDBCドライバはSCRAMに未対応ということが分かります。
新しいJDBCドライバ × パスワードのencryption_typeがscram-sha-256のユーザーで接続してみる
今度はJDBCドライバのバージョンを42.2系に変更して試してみましょう。先程実行したコマンドの引数-classpath
の指定を変更して利用するJDBCドライバのバージョンを変更しています。
USER=scram PASSWORD=scram java -classpath postgresql-42.2.27.jre7.jar:./ JdbcTest 2023-03-24 14:03:22.895092+00
今度は無事に接続できました!
DBユーザーのパスワードをencryption_type:md5で更新してから古いJDBCドライバで接続してみる
JDBCドライバのバージョンを上げれば The authentication type 10 is not supported.
のエラーが回避できることが分かりました。が、諸事情によりJDBCドライバのバージョンを上げられないようなケースもあると思います。こういった場合の対応方法としてDBユーザーのパスワードをencryption_type:md5に更新すれば古いJDBCドライバからでも接続可能になることを確認しておきましょう。
先程作成したscramユーザーのパスワードをencryption_type:md5で再設定します。
postgres=> SELECT * FROM rds_tools.role_password_encryption_type() where rolname = 'scram'; rolname | encryption_type ---------+----------------- scram | scram-sha-256 (1 row) postgres=> SET password_encryption=md5; SET postgres=> ALTER role scram with password 'scram'; ALTER ROLE postgres=> SELECT * FROM rds_tools.role_password_encryption_type() where rolname = 'scram'; rolname | encryption_type ---------+----------------- scram | md5 (1 row)
改めて古いJDBCドライバを使って接続確認してみます。
USER=scram PASSWORD=scram java -classpath postgresql-42.1.4.jre7.jar:./ JdbcTest 2023-03-24 14:12:31.141669+00
無事に古いJDBCドライバからでもつながりました!
まとめ
PostgreSQLのクライアントのバージョンが古い場合は、パスワードのハッシュ形式scram-sha-256
に対応できません。一例として42.2.0より前のJDBCドライバが挙げられます。
もしPostgreSQL 14以後に対して古いクライアントから接続したい場合はまずクライアントのバージョンアップを検討して下さい。もし何らかの事情によってクライアントのバージョンアップが不可能な場合は、encryption_typeをmd5に設定した状態で対象DBユーザーのパスワードを更新することでPostgreSQL 13以前と同様にmd5
を利用した接続が可能になります。