【问题标题】:Unable to connect to postgres with node.js via SSL (unsupported protocol)无法通过 SSL 使用 node.js 连接到 postgres(不支持的协议)
【发布时间】:2020-02-27 19:30:19
【问题描述】:

我可以使用相同的凭据通过 pgAdmin 连接到 postgres 实例,但我无法从我的 node.js 服务器连接。我正在我的 Mac 上运行通过 Homebrew 安装的最新节点版本。

import { Client } from 'pg'
const config = {
    user,
    host,
    database: DATABASE,
    password,
    port: 5432,
    ssl: {
        rejectUnauthorized: false,
        key: fs.readFileSync('./certs/postgresql.key').toString(),
        cert: fs.readFileSync('./certs/postgresql.crt').toString(),
    };
}

const client = new Client(config)
client.connect((err) => {
    if (err) {
        throw err;
    }
});

这是我调用connect时遇到的错误:

Error: write EPROTO 4499043776:error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol:../deps/openssl/openssl/ssl/statem/statem_lib.c:1929:

我尝试使用以下命令通过 openssl 连接到主机,它似乎可以连接。

openssl s_client -starttls postgres -connect <ip>:5432

...
Peer signing digest: MD5-SHA1
Peer signature type: RSA
Server Temp Key: DH, 1024 bits
---
SSL handshake has read 4437 bytes and written 511 bytes
Verification error: self signed certificate in certificate chain
---
New, SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 67F98918A51486780EE40B6F2430310A04CBE141AEC7A78C09EAAC1B6AD62E52
    Session-ID-ctx: 
    Master-Key: C296DD7EAD31580A7D1B3688DA170C3861F5F35755F93BC2A90CACAD7C640B761764C446797475892D785B6A37D278EE
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - c8 c2 49 99 40 4b ed f7-e2 d5 61 6d 3d dc 3a 15   ..I.@K....am=.:.
    0010 - 80 b8 31 c8 9a e0 cd 2c-57 90 5a ed 10 aa 3a c7   ..1....,W.Z...:.
    0020 - eb 61 59 c4 d8 b0 ab 05-16 f5 b7 35 42 dc e8 d5   .aY........5B...
    0030 - c9 06 38 b6 e9 fd 81 bd-ad bc 56 30 e2 92 a7 89   ..8.......V0....
    0040 - a6 30 0b bc 71 a7 3d 63-90 ec fc f0 b2 ca 3f 0a   .0..q.=c......?.
    0050 - 44 4c 57 b3 9f 0c 7f 05-3a 78 6d 90 bc 37 3d 17   DLW.....:xm..7=.
    0060 - a4 0b 53 25 c4 d6 88 4b-a1 f2 57 31 07 21 bf 78   ..S%...K..W1.!.x
    0070 - 14 b3 93 60 a6 e9 ba 16-0e 48 d1 42 4e 8a e9 83   ...`.....H.BN...
    0080 - 53 c0 fe 7e 65 29 e4 e6-02 81 39 aa 3d 3e 0a 9b   S..~e)....9.=>..
    0090 - c2 a9 17 5a 34 c8 21 3c-9c 96 44 84 d1 48 c8 21   ...Z4.!<..D..H.!

    Start Time: 1582830738
    Timeout   : 7200 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
    Extended master secret: no
---

【问题讨论】:

  • “不支持的协议”表示客户端尝试连接的 SSL/TLS 版本不受支持。很可能是因为它太旧了。您将不得不查看它支持的 SSL/TLS 客户端版本(可能是它使用的 opensll 库版本?)。您可能还需要指定要连接的版本?
  • 据我所知,node.js 包含 openssl 并且节点 13.8.0 使用的是最新的 openssl。虽然服务器不在我的控制之下,所以我对它的功能一无所知。
  • 我的猜测是客户端配置不正确,无法成功连接到服务器。我不是节点人,所以我认为最好的办法是让您查看配置设置中可用的选项,并尝试将其设置为服务器喜欢的选项。

标签: node.js postgresql ssl openssl


【解决方案1】:

我认为问题在于服务器支持的唯一协议是 TLSv1,因此 unsupported protocol 错误源于客户端代码试图使用其他更新而不是太旧的东西。

我需要在配置的 ssl 部分使用 secureOptions 来强制它使用 TLSv1。

const config = {
    user,
    host,
    database: DATABASE,
    password,
    port: 5432,
    ssl: {
        rejectUnauthorized: false,
        key: fs.readFileSync('./certs/postgresql.key').toString(),
        cert: fs.readFileSync('./certs/postgresql.crt').toString(),
        secureOptions: constants.SSL_OP_NO_TLSv1_1 | constants.SSL_OP_NO_TLSv1_2 | constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3,

    };
}

【讨论】:

    猜你喜欢
    • 2021-05-04
    • 2020-10-03
    • 2021-11-03
    • 1970-01-01
    • 2014-08-14
    • 2018-10-26
    • 2020-12-22
    • 2022-07-23
    • 1970-01-01
    相关资源
    最近更新 更多