条纹 TLS 1.2 Webhook 问题
Stripe TLS 1.2 Webhook issue
我正在开发一个 API 使用 Node.js 和 express 框架连接到 Stripe。我的 API 是容器 (FROM node:10.1.0
) 中的 运行,我是 运行 使用 docker-compose 的 Ubuntu 16 VM 上的容器:
version: '2.2'
services:
api:
image: my-image:latest
expose:
- 80
nginx:
image: nginx
ports:
- "80:80"
- "443:443"
links:
- api
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
和 nginx.conf
文件:
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
ssl_ciphers TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-ARIA256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-ARIA128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ARIA256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ARIA128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-CCM:DHE-RSA-AES256-CCM8:DHE-RSA-ARIA256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-CCM:DHE-RSA-AES128-CCM8:DHE-RSA-ARIA128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384;
ssl_ecdh_curve X25519:secp521r1:secp384r1;
ssl_prefer_server_ciphers on;
try_files $uri $uri/ =404;
location /api/ {
proxy_pass http://api:80/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
当 运行 curl -XPOST https://my.server.com/api/webhook --tlsv1.2 --verbose
我得到一个看起来像 TLS 1.2 正在工作的很好的响应:
* Trying 23.100.121.74...
* TCP_NODELAY set
* Connected to my.server.com (23.100.121.74) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: OU=Domain Control Validated; CN=*.server.com
* start date: Sep 7 16:29:45 2018 GMT
* expire date: Sep 7 16:29:45 2019 GMT
* subjectAltName: host "my.server.com" matched cert's "*.server.com"
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify ok.
> POST /api/webhook HTTP/1.1
> Host: my.server.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.15.7
< Date: Fri, 22 Mar 2019 17:50:33 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 68
< Connection: keep-alive
< X-Powered-By: Express
< Vary: Origin
< ETag: W/"44-HsiDCuzDBw0t2vb7UevWXjyvmIo"
<
* Connection #0 to host api.server.com left intact
{"message":"Unable to extract timestamp and signatures from header"}
但是,我的服务器上没有收到任何 webhook(在本地使用 ngrok 有效),在 Stripe plateform 上检查 webhook 时,我可以在我的服务器 webhook 试验中看到这个错误:
Status Pending (2 tries)
Next retry around 2019/03/22 18:38 (1 attempt left)
Retry history
[2019/03/22 17:08 to https://my.server.com/api/webhook]: (TLS error) ERR
[2019/03/22 17:38 to https://my.server.com/api/webhook]: (TLS error) ERR
我试过了 https://support.stripe.com/questions/how-do-i-upgrade-my-openssl-to-support-tls-1-2 on the linux VM but nothing changed. Also https://support.stripe.com/questions/upgrade-your-node-integration-from-tls-1-0-to-tls-1-2 告诉我 TLS 1.2 is supported
所以不确定哪里错了
Stripe 需要为 HTTPS webhook 端点提供有效的 TLS 证书,并且当您的站点缺少中间 SSL 证书时,通常会出现这些问题。具体来说,在您的 SSL 实验室结果中,您将看到证书路径部分中的一项标记为 "Extra download."。您可以在这里确认:https://www.ssllabs.com/ssltest/analyze.html
如果您看到此问题,我建议您访问您的证书颁发者(或您购买证书的经销商),并重新安装您的 SSL 证书,包括它附带的任何 CA 证书 'bundle'。如果您在这方面遇到问题,我建议您直接与颁发者和您的网络托管服务商分享您的 SSL 实验室结果,他们可以指导您找到这个中间证书并解决这个问题。
我设法通过使用 https://whatsmychaincert.com/ 创建丢失的 "chain" 来解决问题,然后使用以下命令添加到从 Azure App Service Cerificate 获取的证书中:
cat fullchain.pem example.com.chain.crt > example.com.chained.crt
并在 nginx 中使用 example.com.chained.crt
代替 ssl_certificate
。现在 ssllab 告诉我链条已经完成,Stripe 给了我 200 成功
如果您在 运行 使用 NGINX 代理服务器设置服务器时遇到此问题,您可以解决此问题(由于 SSL 链问题),如这篇优秀博客 post 来自 Sectigo。
关于如何安装中间证书以解决链问题的详细分步说明:
https://support.sectigo.com/Com_KnowledgeDetailPage?Id=kA01N000000zFJQ
我正在开发一个 API 使用 Node.js 和 express 框架连接到 Stripe。我的 API 是容器 (FROM node:10.1.0
) 中的 运行,我是 运行 使用 docker-compose 的 Ubuntu 16 VM 上的容器:
version: '2.2'
services:
api:
image: my-image:latest
expose:
- 80
nginx:
image: nginx
ports:
- "80:80"
- "443:443"
links:
- api
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
和 nginx.conf
文件:
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
ssl_ciphers TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-ARIA256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-ARIA128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ARIA256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ARIA128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-CCM:DHE-RSA-AES256-CCM8:DHE-RSA-ARIA256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-CCM:DHE-RSA-AES128-CCM8:DHE-RSA-ARIA128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384;
ssl_ecdh_curve X25519:secp521r1:secp384r1;
ssl_prefer_server_ciphers on;
try_files $uri $uri/ =404;
location /api/ {
proxy_pass http://api:80/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
当 运行 curl -XPOST https://my.server.com/api/webhook --tlsv1.2 --verbose
我得到一个看起来像 TLS 1.2 正在工作的很好的响应:
* Trying 23.100.121.74...
* TCP_NODELAY set
* Connected to my.server.com (23.100.121.74) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: OU=Domain Control Validated; CN=*.server.com
* start date: Sep 7 16:29:45 2018 GMT
* expire date: Sep 7 16:29:45 2019 GMT
* subjectAltName: host "my.server.com" matched cert's "*.server.com"
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify ok.
> POST /api/webhook HTTP/1.1
> Host: my.server.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.15.7
< Date: Fri, 22 Mar 2019 17:50:33 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 68
< Connection: keep-alive
< X-Powered-By: Express
< Vary: Origin
< ETag: W/"44-HsiDCuzDBw0t2vb7UevWXjyvmIo"
<
* Connection #0 to host api.server.com left intact
{"message":"Unable to extract timestamp and signatures from header"}
但是,我的服务器上没有收到任何 webhook(在本地使用 ngrok 有效),在 Stripe plateform 上检查 webhook 时,我可以在我的服务器 webhook 试验中看到这个错误:
Status Pending (2 tries)
Next retry around 2019/03/22 18:38 (1 attempt left)
Retry history
[2019/03/22 17:08 to https://my.server.com/api/webhook]: (TLS error) ERR
[2019/03/22 17:38 to https://my.server.com/api/webhook]: (TLS error) ERR
我试过了 https://support.stripe.com/questions/how-do-i-upgrade-my-openssl-to-support-tls-1-2 on the linux VM but nothing changed. Also https://support.stripe.com/questions/upgrade-your-node-integration-from-tls-1-0-to-tls-1-2 告诉我 TLS 1.2 is supported
所以不确定哪里错了
Stripe 需要为 HTTPS webhook 端点提供有效的 TLS 证书,并且当您的站点缺少中间 SSL 证书时,通常会出现这些问题。具体来说,在您的 SSL 实验室结果中,您将看到证书路径部分中的一项标记为 "Extra download."。您可以在这里确认:https://www.ssllabs.com/ssltest/analyze.html
如果您看到此问题,我建议您访问您的证书颁发者(或您购买证书的经销商),并重新安装您的 SSL 证书,包括它附带的任何 CA 证书 'bundle'。如果您在这方面遇到问题,我建议您直接与颁发者和您的网络托管服务商分享您的 SSL 实验室结果,他们可以指导您找到这个中间证书并解决这个问题。
我设法通过使用 https://whatsmychaincert.com/ 创建丢失的 "chain" 来解决问题,然后使用以下命令添加到从 Azure App Service Cerificate 获取的证书中:
cat fullchain.pem example.com.chain.crt > example.com.chained.crt
并在 nginx 中使用 example.com.chained.crt
代替 ssl_certificate
。现在 ssllab 告诉我链条已经完成,Stripe 给了我 200 成功
如果您在 运行 使用 NGINX 代理服务器设置服务器时遇到此问题,您可以解决此问题(由于 SSL 链问题),如这篇优秀博客 post 来自 Sectigo。
关于如何安装中间证书以解决链问题的详细分步说明:
https://support.sectigo.com/Com_KnowledgeDetailPage?Id=kA01N000000zFJQ