如何设置MariaDB SSL和来自客户端的安全连接
如何为在Linux或类Unix系统上运行的MariaDB服务器和客户端启用SSL?
在本教程中,我将提供有关如何使用TLS/SSL设置MariaDB服务器以及如何通过控制台和PHP/Python脚本建立安全连接的说明。
MariaDB是一种数据库服务器,为MySQL服务器提供直接替换功能。
MariaDB由MySQL的一些原始作者构建,并得到了自由和开源软件开发人员的广泛支持。
除了MySQL的核心功能外,MariaDB还提供了一系列丰富的功能增强功能,包括其他存储引擎,服务器优化和补丁程序。
如何设置MariaDB SSL/TLS
我在RHEL/CentOS 7/8,Debian 9/10,Ubuntu 16.04/18.04/18.04 LTS,Arch Linux和FreeBSD上测试了这些说明。
但是,它也可以在其他Linux发行版上使用。
步骤1安装MariaDB
根据您的Linux或Unix变体执行命令。
在Ubuntu/Debian Linux上安装MariaDB服务器/客户端
执行以下apt-get命令或apt命令:
$ sudo apt-get install mariadb-server mariadb-client
在CentOS/RHEL/Fedora Linux上安装MariaDB服务器/客户端
执行以下yum命令:
$ sudo yum install mariadb-server mariadb
Fedora Linux用户执行以下dnf命令:
$ sudo dnf install mariadb-server mariadb
在Arch Linux上安装MariaDB服务器/客户端
输入以下pacman命令:
$ sudo pacman -S mariadb
在FreeBSD Unix上安装MariaDB服务器/客户端
要安装端口,请运行:
# cd /usr/ports/databases/mariadb100-server/ && make install clean # cd /usr/ports/databases/mariadb100-client/ && make install clean
要添加二进制软件包,请执行:
# pkg install mariadb100-server mariadb100-client
步骤2保护MariaDB
执行以下命令:
$ mysql_secure_installation
步骤3建立CA凭证(TLS/SSL)
使用mkdir命令在/etc/mysql /目录中创建一个名为ssl的目录:
$ cd /etc/mysql $ sudo mkdir ssl $ cd ssl
注意:用于服务器和客户端证书/密钥的通用名称值必须分别与用于CA证书的通用名称值不同。
为避免出现任何问题,我将它们设置如下。
否则,您将得到认证验证失败的错误。
因此,将其设置如下:CA通用名称:MariaDB admin
服务器通用名称:MariaDB服务器
客户端通用名称:MariaDB客户端
执行以下命令以创建新的CA密钥:
$ sudo openssl genrsa 2048 > ca-key.pem
或者
$ sudo openssl genrsa 4096 > ca-key.pem
执行以下命令以使用该密钥生成证书:
$ sudo openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
现在,您必须具有两个文件,如下所示:
/etc/mysql/ssl/ca-cert.pem
证书颁发机构(CA)的证书文件。/etc/mysql/ssl/ca-key.pem
证书颁发机构(CA)的密钥文件。
我将使用这两个文件来生成服务器和客户端证书。
步骤4创建服务器SSL证书
要创建服务器密钥,请运行:
$ sudo openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem
下一步处理服务器RSA密钥,执行:
$ sudo openssl rsa -in server-key.pem -out server-key.pem
输出示例:
writing RSA key
最后签署服务器证书,运行:
$ sudo openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
输出示例:
Signature ok subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=MariaDB server Getting CA Private Key
现在,您必须具有其他文件:
/etc/mysql/ssl/server-cert.pem
MariaDB服务器证书文件。/etc/mysql/ssl/server-key.pem
MariaDB服务器密钥文件。
您必须在MariaDB服务器本身以及将用于集群/复制流量的任何其他节点上使用以上两个文件。
这两个文件将确保服务器端通信的安全。
步骤5创建客户端TLS/SSL证书
mysql客户端,PHP/Python/Perl/Ruby应用程序将使用客户端证书来保护客户端连接。
您必须在所有客户端(包括Web服务器)上安装以下文件。
为MariaDB服务器创建客户端密钥
$ sudo openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
接下来,处理客户端RSA密钥,执行:
$ sudo openssl rsa -in client-key.pem -out client-key.pem `writing RSA key`
最后,签署客户端证书,运行:
$ sudo openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
输出示例:
Signature ok subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=MariaDB client Getting CA Private Key
步骤6如何验证证书?
执行以下命令来验证证书,以确保所有内容均正确创建:
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
输出示例:
server-cert.pem: OK client-cert.pem: OK
不应有任何错误,并且服务器和客户端证书都必须得到正确的答案。
步骤7将MariaDB服务器配置为使用SSL
编辑vi /etc/mysql/mariadb.conf.d/50-server.cnf或/etc/mysql/mariadb.cnf,如下所示:
$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
在[mysqld]中追加/编辑,如下所示:
### MySQL Server ### ## Securing the Database with ssl option and certificates ## ## There is no control over the protocol level used. ## ## mariadb will use TLSv1.0 or better. ## #ssl ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/server-cert.pem ssl-key=/etc/mysql/ssl/server-key.pem ## Set up TLS version here. For example TLS version 1.2 and 1.3 ## tls_version = TLSv1.2,TLSv1.3
保存并关闭文件。
使用chmod命令/chown命令保护密钥:
## Assuming that mariadb (mysqld) server started by the mysql user ## $ sudo chown -Rv mysql:root /etc/mysql/ssl/
changed ownership of '/etc/mysql/ssl/server-key.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/client-req.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/server-req.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/ca-key.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/server-cert.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/client-cert.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/ca-cert.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/client-key.pem' from root:root to mysql:root changed ownership of '/etc/mysql/ssl/' from root:root to mysql:root
您可以按以下方式重新启动mariadb:
$ sudo /etc/init.d/mysql restart
对于基于systemd的Linux发行版,请使用systemctl命令:
$ sudo systemctl restart mysql
确保没有报告ssl错误。
这是使用grep命令验证的简单方法
$ sudo grep ssl /var/log/syslog $ sudo grep ssl /var/log/syslog | grep key $ sudo grep mysqld /var/log/syslog | grep -i ssl
步骤8将MariaDB客户端配置为使用SSL
将MariaDB客户端(例如192.168.1.200)配置为使用SSL(在/etc/mysql/mariadb.conf.d/50-mysql-clients.cnf中添加):
$ sudo vi /etc/mysql/mariadb.conf.d/50-mysql-clients.cnf
在[mysql]部分中添加/编辑:
## MySQL Client Configuration ## ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/client-cert.pem ssl-key=/etc/mysql/ssl/client-key.pem ## Force TLS version for client too #tls_version = TLSv1.2,TLSv1.3 ### This option is disabled by default ### ### ssl-verify-server-cert ###
保存并关闭文件。
您必须将/etc/mysql/ssl/ca-cert.pem、/etc/mysql/ssl/client-cert.pem和/etc/mysql/ssl/client-key.pem复制到所有客户端。
例如:
{Hyman@server}: rsync /etc/mysql/ssl/ca-cert.pem /etc/mysql/ssl/client-cert.pem /etc/mysql/ssl/client-key.pem \ user@client:/etc/mysql/ssl
步骤9验证
输入mysql命令命令:
$ mysql -u {User-Name-Here} -h {Server-IP-here} -p {DB-Name-Here} $ mysql -u root -h 192.168.1.100 -p mysql $ mysql -u root -h 127.0.0.1 -p mysql
在" MariaDB [(none)]>"提示符下执行以下" SHOW VARIABLES LIKE'%ssl%';"命令:
MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';
或发出状态命令:
MariaDB [(none)]> status;
验证SSL与TLS连接。
由于ssl 3已配置并使用以下命令,因此以下命令应失败:
$ openssl s_client -connect 192.168.1.100:3306 -ssl3 `140510572795544:error:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed:ssl_lib.c:1878:`
检查TLS v 1/1.1/1.2:
$ openssl s_client -connect 192.168.1.100:3306 -tls1 $ openssl s_client -connect 192.168.1.100:3306 -tls1_1 $ openssl s_client -connect 192.168.1.100:3306 -tls1_2
输出示例:
CONNECTED(00000003) -- no peer certificate available -- No client certificate CA names sent -- SSL handshake has read 5 bytes and written 7 bytes -- New, (NONE), Cipher is (NONE) Secure Renegotiation IS 不支持 Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1485335036 Timeout : 7200 (sec) Verify return code: 0 (ok) --
如何读取tcpdump数据包捕获文件以验证安全通信
最后,您可以使用在命令行下运行的tcpdump命令数据包分析器来查看端口3306:
$ sudo tcpdump -i eth0 -s 65535 port 3306 -w /tmp/mysql.pcap
现在,从您的PHP/Python/Perl/Ruby mysql应用程序或控制台mysql应用程序连接:
$ mysql -u bar -h 192.168.1.100 -p foo
使用tcpdump验证服务器和客户端之间是否没有交换明文信息(包括密码),如下所示:
$ tcpdump -r /tmp/mysql.pcap | less
您可以使用tcpdump或其他工具(例如Wireshark)读取捕获的流量。
步骤10将用户添加到MariaDB服务器
执行以下命令:
$ mysql -u root -p
创建一个名为foo的数据库:
CREATE DATABASE foo;
为名为foo的数据库添加名为bar的用户:
GRANT ALL ON foo.* TO bar@localhost IDENTIFIED BY 'mypassword' REQUIRE SSL;
授予来自192.168.1.200托管的Web服务器的访问权限:
GRANT ALL ON foo.* TO [email protected] IDENTIFIED BY 'mypassword' REQUIRE SSL;
从bash shell建立安全连接
您可以从控制台登录,如下所示:
$ mysql -u bar -p -h 192.168.1.100 foo
通过Python建立安全连接
首先安装MySQL的Python接口:
$ sudo apt-get install python-mysql.connector
或适用于Python v3.x
$ sudo apt-get install python3-mysql.connector
这是使用SSL安全连接的示例Python代码:
#!/usr/bin/python import MySQLdb ssl = {'cert': '/etc/mysql/ssl/client-cert.pem', 'key': '/etc/mysql/ssl/client-key.pem'} conn = MySQLdb.connect(host='192.168.1.100', user='bar', passwd='mypassword', ssl=ssl) cursor = conn.cursor() cursor.execute("SHOW STATUS LIKE 'Ssl_cipher'") print cursor.fetchone()
或者
#!/usr/bin/python # Note (Example is valid for Python v2 and v3) from __future__ import print_function import sys import mysql.connector from mysql.connector.constants import ClientFlag config = { 'user': 'bar', 'password': 'mypassword', 'host': '192.168.1.100', 'client_flags': [ClientFlag.SSL], 'ssl_ca': '/etc/mysql/ssl/ca-cert.pem', 'ssl_cert': '/etc/mysql/ssl/client-cert.pem', 'ssl_key': '/etc/mysql/ssl/client-key.pem', } cnx = mysql.connector.connect(**config) cur = cnx.cursor(buffered=True) cur.execute("SHOW STATUS LIKE 'Ssl_cipher'") print(cur.fetchone()) cur.close() cnx.close()
输出示例:
('Ssl_cipher', 'DHE-RSA-AES256-SHA')