0

在 openshift 中,我们托管了基于 Spring Boot 的微服务。其中一个微服务通过连接到 smtp 服务器发送电子邮件。smtp 服务器是组织的一部分,它不是外部服务器。当服务尝试发送电子邮件时,我收到以下错误:此错误仅发生在较高级别的环境中,而不发生在较低级别的 DEV 环境中。可能是什么原因?

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;

当我尝试以下命令时,从 pods 终端

curl --ssl-reqd --url 'smtp://mailhost.myorg.com:587' --user 'usrname:pwd' --mail-from 'fromaddress@myorg.com' --mail-rcpt 'toaddr@myorg.com' --upload-file mail.txt -vv

即使在 DEV 中,我也会收到以下错误。

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* About to connect() to mailhost.myorg.com port 587 (#0)
*   Trying 10.46.113.103...
* Connected to mailhost.myorg.com (10.46.113.103) port 587 (#0)
< 220-SVR.MYORG.corp ESMTP
< 220 Welcome to the Myorg Secure SMTP Relay
> EHLO mail.txt
< 250-myserv.myorg.corp
< 250-8BITMIME
< 250-SIZE 26214400
< 250 STARTTLS
> STARTTLS
< 220 Go ahead with TLS
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Server certificate:
*       subject: CN=myserv.myorg.corp,OU=SSL Servers,O=MyORG Inc,C=US
*       start date: Sep 21 13:41:03 2020 GMT
*       expire date: Sep 21 14:11:03 2022 GMT
*       common name: myserv.myorg.corp
*       issuer: CN=MyORG Inc Issuing CA,OU=Certification Authorities,O=MyORG Inc,C=US
* NSS error -8172 (SEC_ERROR_UNTRUSTED_ISSUER)
* Peer's certificate issuer has been marked as not trusted by the user.
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

所以我的问题是

  1. 当我做 curl 时,为什么它不能在 DEV 和更高的环境中工作
  2. 当我让我的服务发送电子邮件时,为什么它在 DEV 中工作而不是在更高的环境中工作
4

1 回答 1

1

您需要使用以下命令将邮件服务器证书添加到 docker 容器内的 jre cacert:

COPY mailServ.crt $JAVA_HOME/jre/lib/security
RUN \
    cd $JAVA_HOME/jre/lib/security \
    && keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias config -file mailServ.crt

587 端口是 SMTP 的默认非安全和安全端口(一些传统 ISP 仍在使用 465 进行 ssl)。可能在您的 DEV 环境中 SSL 未在端口 587 上启用,而在生产环境中 SSL 是强制性的。

至于 curl,可能你需要选项 --cacert mailServ.crt。此外,在 DEV 环境中,您的 JDK cacerts 中可能有您的自签名证书 mailServ.crt,但 curl 不会使用它,除非您放置 --cacert mailServ.crt。您也可以按照自签名证书的建议使用 --insecure 选项。

于 2020-12-20T17:35:22.537 回答