如何强制客户端对 postgresql 使用 SSL?
How to enforce client to use SSL for postgresql?
环境:
Windows 10, localhost, same machine
pg 12
node 14
openssl 1.1.1k
我已经阅读并完成了从 this 开始的 pg 文档。
postgresql.conf(在C:\Program Files\PostgreSQL\data,我的理解是控制pg DB服务器)
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\data中,我的理解是它的效果是在客户端如web API或任何数据库消费者,而不是数据库服务器)
...
hostssl all all 127.0.0.1/32 cert clientcert=1
...
pSQL 显示它正在通过 SSL 进行通信:
但是一个简单的节点项目可以连接没有 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
在 pg_hba.conf
的开头添加以下行:
hostnossl all all 0.0.0.0/0 reject
然后您必须重新加载 PostgreSQL(如果重新加载导致任何错误,请检查日志文件)。
这将拒绝所有使用未加密 TCP 连接的连接尝试。
环境:
Windows 10, localhost, same machine
pg 12
node 14
openssl 1.1.1k
我已经阅读并完成了从 this 开始的 pg 文档。
postgresql.conf(在C:\Program Files\PostgreSQL\data,我的理解是控制pg DB服务器)
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\data中,我的理解是它的效果是在客户端如web API或任何数据库消费者,而不是数据库服务器)
...
hostssl all all 127.0.0.1/32 cert clientcert=1
...
pSQL 显示它正在通过 SSL 进行通信:
但是一个简单的节点项目可以连接没有 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
在 pg_hba.conf
的开头添加以下行:
hostnossl all all 0.0.0.0/0 reject
然后您必须重新加载 PostgreSQL(如果重新加载导致任何错误,请检查日志文件)。
这将拒绝所有使用未加密 TCP 连接的连接尝试。