node.js - 使用 Express Gateway 的证书验证错误

标签 node.js express ssl openssl express-gateway

在使用由 OpenSSL 生成的证书时,我无法让 Express Gateway 连接到后端服务。每当网关尝试连接到服务时,我都会在日志中收到此错误:

project_edge_express_1    | 2019-12-03T23:44:32.189Z [EG:gateway] debug: request matched condition in proxy policy
project_edge_express_1    | 2019-12-03T23:44:32.189Z [EG:policy] debug: proxying to https://api.project.local/, POST /oauth/token
project_edge_express_1    | 2019-12-03T23:44:32.266Z [EG:policy] warn: unable to verify the first certificate

我原以为这是一个证书问题,并经历了几轮重新生成证书。以下是我最新迭代的输出:

C:\..\carbon> openssl x509 -in .\ca\intermediate\certs\api.project.local.cert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4096 (0x1000)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=Oklahoma, CN=Development Intermediate CA
        Validity
            Not Before: Dec  3 04:09:36 2019 GMT
            Not After : Nov 30 04:09:36 2029 GMT
        Subject: C=US, ST=Oklahoma, L=Oklahoma City, CN=api.project.local
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b6:f6:d1:60:88:db:8e:a4:b3:bd:8e:61:02:8b:
                    ...
                    69:6b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier:
                88:72:74:76:DC:3A:3B:AD:47:7D:85:60:F4:35:2C:76:E3:F2:0D:E0
            X509v3 Authority Key Identifier:
                keyid:9B:95:50:21:22:4A:66:48:5A:43:E2:0D:8D:A4:25:93:8E:4D:4F:27
                DirName:/C=US/ST=Oklahoma/L=Oklahoma City/CN=Development Root CA
                serial:10:00

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:api.project.local
    Signature Algorithm: sha256WithRSAEncryption
         b6:2e:ee:69:a6:4d:0e:4d:dc:f4:42:31:4e:77:10:56:fa:3d:
         ...
         c6:eb:40:17:08:82:4c:0f

但是,当我登录到运行 express 的容器并执行手动证书检查时,OpenSSL 报告证书有效:

C:\..\project> docker exec -it project_edge_express_1 /bin/bash
root@efc66f266d19:/usr/src/app# openssl s_client -connect api.project.local:443
CONNECTED(00000003)
depth=2 C = US, ST = Oklahoma, L = Oklahoma City, CN = Development Root CA
verify return:1
depth=1 C = US, ST = Oklahoma, L = Oklahoma City, CN = Intermediate CA
verify return:1
depth=0 C = US, ST = Oklahoma, L = Oklahoma City, CN = api.project.local
verify return:1
---
Certificate chain
 0 s:/C=US/ST=Oklahoma/L=Oklahoma City/CN=api.project.local
   i:/C=US/ST=Oklahoma/L=Oklahoma City/CN=Development Intermediate CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIF3DCCA8SgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbTELMAkGA1UEBhMCVVMx
...
kBOe8nsEvMnG60AXCIJMDw==
-----END CERTIFICATE-----
subject=/C=US/ST=Oklahoma/L=Oklahoma City/CN=api.project.local
issuer=/C=US/ST=Oklahoma/L=Oklahoma City/CN=Development Intermediate CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2129 bytes and written 269 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: CC...B8
    Session-ID-ctx:
    Master-Key: 0A...D631C75477            PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - ...

    Start Time: 1575416738
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes

我什至尝试在 Express 网关中手动禁用证书验证。这是我当前的配置:

http:
  port: 8080
admin:
  port: 9876
  host: localhost
apiEndpoints:
  api:
    - host: localhost
      paths: '/ip'

    - host: localhost
      paths: '/oauth/token'
      methods: ['POST']

    - host: localhost
      paths: '/v1/*'
serviceEndpoints:
  httpbin:
    url: 'https://httpbin.org'
  project:
    url: 'https://api.project.local'
policies:
  - cors
  - log
  - proxy
pipelines:
  default:
    apiEndpoints:
      - api
    policies:
      - proxy:
          secure: false
          condition: 
            name: pathExact
            path: /oauth/token
          action:
            serviceEndpoint: oauth

除了依靠陌生人的善意,我不知道该何去何从。

更新 2019 年 12 月 3 日晚上 8:05 CST:

我使用 https 库在 Node 中编写了一个小型 POC,并使用该库运行相同的请求。请求按预期进行。我还使用 cURL 验证了请求,结果也成功了。

更新 2019 年 12 月 4 日上午 6:31 CST:

这是构建运行 Express Gateway 的容器的 Dockerfile,以备不时之需:

FROM node:10

COPY ./ca/intermediate/certs/ca-chain.cert.pem /usr/local/share/ca-certificates/ca-chain.crt
RUN chmod 644 /usr/local/share/ca-certificates/* && update-ca-certificates

WORKDIR /usr/src/app

COPY edge/gateway/package*.json ./

RUN npm install

COPY edge/gateway .

EXPOSE 8080
CMD [ "node", "server.js" ]

最佳答案

NodeJS 不信任操作系统的 CA 列表。

检查 this回答。

您需要使用 NODE_EXTRA_CA_CERTS 选项运行 Node。

关于node.js - 使用 Express Gateway 的证书验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59167188/

相关文章:

node.js - 如何切片或限制动态嵌套数组nodejs

javascript - 类型错误 : Cannot read property 'left' of undefined

redirect - Nginx 通配符子域重定向到非 www

ssl - docker nginx容器上配置https失败,一直报超时

angularjs - 如何在ejs中发送对象作为函数参数

javascript - 运行 exec 命令时保留输出颜色

node.js - 游标.sort()和聚合$sort之间的区别

api - 使用node-trello模块发送post请求

node.js - 我想使用 Stormpath、Express.js 和 Node.js。我想要stormpath-express 还是express-stormpath?

java - 主机名 validator 实现