使用mysql-client从Alpine Docker映像内部通过SSL连接到Amazon RDS。 并validation证书

我有一个数据库托pipe在亚马逊RDS(欧洲西部2区)。

我试图从一个Docker容器中连接到它。 我的中级证书是rds-ca-2015-eu-west-2.pem

Ubuntu工作正常:

 docker run --rm -v "$PWD/rds-ca-2015-eu-west-2.pem:/ca.pem:ro,cached" ubuntu sh -c '\ apt-get update > /dev/null \ && apt-get install -y mysql-client > /dev/null \ && mysql \ -h MYDATABASE.eu-west-2.rds.amazonaws.com \ -P 3306 \ -u MYUSERNAME \ -pMYPASSWORD \ --ssl-mode=VERIFY_IDENTITY \ --ssl-ca=/ca.pem \ -e "SELECT NOW();"' 

输出:

 mysql: [Warning] Using a password on the command line interface can be insecure. NOW() 2017-08-31 13:03:05 

但阿尔卑斯的行为有所不同:

 docker run --rm -v "$PWD/rds-ca-2015-eu-west-2.pem:/ca.pem:ro,cached" alpine sh -c '\ apk update > /dev/null \ && apk add mysql-client > /dev/null \ && mysql \ -h MYDATABASE.eu-west-2.rds.amazonaws.com \ -P 3306 \ -u MYUSERNAME \ -pMYPASSWORD \ --ssl-verify-server-cert \ --ssl-ca=/ca.pem \ -e "SELECT NOW();"' 

输出:

 ERROR 2026 (HY000): SSL connection error: error:14007086:SSL routines:CONNECT_CR_CERT:certificate verify failed 

这里发生了什么? 我如何debugging? 如何使证书validation成功?

不可否认,我对Alpine的MySQL调用与Ubuntu的调用略有不同。 Alpine的MySQL客户端较旧,使用--ssl-verify-server-cert而不是--ssl-mode=VERIFY_IDENTITY 。 这不是问题的根源; 我已经成功地使用了--ssl-verify-server-cert连接到macOS上的RDS。


我听说MySQL客户端可以用两种不同的SSL实现来构build:

  • yaSSL – 不支持证书链或--ssl-capath
  • OpenSSL的

当然,如果apk提供的MySQL客户端不支持证书链,那就可以解释它。 或者,如果Alpine带有较less的根证书或中间证书。


我尝试了以下。 它没有帮助。

 apk add ca-certificates && update-ca-certificates 

这不是一个networking问题。 如果closures证书validation(即删除--ssl-ca--ssl-verify-server-cert ),并使用encryption( --ssl ):Alpine成功连接到RDS。

所以这纯粹是一个authenticationvalidation问题。


关于debugging,很高兴知道:

  • mysql-client(而不是它的SSL实现) 尝试什么?
    • 它信任哪些根证书?
    • 它咨询了哪些中间证书?

如果证书链不受支持,也许有办法抓住整个链,并将其连接成一个证书 ?

我声称rds-ca-2015-root.pem是一个可信任的用于证书中间证书rds-ca-2015-eu-west-2.pem

我想,也许我可以结合证书:

 cat rds-ca-2015-eu-west-2.pem rds-ca-2015-root.pem > chained-cert.pem 

我试图使用chained-cert.pem作为我的中间证书。 这没有奏效。 也许我误解了一些东西。


我认为也许这将是有用的抢证书,以便我可以尝试直接validation它,而不是通过MySQL客户端。

 openssl s_client -connect MYDATABASE.eu-west-2.rds.amazonaws.com:3306 -showcerts 

可悲的是,这导致:

 7428:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.50.6/src/ssl/s23_clnt.c:618: 

因为MySQL:3306在启动SSL会话之前首先使用明文协议。


我试图获取证书的另一种方法是利用mysql-connector-java的会话处理; 它理解协议,并在适当的时候交给SSL。

我在sun.security.x509.X509CertImpl#verify(PublicKey var1, String var2)放置了一个断点,尝试查看二进制证书。

有各种各样的字节数组看起来很像DER编码的证书,所以我试图通过base64编码将它们转换成PEM,用-----BEGIN|END CERTIFICATE-----围绕它们,并限制列使用fold -w 64 cert.pem

这没有奏效。 我所生产的每件东西都没有错, 当我试图用opensslparsing或validation它们时,它们都遇到了Expecting: TRUSTED CERTIFICATE

诚然,这是一个远射。