Mariadb 启用 TLS 安全连接

目录

一、概述

默认情况下,MariaDB 在服务器和客户端之间传输数据时不加密。当服务器和客户端运行在同一主机上保证处于安全的网络中时,这通常是可以接受的。然而,如果服务器和客户端位于不同的网络上或者位于高风险网络中,缺乏加密确实会带来安全问题,因为恶意行为者可能会窃听通过服务器和客户端之间的网络发送的流量。

为了减轻这种担忧,MariaDB 允许您使用传输层安全 (TLS) 协议对服务器和客户端之间传输的数据进行加密。 TLS 以前称为安全套接字层 (SSL),但严格来说,SSL 协议是 TLS 的前身,该版本的协议现在被认为是不安全的。MariaDB 文档仍然使用 SSL 术语表述,是出于兼容性原因,但实际上,MariaDB 仅支持 TLS。

二、创建自签署证书

OpenSSL 自签署证书生成

生成服务器证书和客户端证书

shell
# 初始化
git clone https://code.wangyan.cloud//wangyan/gen-ssl-cert.git /tmp/gen-ssl-cert
cd /tmp/gen-ssl-cert
make init

# 根证书
make gen-ca-key
make gen-ca-csr
make gen-ca-cert

# 中间证书
make gen-ica-key
make gen-ica-csr
make gen-ica-cert
make gen-ica-chain

# 服务器证书
make gen-server-key
make gen-server-csr
make gen-server-cert

# 客户端证书
make gen-client-key
make gen-client-csr
make gen-client-cert
make gen-client-pkcs12

准备证书文件

shell
#准备目录
sudo mkdir /etc/my.cnf.d/certificates && \
sudo chmod 777 /etc/my.cnf.d/certificates && \
sudo chmod o+t /etc/my.cnf.d/certificates

# 服务端证书
cp /tmp/gen-ssl-cert/ica/certs/ica-chain-cert.crt /etc/my.cnf.d/certificates/ca.pem && \
cp /tmp/gen-ssl-cert/ica/certs/server-cert.crt /etc/my.cnf.d/certificates/server-cert.pem && \
cp /tmp/gen-ssl-cert/ica/private/server-key.pem /etc/my.cnf.d/certificates/server-key.pem

# 客户端证书
cp /tmp/gen-ssl-cert/ica/certs/client-cert.crt /etc/my.cnf.d/certificates/client-cert.pem && \
cp /tmp/gen-ssl-cert/ica/private/client-key.pem /etc/my.cnf.d/certificates/client-key.pem

# 修改权限
sudo chown mysql:mysql -R /etc/my.cnf.d/certificates/

二、MariaDB 服务端启用 TLS

ssl_cert 设置服务器的 X509 证书的路径。

ssl_key 设置服务器私钥的路径。

ssl_ca 设置证书颁发机构 (CA) 链的路径,用来验证服务器证书。

shell
sudo sh -c "cat >/etc/my.cnf.d/enable_tls.cnf" <<EOF
[mariadb]
# Use Secure Connections to transfer data
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl_cert = /etc/my.cnf.d/certificates/server-cert.pem
ssl_key = /etc/my.cnf.d/certificates/server-key.pem
EOF

重启 & 检查

shell
# 重启
sudo systemctl restart mariadb

# 动态刷新证书,可不用重启
FLUSH SSL

# 检查 TLS 是否已启用
SHOW GLOBAL VARIABLES LIKE 'have_ssl';
SHOW SESSION STATUS LIKE 'Ssl_cipher';

三、MariaDB 客户端启用 TLS

3.1. 什么是证书验证?

服务端证书验证

客户端根据证书中的某些属性检查服务器的主机名和 IP 地址来验证服务器证书。对于大多数客户端,默认情况下禁用服务器证书验证,并且仅在指定选项(例如ssl-verify-server-cert指定)时才启用它。
为了验证服务器的证书,客户端和实用程序将根据服务器的主机名和 IP 地址检查位于证书主题字段中的通用名称 (CN)属性。如果公用名 (CN)与其中任何一个匹配,则证书通过验证。
使用主题备用名称 (SAN) 也叫 subjectAltName 进行服务器证书验证。当使用支持使用 subjectAltName 字段进行服务器证书验证的客户端时,如果服务器证书包含任何 subjectAltName 字段,则还将根据服务器的主机名和 IP 地址检查这些字段。

客户端证书验证

服务器通过SUBJECT根据客户端证书中的主题属性检查客户端的已知信息来验证客户端证书。

3.2. 双向 TLS

双向 TLS 意味着客户端和服务器都提供私钥和 X509 证书,客户端和服务器都要验证彼此身份。

即客户端要对服务端证书进行验证。同时,服务端也要对客户端的证书进行验证。

(1)通过配置文件:

shell
sudo sh -c "cat >>/etc/my.cnf.d/enable_tls.cnf" <<EOF

[client-mariadb]
ssl_cert = /etc/my.cnf.d/certificates/client-cert.pem
ssl_key = /etc/my.cnf.d/certificates/client-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl-verify-server-cert
EOF

(2)通过命令行:

shell
mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-verify-server-cert

3.3. 单向 TLS

当在没有客户端证书的情况下使用 TLS 时,称为单向 TLS,因为只有服务器提供私钥和 X509 证书,因此只能在一个方向进行身份验证。然而,双向加密仍然是可能的。服务器证书验证是指客户端验证证书是否属于服务器。

(1)通过配置文件:

shell
[client-mariadb]
...
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl-verify-server-cert

(2)通过命令行:

shell
mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-verify-server-cert

3.4. 双向 vs 单向

不管是双向还是单向,都要对服务器证书进行验证。区别在于单向没有指定客户端证书,因此,服务器不能验证客户端,但客户端都能验证服务端。

当然了,还有一种情况是,启用了单向 TLS,但是也不验证服务器证书

方法如下:

(1)通过配置文件:

shell
[client-mariadb]
...
ssl

(2)通过命令行:

shell
mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl

四、强制使用 TLS

4.1. 特定用户帐户使用 TLS

您可以为特定用户帐户设置 TLS 相关的限制,例如,需要访问敏感数据的用户帐户。可以使用 CREATE USER、ALTER USER 或 GRANT 语句为用户帐户启用这些限制。

(1) 必须通过 TLS 连接

sql
ALTER USER 'alice'@'%' 
   REQUIRE SSL;

(2) 必须通过 TLS 且是有效的客户端证书

sql
ALTER USER 'alice'@'%' 
   REQUIRE X509;

(3) 必须通过 TLS 且是特定的客户端证书

sql
ALTER USER 'alice'@'%' 
   REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland';

4.2 特定主机的特定帐户使用 TLS

sql
CREATE USER 'alice'@'localhost' 
   REQUIRE NONE;

CREATE USER 'alice'@'%'
   REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
   AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com'
   AND CIPHER 'ECDHE-ECDSA-AES256-SHA384';
shell
# 初始化
git clone https://code.wangyan.cloud//wangyan/gen-ssl-cert.git /tmp/gen-ssl-cert

参考文档

Secure Connections Overview

Securing Connections for Client and Server

Connecting to MariaDB

ESC