4.5. 在 PostgreSQL 服务器中配置 TLS 加密
默认情况下,PostgreSQL 使用未加密的连接。如需更多安全连接,您可以在 PostgreSQL 服务器中启用传输层安全(TLS)支持,并将客户端配置为建立加密连接。
先决条件
- 已安装 PostgreSQL 服务器。
- 初始化数据库集群。
- 如果服务器运行 RHEL 9.2 或更高版本,并且启用了 FIPS 模式,则客户端必须支持扩展 Master Secret (EMS)扩展或使用 TLS 1.3。没有 EMS 的 TLS 1.2 连接会失败。如需更多信息,请参阅红帽知识库解决方案 在 RHEL 9.2 及更高版本上强制执行 TLS 扩展 "Extended Master Secret"。
流程
安装 OpenSSL 库:
# dnf install openssl生成 TLS 证书和密钥:
# openssl req -new -x509 -days 365 -nodes -text -out server.crt \ -keyout server.key -subj "/CN=dbhost.yourdomain.com"将 dbhost.yourdomain.com 替换为您的数据库主机和域名。
将签名的证书和私钥复制到数据库服务器的所需位置:
# cp server.{key,crt} /var/lib/pgsql/data/.将签名证书的所有者和组所有权改为
postgres用户:# chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}限制私钥的权限,使其只可由所有者读取:
# chmod 0400 /var/lib/pgsql/data/server.key通过在
/var/lib/pgsql/data/postgresql.conf文件中更改以下行,将密码哈希算法设置为scram-sha-256:#password_encryption = md5 # md5 or scram-sha-256改为:
password_encryption = scram-sha-256通过在
/var/lib/pgsql/data/postgresql.conf文件中更改以下行,将 PostgreSQL 配置为使用 SSL/TLS:#ssl = off改为:
ssl=on通过更改
/var/lib/pgsql/data/pg_hba.conf文件中的 IPv4 本地连接,将所有数据库的访问限制为只使用 TLS 的客户端的连接:host all all 127.0.0.1/32 ident改为:
hostssl all all 127.0.0.1/32 scram-sha-256另外,您可以通过添加以下新行来限制单个数据库和用户的访问:
hostssl mydatabase mydbuser 127.0.0.1/32 scram-sha-256将 mydatabase 替换为数据库名称,并将 mydbuser 替换为用户名。
通过重启
postgresql服务来有效地进行更改:# systemctl restart postgresql.service
验证
手动验证连接是否已加密:
以 mydbuser 用户身份连接到 PostgreSQL 数据库,指定主机名和数据库名称:
$ psql -U mydbuser -h 127.0.0.1 -d mydatabase Password for user mydbuser:将 mydatabase 替换为数据库名称,并将 mydbuser 替换为用户名。
获取有关当前数据库连接的信息:
mydbuser=> \conninfo You are connected to database "mydatabase" as user "mydbuser" on host "127.0.0.1" at port "5432". SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
您可以编写一个简单的应用程序,验证与 PostgreSQL 的连接是否已加密。本例演示了使用 C 编写的那些使用
libpq客户端库(由libpq-devel软件包提供)的应用程序:#include <stdio.h> #include <stdlib.h> #include <libpq-fe.h> int main(int argc, char* argv[]) { //Create connection PGconn* connection = PQconnectdb("hostaddr=127.0.0.1 password=mypassword port=5432 dbname=mydatabase user=mydbuser"); if (PQstatus(connection) ==CONNECTION_BAD) { printf("Connection error\n"); PQfinish(connection); return -1; //Execution of the program will stop here } printf("Connection ok\n"); //Verify TLS if (PQsslInUse(connection)){ printf("TLS in use\n"); printf("%s\n", PQsslAttribute(connection,"protocol")); } //End connection PQfinish(connection); printf("Disconnected\n"); return 0; }将 mypassword 替换为密码,将 mydatabase 替换为数据库名称,并将 mydbuser 替换为用户名。
注意您必须使用
-lpq选项为编译加载pq库。例如,使用 GCC 编译器编译应用程序:$ gcc source_file.c -lpq -o myapplication其中 source_file.c 包含上面的示例代码,myapplication 是应用程序的名称,用于验证安全的 PostgreSQL 连接。
例 4.2. 使用 TLS 加密初始化、创建和连接到 PostgreSQL 数据库
本例演示如何初始化 PostgreSQL 数据库,创建数据库用户和数据库,以及如何使用安全连接连接到数据库。
安装 PosgreSQL 服务器:
# dnf install postgresql-server初始化数据库集群:
# postgresql-setup --initdb * Initializing database in '/var/lib/pgsql/data' * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log安装 OpenSSL 库:
# dnf install openssl生成 TLS 证书和密钥:
# openssl req -new -x509 -days 365 -nodes -text -out server.crt \ -keyout server.key -subj "/CN=dbhost.yourdomain.com"将 dbhost.yourdomain.com 替换为您的数据库主机和域名。
将签名的证书和私钥复制到数据库服务器的所需位置:
# cp server.{key,crt} /var/lib/pgsql/data/.将签名证书的所有者和组所有权改为
postgres用户:# chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}限制私钥的权限,使其只可由所有者读取:
# chmod 0400 /var/lib/pgsql/data/server.key将密码哈希算法设置为
scram-sha-256。在/var/lib/pgsql/data/postgresql.conf文件中,更改以下行:#password_encryption = md5 # md5 or scram-sha-256改为:
password_encryption = scram-sha-256将 PostgreSQL 配置为使用 SSL/TLS。在
/var/lib/pgsql/data/postgresql.conf文件中,更改以下行:#ssl = off改为:
ssl=on启动
postgresql服务:# systemctl start postgresql.service以名为
postgres的系统用户登录:# su - postgres以
postgres用户身份启动 PostgreSQL 互动终端:$ psql -U postgres psql (13.7) Type "help" for help. postgres=#创建名为
mydbuser的用户,再为mydbuser设置一个密码:postgres=# CREATE USER mydbuser WITH PASSWORD 'mypasswd'; CREATE ROLE postgres=#创建名为
mydatabase的数据库:postgres=# CREATE DATABASE mydatabase; CREATE DATABASE postgres=#为
mydbuser用户授予所有权限:postgres=# GRANT ALL PRIVILEGES ON DATABASE mydatabase TO mydbuser; GRANT postgres=#从互动终端注销:
postgres=# \q注销
postgres用户会话:$ logout通过更改
/var/lib/pgsql/data/pg_hba.conf文件中的 IPv4 本地连接,将所有数据库的访问限制为只使用 TLS 的客户端的连接:host all all 127.0.0.1/32 ident改为:
hostssl all all 127.0.0.1/32 scram-sha-256通过重启
postgresql服务来有效地进行更改:# systemctl restart postgresql.service以
mydbuser用户身份连接到 PostgreSQL 数据库,指定主机名和数据库名称:$ psql -U mydbuser -h 127.0.0.1 -d mydatabase Password for user mydbuser: psql (13.7) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. mydatabase=>