一、SSL和TLS的区别
SSL(Secure Socket Layer)是1994年由网景(Netscape)公司设计的一种安全的网络传输协议,并用于该公司的Web浏览器中,后多家Web浏览器相继采用该协议,成为了事实上的行业标准。SSL在1995年发布了3.0版本,但在2014年,SSL3.0被发现存在可能导致POODLE的安全漏洞,已不再安全。
TLS(Transport Layer Security)是IETF在SSL3.0基础上设计的协议,在1999年作为RFC2246发布的TLS1.0实际上相当于SSL3.1。后续的TLS版本陆续增加了更多防范攻击的策略,更加的安全。
二、相关文件
MySQL启动之后,会自动在数据目录创建SSL/TLS使用的PEM文件,有些可能不存在,具体情况具体分析。
- ca-key.pem:CA私钥
- ca.pem:自签的CA证书,客户端连接也需要提供
- client-cert.pem:客户端连接服务器需要提供的证书文件
- client-key.pem:客户端连接服务器需要提供的私钥文件
- private_key.pem:私钥/公钥对的私有成员
- public_key.pem:私钥/公钥对的共有成员
- server-cert.pem:服务器端证书文件
- server-key.pem:服务器端私钥文件
三、配置
服务端:
表示mysql服务端已经开启ssl支持
服务端可以开启<span class="ne-text">require_secure_transport</span>
来要求所有连接都进行ssl连接。
配置文件:
[mysqld]
ssl_ca=/path/to/ca.pem
ssl_cert=/path/to/server-cert.pem
ssl_key=/path/to/server-key.pem
四、客户端
MySQL 客户端连接 Server 时,通过 --ssl-mode 参数指定
- --ssl-mode=PREFFERED,默认行为,client 端尝试使用加密进行连接,如果无法构建加密连接,则会退回到未加密的连接
- –ssl-mode=REQUIRED时,Client 端需要加密连接,如果无法构建连接,则 Client 端将失败
- –ssl-mode=DISABLED,Client 端使用未加密的连接
- –ssl-mode=VERIFY_CA,Client 端需要加密连接,并且还对 CA 证书进行验证
- –ssl-mode=VERIFY_IDENTITY,Client 端需要加密的连接,并且还针对 CA 证书和其证书中的服务器主机名执行验证
# EXAMPLE:
# 在服务端支持ssl,但不强制要求ssl时,默认的PREFFERED和DISABLE都可以使用,没有加密
# 1. 使用了加密,但直接信任服务端发送过来的公钥
mysql -h111.222.123.23 -P1234 -uUser -p --ssl-mode=REQUIRED
# 2. 使用CA来验证服务器发送过来的公钥,需要将服务器端的ca.pem文件下载到本地机器
mysql -h111.222.123.23 -P1234 -uUser -p --ssl-mode=VERIFY_CA --ssl-ca=/path/to/ca.pem
# 3. 还需要对证书中服务器主机名进行验证,三个文件都来自服务器端
# 但是这种方式 主机名身份验证 不适用于由服务器自动创建或使用 mysql_ssl_rsa_setup 手动创建的自签名CA证书(所以自创的以下会连接失败)
mysql -h111.222.123.23 -P1234 -uUser -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=/path/to/ca.pem --ssl-cert=/path/to/client-cert.pem --ssl-key=/path/to/client-key.pem
五、SSL握手过程
- 客户端发起 ssl 连接请求;
- MySQL Server 发送数字证书 server-cert.pem 给客户端(server-cert.pem包含:服务器公钥、CA签名信息);
- 客户端使用CA 证书 ca.pem中的 CA 公钥解密 server-cert.pem 中的签名,进行验证;(由于是 MySQL 自签名的CA证书,无法从操作系统的可信任区获取(压根不在这里边),所以事先必须在客户端本地保存 CA 证书文件)
- 验证通过后,生成对称密钥,使用 server-cert.pem 中的公钥加密“对称密钥”,发送给 MySQL Server;
- MySQL Server 使用自己保留的私钥 server-key.pem 解密,得到“对称密钥”;
- 接下来传输数据则使用“对称密钥”进加密和解密(对称加密解密快)
如果仅指定 --ssl-mode=REQUIRED,不指定 --ssl-mode=VERIFY_CA 或者 --ssl-mode=VERIFY_IDENTITY,则不需要步骤3,直接获取并信任公钥。