通过SSL的MariaDB无法正常工作,"证书验证失败"

时间:2017-02-09 20:08:21

标签: ssl mariadb rhel7

使用this guide我尝试设置MariaDB(mysql),以便在 dbserver appclient 之间使用SSL。

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

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

[root@appclient 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上打开:

[root@appclient mysql]# telnet dbserver 3306
Connected to dbserver.
Escape character is '^]'.
R
5.5.52-MariaDB

接下来,我在 dbserver 上检查了MariaDB(mysql)ssl变量:

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

[root@appclient 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

没有bueno。

使用openssl检查 appclient 的证书...

[root@appclient mysql]# cd /etc/pki/tls/certs/mysql/
[root@appclient 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

对于踢,我在 dbserver 上运行了相同的openssl测试:

[root@dbserver 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文件中?

2 个答案:

答案 0 :(得分:6)

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

这是一个对我有用的分步指南:

这个答案假设有两台服务器:

  1. dbserver(我们的数据库所在的位置)
  2. appclient(我们的应用程序所在的位置)
  3. 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
    

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

    确保你仍然是/ root / certs / mysql /用于下一个命令

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

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

    确保您看到两个证书:

    cat ca.pem 
    

    现在服务器端工作结束。

    打开另一个终端

    ssh appclient
    

    和以前一样,为客户端证书创建永久主页

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

    现在,将客户端证书(在dbserver上创建)放在appclient上。 您可以将它们翻过来,或者只是逐个复制和粘贴文件。

    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错误:无法从中获取证书   '/etc/pki/tls/certs/mysql/client-cert.pem'

    问题在于root拥有的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 
    

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

    这将显示您的连接状态,它应如下所示:

    Connection id:      4
    Current database:   
    Current user:       iamsecure@appclient
    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
    

    如果您在连接尝试中获得权限被拒绝错误,请检查上面的GRANT语句以确保没有任何流浪字符或'标记。

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

    这适用于RHEL7,也可能适用于CentOS7。无法确认这些确切步骤是否适用于其他地方。

    希望这可以节省别人一点时间和恶化。

答案 1 :(得分:3)

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

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