MariaDB的通过SSL不工作, “证书验证失败”

问题描述:

使用this guide我试图建立MariaDB的(MySQL的)使用DBSERVER和appclient之间SSL。MariaDB的通过SSL不工作, “证书验证失败”

我按照指南在服务器上创建了服务器和客户端证书。然后我复制了三个必要的客户端文件,以appclient并设置所有权和权限:

[[email protected] mysql]# ll /etc/pki/tls/certs/ 
drwxr-xr-x. 2 mysql mysql 88 Feb 9 13:31 mysql 

[[email protected] mysql]# ll /etc/pki/tls/certs/mysql/ 
-rw-------. 1 mysql mysql 1372 Feb 9 13:31 ca-cert.pem 
-rw-------. 1 mysql mysql 1230 Feb 9 14:16 client-cert.pem 
-rw-------. 1 mysql mysql 1705 Feb 9 14:16 client-key.pem 

这里有appclient完整的my.cnf:

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
symbolic-links=0 

[client] 
ssl-ca=/etc/pki/tls/certs/mysql/ca-cert.pem 
ssl-cert=/etc/pki/tls/certs/mysql/client-cert.pem 
ssl-key=/etc/pki/tls/certs/mysql/client-key.pem 

[mysqld_safe] 
log-error=/var/log/mariadb/mariadb.log 
pid-file=/var/run/mariadb/mariadb.pid 

!includedir /etc/my.cnf.d 

接下来,我测试了一下3306端口是开放的在DBSERVER:

[[email protected] mysql]# telnet dbserver 3306 
Connected to dbserver. 
Escape character is '^]'. 
R 
5.5.52-MariaDB 

接下来我查了MariaDB的(MySQL的)SSL变量DBSERVER

MariaDB [(none)]> show variables like '%ssl%'; 
+---------------+------------------------------------------+ 
| Variable_name | Value         | 
+---------------+------------------------------------------+ 
| have_openssl | YES          | 
| have_ssl  | YES          | 
| ssl_ca  | /etc/pki/tls/certs/mysql/ca-cert.pem  | 
| ssl_capath |           | 
| ssl_cert  | /etc/pki/tls/certs/mysql/server-cert.pem | 
| ssl_cipher |           | 
| ssl_key  | /etc/pki/tls/certs/mysql/server-key.pem | 
+---------------+------------------------------------------+ 

接下来我查了appclient MariaDB的(MySQL的)SSL变量:

MariaDB [(none)]> show variables LIKE '%ssl%'; 
+---------------+----------+ 
| Variable_name | Value | 
+---------------+----------+ 
| have_openssl | DISABLED | 
| have_ssl  | DISABLED | 
| ssl_ca  |   | 
| ssl_capath |   | 
| ssl_cert  |   | 
| ssl_cipher |   | 
| ssl_key  |   | 
+---------------+----------+ 
7 rows in set (0.00 sec) 

看起来像问题的开始/源。

如果我尝试从appclient反正连接到DBSERVER

[[email protected] mysql]# mysql -h dbserver -u ssluser -p 
Enter password: 
ERROR 2026 (HY000): SSL connection error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 

没有布埃诺。

检查appclient的证书与OpenSSL的...

[[email protected] mysql]# cd /etc/pki/tls/certs/mysql/ 
[[email protected] mysql]# openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem 
Error opening certificate file server-cert.pem 
139864320337824:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('server-cert.pem','r') 
139864320337824:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400: 
unable to load certificate 
client-cert.pem: OK 

踢,我跑了相同的OpenSSL测试上DBSERVER

[[email protected] mysql]# openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem 
server-cert.pem: C = XX, ST = XX, L = CityName, O = MyOrganization, OU = MyGroup, CN = dbserver 
error 18 at 0 depth lookup:self signed certificate 
OK 
client-cert.pem: OK 

教程只提到复制ca-cert.pemclient-cert.pemclient-key.pem给客户端,但上面的失败指向客户端上丢失的server-cert.pem

我是否需要在客户端上创建服务器 - *。pem文件?如果是这样,那么这些文件会在/etc/my.cnf文件中出现在哪里?

+0

这是一个自签名证书吗?由于openssl告诉你证书验证失败,这表明你用来签署证书的权限应该被添加到你正在运行的操作系统上。我不知道是否有一个标志禁止验证证书,但也许有一些Google在这方面可以帮助? –

+0

它是自签名的。所有证书都是在每个文档的dbserver上生成的。请注意,openssl由于缺少'server-cert.pem'而未能通过测试,本教程未对其进行描述或解决。这是我坚持的部分。 –

+0

'cat server-cert.pem client-cert.pem> ca.pem'取得了一些进展,然后更新appclient的my.cnf以使用'ssl-ca = ca.pem'。而不是SSL错误,我得到一个身份验证错误。 –

几个MySQL/MariaDB SSL安装指南中缺少的成分是确保ssl-ca证书文件包含服务器和客户端ca。

这里有一个一步一步地指导其工作对我来说:


这个回答假设两个服务器:

  1. DBSERVER(其中我们的数据库的生命)
  2. appclient(其中我们的应用生活)

FWIW,这两个服务器都是SELinux强制执行的。

首先,登录到dbserver

创建一个用于创建证书的临时目录。

mkdir /root/certs/mysql/ && cd /root/certs/mysql/ 

创建服务器证书

openssl genrsa 2048 > ca-key.pem 
openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem 
openssl req -sha1 -newkey rsa:2048 -days 730 -nodes -keyout server-key.pem > server-req.pem 
openssl rsa -in server-key.pem -out server-key.pem 
openssl x509 -sha1 -req -in server-req.pem -days 730 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem 

移动服务器证书/etc/pki/tls/certs/mysql/目录路径假定的CentOS或RHEL(根据需要在其他版本中调整):

mkdir /etc/pki/tls/certs/mysql/ 
cp /root/certs/mysql/* /etc/pki/tls/certs/mysql/ 

一定要设置权限在文件夹和文件上。 MySQL需要完全的所有权和访问权限

chown -R mysql:mysql /etc/pki/tls/certs/mysql 

现在配置MySQL/MariaDB的

# vi /etc/my.cnf 
# i 
[mysqld] 
bind-address=* 
ssl-ca=/etc/pki/tls/certs/ca-cert.pem 
ssl-cert=/etc/pki/tls/certs/server-cert.pem 
ssl-key=/etc/pki/tls/certs/server-key.pem 
# :wq 

然后

systemctl restart mariadb 

不要忘了打开防火墙以允许从appclient连接(使用IP 1.2.3.4)

firewall-cmd --zone=drop --permanent --add-rich-rule 'rule family="ipv4" source address="1.2.3.4" service name="mysql" accept' 
# I force everything to the drop zone. Season the above command to taste. 

现在重新启动firewalld

service firewalld restart 

接下来,登录DBSERVER的MySQL服务器:

mysql -uroot -p 

发出以下以创建客户端的用户。注意GRANT语句中的REQUIRE SSL。

GRANT ALL PRIVILEGES ON *.* TO ‘iamsecure’@’appclient’ IDENTIFIED BY ‘dingdingding’ REQUIRE SSL; 
FLUSH PRIVILEGES; 
# quit mysql 

您应该仍然在第一步中的/ root/certs/mysql中。如果没有,请回到下面的命令之一。

创建客户端证书

openssl req -sha1 -newkey rsa:2048 -days 730 -nodes -keyout client-key.pem > client-req.pem 
openssl rsa -in client-key.pem -out client-key.pem 
openssl x509 -sha1 -req -in client-req.pem -days 730 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem 

注意:我用同样的通用名称为服务器和客户端证书。因人而异。

确保你仍然/根/证书/ mysql /下为下一个命令

合并服务器和客户端CA证书到一个文件:

cat server-cert.pem client-cert.pem > ca.pem 

确保你看到两个证书:

cat ca.pem 

服务器端工作结束。

打开另一个终端和

ssh appclient 

和以前一样,建立一个永久的家的客户端证书

mkdir /etc/pki/tls/certs/mysql/ 

现在,放在appclient(上DBSERVER创建)的客户端证书。 您可以scp他们,或者只是复制和粘贴文件一个接一个。

scp dbserver 
# copy files from dbserver to appclient 
# exit scp 

再次,请务必设置文件夹和文件的权限。 MySQL需要完全的所有权和访问权限

chown -R mysql:mysql /etc/pki/tls/certs/mysql 

你应该有三个文件,每个用户所拥有的MySQL:

/etc/pki/tls/certs/mysql/ca.pem 
/etc/pki/tls/certs/mysql/client-cert.pem 
/etc/pki/tls/certs/mysql/client-key.pem 

现在编辑在[client]部分appclient的MariaDB的/ MySQL的配置。

vi /etc/my.cnf 
# i 
[client] 
ssl-ca=/etc/pki/tls/certs/mysql/ca.pem 
ssl-cert=/etc/pki/tls/certs/mysql/client-cert.pem 
ssl-key=/etc/pki/tls/certs/mysql/client-key.pem 
# :wq 

重启appclient的MariaDB的服务:

systemctl restart mariadb 

还在这里

客户端这应该回报:SSL TRUE

mysql --ssl --help 

现在,登录appclient的MySQL实例

mysql -uroot -p 

应该是看到这两个变量低于

show variables LIKE '%ssl'; 
    have_openssl YES 
    have_ssl    YES 

起初我看到

have_openssl NO 

快速查看mariadb.log透露:

SSL error: Unable to get certificate from '/etc/pki/tls/certs/mysql/client-cert.pem'

的问题是,国有根client-cert.pem和包含的文件夹。 解决方案是将/ etc/pki/tls/certs/mysql /的所有权设置为mysql。如果需要从台阶正上方

chown -R mysql:mysql /etc/pki/tls/certs/mysql 

重启MariaDB的,现在我们就可以开始测试安全连接

我们还在appclient这里

尝试连接到DBSERVER提供商的MySQL使用上面创建的帐户的实例。

mysql -h dbserver -u iamsecure -p 
# enter password dingdingding (hopefully you changed that to something else) 

有一点点运气,你应该没有错误地登录。

要确认您已连接启用SSL,问题从MariaDB的/ MySQL的提示符下输入以下命令:

\s 

这是一个反斜杠S,又名状态

,将显示的状态你的连接应该看起来像这样:

Connection id:  4 
Current database: 
Current user:  [email protected] 
SSL:   Cipher in use is DHE-RSA-AES256-GCM-SHA384 
Current pager:  stdout 
Using outfile:  '' 
Using delimiter: ; 
Server:   MariaDB 
Server version:  5.X.X-MariaDB MariaDB Server 
Protocol version: 10 
Connection:  dbserver via TCP/IP 
Server characterset: latin1 
Db  characterset: latin1 
Client characterset: utf8 
Conn. characterset: utf8 
TCP port:  3306 
Uptime:   42 min 13 sec 

如果你获得了权限被拒绝的错误r连接尝试,请检查上面的GRANT语句以确保没有任何杂散字符或'标记。

如果您有SSL错误,请回头阅读本指南以确保步骤有序。

这适用于RHEL7,并可能在CentOS7上运行。无法确认这些确切步骤是否可以在其他地方使用。

希望这节省了别人一点时间和加重。

根据mentioned guide,您必须确保所有三个证书的“通用名称”不同。

我得到了同样的错误,因为我已经为所有三个证书使用了相同的CN。重新生成具有不同CN的证书后,错误消失。

+0

CentDB 7上的MariaDB:可以确认这一点。使用FQ主机名称作为CN后,它失败了,但是当使用Vivek清晰标记的建议时,它工作得很好,一旦会话开始,它就会使用SSL密码(状态查询)正确报告。 –