如何强制客户端使用 SSL 连接 PostgreSQL?

3

环境:

Windows 10, localhost, same machine
pg 12
node 14
openssl 1.1.1k

我已阅读并完成了从这里开始的pg文档。 postgresql.conf(位于C:\Program Files\PostgreSQL\12\data中,我的理解是它控制pg数据库服务器)。
ssl = on # per pg doc: server will listen for both normal and SSL connections on the same TCP port, and will negotiate with any connecting client on whether to use SSL
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' 
ssl_prefer_server_ciphers = on
ssl_ca_file = 'root.crt' # per pg doc, 18.9.3: To require the client to supply a trusted certificate
ssl_crl_file = ''

pg_hba.conf(位于C:\ Program Files \ PostgreSQL \ 12 \ data中,我的理解是它的影响是在客户端,比如Web API或任何DB消费者上,而不是在DB服务器上)


...
hostssl all             all             127.0.0.1/32 cert clientcert=1
...

pSQL显示它正在通过SSL进行通信: enter image description here

但一个简单的Node项目也可以连接无需SSL:

require('dotenv').config({ path: './environment/PostgreSql.env'});

const pgp = require('pg-promise')();    

const db = pgp(
    {
        user: process.env.PGuser,
        host: process.env.PGhost,
        database: process.env.PGdatabase,
        password: process.env.PGpassword,
        port: process.env.PGport,
        
        ssl: false  // optional, but true gets code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
    }
);

var sql = 'select * from current.testssl()';  
db.any(sql)
    .then
    (
        good => 
        { 
            console.log(good); // ssl false gets data 
        },
        bad => 
        { 
            console.log(bad); 
/* ssl true gets 
at TLSWrap.callbackTrampoline (internal/async_hooks.js:130:17) 
{
code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', 
stack: 'Error: unable to verify the first certificate…ckTrampoline (internal/async_hooks.js:130:17)', 
message: 'unable to verify the first certificate'
}
*/
            
        }
    );

最终解决方案基于@Lauranz Albe和@jjanes的pg_hba.conf:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
hostnossl  all  all  0.0.0.0/0  reject  # must be the 1st line!
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5
hostssl all             all             0.0.0.0/0   cert clientcert=verify-full

问题出在你没有向我们展示的某些地方。你的.env文件中有什么?你的pg_hba.conf文件中其余的行是按照什么顺序排列的? - jjanes
@jjanes .env 包含了上面代码中显示的内容:user, host, databasename, password 等等。请完成上面 pg_hba.conf 的内容。 - Jeb50
1
拒绝必须是第一行,而不是最后一行。但是主机是什么?它很重要实际上是什么(也许在那个pg_hba中并不重要,但一般情况下重要。 127.0.0.1与192.168.0.37不同) - jjanes
@jjanes 主机?本地主机。它适用于节点项目。pgAdmin仍然能够在http://127.0.0.1:53819/browser/上连接而不需要httpS。谢谢! - Jeb50
1个回答

4
在您的 pg_hba.conf 文件的开头添加以下行:
hostnossl  all  all  0.0.0.0/0  reject

然后,您需要重新加载PostgreSQL(如果重新加载导致任何错误,请检查日志文件)。

这将拒绝所有使用未加密TCP连接的连接尝试。

有关详细信息,请参见文档


仍然是一样的,我还尝试了 hostnossl all all 127.0.0.1/32 reject 并重新启动了机器。这是因为我在同一台机器上吗? - Jeb50
我忘了提到你需要重新加载PostgreSQL。如果仍然无法正常工作,则您正在编辑错误的 pg_hba.conf 文件。 - Laurenz Albe
你是对的要重新加载。每次编辑后,我都会“关闭”机器至少10秒钟,然后再重新开机。测试了hostnossl all all 0.0.0.0/0 rejecthostnossl all all 127.0.0.1/32 reject。我的机器上只有一个pg_hba.conf,位于C:\Program Files\PostgreSQL\12\data(pg的数据目录)。我还尝试添加一些额外的内容,结果得到了LOG F0000 authentication option not in name=value format: md5 FATAL XX000 could not load pg_hba.conf的错误提示。 - Jeb50
那么你的条目顺序就不正确。 - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接