代码改变世界

【PostgreSQL】PostgreSQL开启ssl/tls

  abce  阅读(4923)  评论(0编辑  收藏  举报

没有Cert/Key文件时开启SSL/TLS

来看看在没有证书或keys文件的场景下,开启SSL/TLS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
postgres=# show ssl;
 ssl
-----
 off
(1 row)
 
postgres=# alter system set ssl=on;
ALTER SYSTEM
postgres=# select pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)
 
postgres=#

修改过程没有任何报错,但是我们真的使用了SSL?如果我们查看错误日志,会看到以下错误信息:

1
2
3
4
2022-07-06 15:13:41.574 CST [1196] LOG:  received SIGHUP, reloading configuration files
2022-07-06 15:13:41.575 CST [1196] LOG:  parameter "ssl" changed to "on"
2022-07-06 15:13:41.576 CST [1196] LOG:  could not load server certificate file "server.crt": No such file or directory
2022-07-06 15:13:41.576 CST [1196] LOG:  SSL configuration was not reloaded

创建证书

因此,我们首先要创建上面的提到的文件。如果没有,可以创建一个,例如:

1
2
3
4
5
6
7
# cd /var/lib/pgsql/14/data
# openssl req -nodes -new -x509 -keyout server.key -out server.crt -subj '/C=US/L=NYC/O=Percona/CN=postgres'
Generating a 2048 bit RSA private key
....+++
.........................+++
writing new private key to 'server.key'
-----

在创建之前,我们已经修改了当前目录到postgresql的数据目录。然后修改一下文件的权限和属主

1
2
3
4
5
# chmod 400 server.{crt,key}
# chown postgres:postgres server.{crt,key}
# ll server.{crt,key}
-r--------. 1 postgres postgres 1212 Jul  6 20:12 20:49 server.crt
-r--------. 1 postgres postgres 1704 Jul  6 20:12 20:49 server.key

开启SSL/TLS

1
2
3
4
5
6
7
postgres=# alter system set ssl=on;
ALTER SYSTEM
postgres=# select pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

这次就不会报错了:

1
2
2022-07-06  20:49:05.823 UTC [5284] LOG:  received SIGHUP, reloading configuration files
2022-07-06  20:49:05.823 UTC [5284] LOG:  parameter "ssl" changed to "on"

至此,我们已经开启了SSL。但是,我们还要配置文件pg_hba.conf。我们可以使用关键字”hostssl“来代替”host“强制postgresql使用ssl。”host“验证也可以看到有会话使用ssl,因为”host“支持使用ssl连接,但是不会强制。假设pg_hba.conf配置是这样的:

1
2
3
4
5
6
# TYPE  DATABASE        USER   ADDRESS            METHOD
local   all             all                       peer
host    all             all    127.0.0.1/32       scram-sha-256
host    all             all    ::1/128            scram-sha-256
host    all             all    0.0.0.0/0          md5
host    replication     all    10.124.33.113/24   md5

如果希望所有远程连接都是用ssl连接,可以这样:

1
2
3
4
5
6
# TYPE   DATABASE       USER    ADDRESS            METHOD
local    all            all                        peer
host     all            all     127.0.0.1/32       scram-sha-256
host     all            all     ::1/128            scram-sha-256
hostssl  all            all     0.0.0.0/0          md5
hostssl  replication    all     10.124.33.113/24   md5


同样,如果我们坚持真正强制连接以使用SSL,这还不够。我们必须再次调用pg_reload_conf()以确保它们被加载:

1
2
3
4
5
postgres=# select pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

至此,远程非ssl连接会被拒绝。

1
2
# psql "host=192.168.56.111 sslmode=disable"
psql: error: connection to server at "192.168.56.111", port 5432 failed: FATAL:  no pg_hba.conf entry for host "192.168.56.112", user "postgres", database "postgres", no encryption

检查使用SSL/TLS的会话连接

1
2
3
4
5
6
7
8
9
10
11
postgres=# select pg_ssl.pid, pg_ssl.ssl, pg_ssl.version,
           pg_sa.backend_type, pg_sa.usename, pg_sa.client_addr
           from pg_stat_ssl pg_ssl
           join pg_stat_activity pg_sa
             on pg_ssl.pid = pg_sa.pid;
 pid  | ssl | version |  backend_type  | usename  |  client_addr
------+-----+---------+----------------+----------+---------------
 5547 | f   |         | walsender      | postgres | 192.168.56.12
 5549 | f   |         | client backend | postgres | 192.168.56.11
 5556 | f   |         | client backend | postgres | 192.168.56.12
(3 rows)

这里,复制连接walsender还没有使用ssl,其它两个会话也是。需要重启一下让他们重新建立连接。可以重启,也可以使用pg_terminate_backend(主节点或复制节点都可以)。例如:

1
2
3
4
5
postgres=# select pg_terminate_backend(5547);
 pg_terminate_backend
----------------------
 t
(1 row)

 

重新建立连接后就使用ssl了:

1
2
3
4
5
6
7
8
9
10
11
postgres=# select pg_ssl.pid, pg_ssl.ssl, pg_ssl.version,
           pg_sa.backend_type, pg_sa.usename, pg_sa.client_addr
           from pg_stat_ssl pg_ssl
           join pg_stat_activity pg_sa
             on pg_ssl.pid = pg_sa.pid;
 pid  | ssl | version |  backend_type  | usename  |  client_addr
------+-----+---------+----------------+----------+---------------
 5557 | t   | TLSv1.2 | walsender      | postgres | 192.168.56.12
 5549 | f   |         | client backend | postgres | 192.168.56.11
 5556 | f   |         | client backend | postgres | 192.168.56.12
(3 rows)

pid 5549是psql自己,可以轻松解决:

1
2
3
4
5
postgres=# select pg_backend_pid();
 pg_backend_pid
----------------
           5549
(1 row)

客户端可以通过 \conninfo检查自己的连接信息:​

1
2
3
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" on host "192.168.56.11" at port "5432".
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)


 

 

 

 

 

 

 

 

 

 

 

 

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2016-07-08 Rman备份的保留策略(retention policy)
2015-07-08 11g新特性-自动sql调优(Automatic SQL Tuning)
2015-07-08 如何修改DBSNMP和SYSMAN用户的密码
点击右上角即可分享
微信分享提示