翼度科技»论坛 编程开发 mysql 查看内容

MySQL运维实战(2.4) SSL认证在MySQL中的应用

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
作者:俊达
引言

MySQL支持使用TLS协议进行通信,该协议在数据库通信中具有关键作用。首先,TLS能够加密客户端与服务端之间的通信数据,涵盖了客户端发送至服务端的SQL请求以及服务端返回给客户端的数据,从而确保敏感信息的保密性和完整性。除此之外,TLS还允许客户端验证服务端的身份,确保安全连接。同时,TLS还使得服务端能够验证客户端的身份,实现双向认证,从而进一步增强了通信安全性和互信性。这些TLS功能在MySQL通信中发挥着重要作用,为数据传输提供了必要的保护和验证机制。
1 Server端开启SSL

服务端默认已经开启SSL,可以通过如下命令查看是否支持SSL:
参数have_ssl为 YES
  1. | have_openssl  | YES             |
  2. | have_ssl      | YES             |
  3. | ssl_ca        | ca.pem          |
  4. | ssl_capath    |                 |
  5. | ssl_cert      | server-cert.pem |
  6. | ssl_cipher    |                 |
  7. | ssl_crl       |                 |
  8. | ssl_crlpath   |                 |
  9. | ssl_key       | server-key.pem  |
复制代码
参数说明:
参数说明have_openssl和have_ssl一样have_sslYES: 启用SSLDISABLED: 已经编译了SSL功能,但是没有开启ssl_caCA文件,默认是ca.pemssl_capathCA文件路径,默认为空。mysqld会从datadir查找ca.pemssl_cert服务端证书,默认server-cert.pem.ssl_cipherSSL加密方式,默认为空ssl_crlcertificate revocation lists文件,默认为空ssl_crlpathcertificate revocation lists文件路径,默认为空ssl_key服务端证书私钥,默认server-key.pem.server端启用SSL,需要ca.pem, server-cert.pem, server-key.pem 3个文件。
客户端需要有ca.pem, client-cert.pem, client-key.pem 3个文件。
2 客户端SSL

使用mysql客户端连接到服务端时,默认会使用加密通信,
登陆后输入 \s, 或者show status like 'ssl_cipher',如果看Cipher信息,说明连接已经开启加密通信
  1. [root@box1 mysql]# mysql -uroot -h127.0.0.1 -P3306 -phello
  2. Server version: 5.7.32 MySQL Community Server (GPL)
  3. ...
  4. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  5. mysql> \s
  6. --------------
  7. mysql  Ver 14.14 Distrib 5.7.32, for Linux (x86_64) using  EditLine wrapper
  8. Connection id:                23
  9. Current database:
  10. Current user:                root@localhost
  11. SSL:                        Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
  12. Current pager:                stdout
  13. Using outfile:                ''
  14. Using delimiter:        ;
  15. Server version:                5.7.32 MySQL Community Server (GPL)
  16. Protocol version:        10
  17. Connection:                127.0.0.1 via TCP/IP
  18. Server characterset:        latin1
  19. mysql> show status like 'ssl_cipher';
  20. +---------------+-----------------------------+
  21. | Variable_name | Value                       |
  22. +---------------+-----------------------------+
  23. | Ssl_cipher    | ECDHE-RSA-AES128-GCM-SHA256 |
复制代码
2.1 客户端禁用ssl通信

mysql客户端登陆时加上 --ssl-mode=disabled禁用TLS通信
  1. mysql -uroot -h127.0.0.1 -P3306 -phello --ssl-mode=disabled
  2. mysql> \s
  3. --------------
  4. mysql  Ver 14.14 Distrib 5.7.32, for Linux (x86_64) using  EditLine wrapper
  5. Connection id:                25
  6. Current database:
  7. Current user:                root@localhost
  8. SSL:                        Not in use
  9. Current pager:                stdout
  10. mysql> show status like 'ssl_cipher';
  11. +---------------+-------+
  12. | Variable_name | Value |
  13. +---------------+-------+
  14. | Ssl_cipher    |       |
  15. +---------------+-------+
复制代码
2.2客户端要求验证服务端证书

客户端可以要求验证服务端的证书。
mysql客户端将ssl-mode参数设置为verify_ca或verify_identity, 同时需要提供用来签名的ca证书。
verify_ca的作用,是为了让服务端证明,他的证书是客户端参数中的指定的ca签名的。其他服务器无法冒充。
  1. mysql -uroot -h127.0.0.1 -P3306 -phello --ssl-mode=verify_ca --ssl-ca=ca.pem
  2. show status like 'ssl_cipher';
  3. +---------------+-----------------------------+
  4. | Variable_name | Value                       |
  5. +---------------+-----------------------------+
  6. | Ssl_cipher    | ECDHE-RSA-AES128-GCM-SHA256 |
复制代码
如果证书验证不通过,客户端连接会报错。服务端日志中也能看到相关报错信息。
  1. ### client
  2. root@box1 mysql]# mysql -uroot -h127.0.0.1 -P3306 -phello --ssl-mode=verify_ca --ssl-ca=/data/mysql01/data/ca.pem
  3. mysql: [Warning] Using a password on the command line interface can be insecure.
  4. ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)
  5. ### server
  6. [root@box1 mysql]# tail -1 /var/log/mysqld.log
  7. 2021-03-31T23:34:20.461350Z 28 [Note] Bad handshake
复制代码
3 服务端要求验证客户端使用SSL登录

虽然服务端开启了SSL,但是默认情况下用户可以选择启用或不启用加密通信。
服务端可以强制要求客户端使用加密通信,也可以要求客户端证明自己的身份。
这可以在创建用户的时候指定。
  1. CREATE USER 'user_1'@'%'  identified by 'hello' require ssl;
  2. CREATE USER 'user_2'@'%'  identified by 'hello' require x509;
  3. CREATE USER 'user_3'@'%'  identified by 'hello' require cipher 'ECDHE-RSA-AES256-GCM-SHA384';
  4. CREATE USER 'user_4'@'%'  identified by 'hello' require cipher 'ECDHE-ECDSA-AES256-GCM-SHA384';
  5. CREATE USER 'user_5'@'%'  identified by 'hello' require issuer 'www.dtstack.com' ;
  6. CREATE USER 'user_6'@'%'  identified by 'hello' require subject '/CN=client.dtstack.com';
复制代码
上面创建的用户中,
user_1必须开启SSL加密才能连接到服务器
user_2需要使用x509证书格式
user_3需要使用cipher ECDHE-RSA-AES256-GCM-SHA384
user_4需要使用cipher ECDHE-ECDSA-AES256-GCM-SHA384
user_5需要使用www.dtstack.com签发的证书
user_6需要使用subject为client.dtstack.com的证书
4测试用户信息
  1. select user,host, ssl_type, ssl_cipher, x509_issuer, x509_subject from mysql.user where user like 'user%';
  2. +--------+------+-----------+-------------------------------+-----------------+------------------------+
  3. | user   | host | ssl_type  | ssl_cipher                    | x509_issuer     | x509_subject           |
  4. +--------+------+-----------+-------------------------------+-----------------+------------------------+
  5. | user_1 | %    | ANY       |                               |                 |                        |
  6. | user_2 | %    | X509      |                               |                 |                        |
  7. | user_3 | %    | SPECIFIED | ECDHE-RSA-AES256-GCM-SHA384   |                 |                        |
  8. | user_4 | %    | SPECIFIED | ECDHE-ECDSA-AES256-GCM-SHA384 |                 |                        |
  9. | user_5 | %    | SPECIFIED |                               | www.dtstack.com | client.dtstack.com     |
  10. | user_6 | %    | SPECIFIED |                               |                 | /CN=client.dtstack.com |
  11. +--------+------+-----------+-------------------------------+-----------------+------------------------+
复制代码
4.1强制SSL

user_1登陆,如果不开启ssl-mode,登陆报错。使用SSL才能登陆
  1. [root@box1 pki]# mysql -uuser_1 -phello -h127.0.0.1 --ssl-mode=disabled
  2. mysql: [Warning] Using a password on the command line interface can be insecure.
  3. ERROR 1045 (28000): Access denied for user 'user_1'@'localhost' (using password: YES)
  4. [root@box1 pki]# mysql -uuser_1 -phello -h127.0.0.1
  5. ...
  6. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  7. mysql> \s
  8. ...
  9. Current user:                user_1@localhost
  10. SSL:                        Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
复制代码
4.2强制使用客户端证书

user_2需要x509证书才能登陆
  1. [root@box1 pki]# mysql -uuser_2 -phello -h127.0.0.1
  2. ERROR 1045 (28000): Access denied for user 'user_2'@'localhost' (using password: YES)
  3. [root@box1 pki]# mysql -uuser_2 -phello -h127.0.0.1 --ssl-mode=required
  4. ERROR 1045 (28000): Access denied for user 'user_2'@'localhost' (using password: YES)
  5. [root@box1 pki]# mysql -uuser_2 -phello -h127.0.0.1  --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  6. ...
  7. Welcome to the MySQL monitor.  Commands end with ; or \g.
  8. mysql> \s
  9. ...
  10. Current user:                user_2@localhost
  11. SSL:                        Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
复制代码
4.3 强制指定客户端cipher

user_3指定了cipher, 无法登陆。 可以从服务端alert.log查看登陆失败的原因。
  1. [root@box1 pki]# mysql -uuser_3 -pxhello -h127.0.0.1 --ssl-mode=required --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  2. ERROR 1045 (28000): Access denied for user 'user_3'@'localhost' (using password: YES)
  3. ### 服务端日志
  4. [root@box1 mysql]# tail -1 /var/log/mysqld.log2021-04-01T00:07:44.216859Z 51 [Note] X509 ciphers mismatch: should be 'ECDHE-RSA-AES256-GCM-SHA384' but is 'ECDHE-RSA-AES128-GCM-SHA256'
  5. 2021-04-01T00:07:44.216915Z 51 [Note] Access denied for user 'user_3'@'localhost' (using password: YES)
复制代码
说明了cipher不满足要求。
my.cnf增加ssl_ciphper参数,重启服务
  1. [root@box1 mysql]# tail -1 /etc/my.cnf
  2. ssl_cipher=ECDHE-RSA-AES256-GCM-SHA384
  3. [root@box1 mysql]# service mysqld restart
  4. Redirecting to /bin/systemctl restart mysqld.service
复制代码
  1. -- 再次尝试登陆,可以看到SSL 使用的ciper变成了 ECDHE-RSA-AES256-GCM-SHA384
  2. [root@box1 pki]# mysql -uuser_3 -phello -h127.0.0.1 --ssl-mode=required --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  3. ...
  4. mysql> \s
  5. Current user:                user_3@localhost
  6. SSL:                        Cipher in use is ECDHE-RSA-AES256-GCM-SHA384
复制代码
4.4验证客户端证书的subject 和 issuer
  1. ### client
  2. [root@box1 pki]# mysql -uuser_5 -phello -h127.0.0.1 --ssl-mode=required --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  3. ERROR 1045 (28000): Access denied for user 'user_5'@'localhost' (using password: YES)
  4. ### server
  5. [root@box1 mysql]# tail -2 /var/log/mysqld.log
  6. 2021-04-01T01:17:21.692560Z 6 [Note] X509 issuer mismatch: should be 'www.dtstack.com' but is '/C=CN/ST=HZ/L=ZJ/O=lazybug CO/OU=freecity/CN=www.dtstack.com/emailAddress=junda@dtstack.com'
  7. 2021-04-01T01:17:21.692607Z 6 [Note] Access denied for user 'user_5'@'localhost' (using password: YES)
  8. ### client
  9. [root@box1 pki]# mysql -uuser_6 -phello -h127.0.0.1 --ssl-mode=required --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  10. ERROR 1045 (28000): Access denied for user 'user_6'@'localhost' (using password: YES)
  11. ### server
  12. [root@box1 mysql]# tail -2 /var/log/mysqld.log
  13. 2021-04-01T01:20:41.297093Z 8 [Note] X509 subject mismatch: should be '/CN=client.dtstack.com' but is '/C=XX/L=Default City/O=Default Company Ltd'
  14. 2021-04-01T01:20:41.297144Z 8 [Note] Access denied for user 'user_6'@'localhost' (using password: YES)
复制代码
重新生成client证书,指定subject
  1. [root@box1 pki]# openssl req -subj /CN=client.dtstack.com -newkey rsa:2048 -days 3600 \
  2.         -nodes -keyout client-key.pem -out client-req.pem
  3.         
  4. writing new private key to 'client-key.pem'
  5. [root@box1 pki]# openssl rsa -in client-key.pem -out client-key.pem
  6. writing RSA key
  7. [root@box1 pki]# openssl x509 -sha384 -req -in client-req.pem -days 3600 \
  8. >         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
  9. Signature ok
  10. subject=/CN=client.dtstack.com
  11. Getting CA Private Key
复制代码
使用新的证书,就可以登录的数据库了:
  1. [root@box1 pki]# mysql -uuser_6 -phello -h127.0.0.1 --ssl-mode=required --ssl-cert=client-cert.pem --ssl-key=client-key.pem
  2. ...
  3. mysql> \s
  4. Current user:                user_6@localhost
  5. SSL:                        Cipher in use is ECDHE-RSA-AES256-GCM-SHA384
复制代码
附录:SSL证书相关命令

生成证书的命令
  1. # Create clean environment
  2. rm -rf newcerts
  3. mkdir newcerts && cd newcerts
  4. # Create CA certificate
  5. openssl genrsa 2048 > ca-key.pem
  6. openssl req -new -x509 -nodes -days 3600 \
  7.         -key ca-key.pem -out ca.pem
  8. # Create server certificate, remove passphrase, and sign it
  9. # server-cert.pem = public key, server-key.pem = private key
  10. openssl req -newkey rsa:2048 -days 3600 \
  11.         -nodes -keyout server-key.pem -out server-req.pem
  12. openssl rsa -in server-key.pem -out server-key.pem
  13. openssl x509  -sha384 -req -in server-req.pem -days 3600 \
  14.         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
  15. # Create client certificate, remove passphrase, and sign it
  16. # client-cert.pem = public key, client-key.pem = private key
  17. openssl req -subj /client.dtstack.com -newkey rsa:2048 -days 3600 \
  18.         -nodes -keyout client-key.pem -out client-req.pem
  19. openssl rsa -in client-key.pem -out client-key.pem
  20. openssl x509 -sha384 -req -in client-req.pem -days 3600 \
  21.         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
  22.         
  23. openssl x509 -req -in client-req.pem -days 3600 \
  24.         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
复制代码
查看证书信息
  1. [root@box1 mysql]# openssl x509 -text -in server-cert.pem -noout
  2. Certificate:
  3.     Data:
  4.         Version: 3 (0x2)
  5.         Serial Number: 2 (0x2)
  6.     Signature Algorithm: sha256WithRSAEncryption
  7.         Issuer: CN=MySQL_Server_5.7.32_Auto_Generated_CA_Certificate
  8.         Validity
  9.             Not Before: Mar 31 12:14:46 2021 GMT
  10.             Not After : Mar 29 12:14:46 2031 GMT
  11.         Subject: CN=MySQL_Server_5.7.32_Auto_Generated_Server_Certificate
  12.         Subject Public Key Info:
  13.             Public Key Algorithm: rsaEncryption
  14.                 Public-Key: (2048 bit)
  15.                 Modulus:
  16. [root@box1 pki]# openssl x509 -text -in client-cert.pem -noout
  17. Certificate:
  18.     Data:
  19.         Version: 1 (0x0)
  20.         Serial Number: 1 (0x1)
  21.     Signature Algorithm: sha384WithRSAEncryption
  22.         Issuer: C=CN, ST=HZ, L=ZJ, O=lazybug CO, OU=freecity, CN=www.dtstack.com/emailAddress=junda@dtstack.com
  23.         Validity
  24.             Not Before: Apr  1 01:34:53 2021 GMT
  25.             Not After : Feb  8 01:34:53 2031 GMT
  26.         Subject: CN=client.dtstack.com
  27.         Subject Public Key Info:
  28.             Public Key Algorithm: rsaEncryption
  29.                 Public-Key: (2048 b
复制代码
验证证书

使用openssl verify命令验证证书有效性。CAfile是用于创建证书的ca文件。
  1. [root@box1 pki]# openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
  2. server-cert.pem: OK
  3. client-cert.pem: OK
复制代码
如果ca文件和证书文件不匹配,验证会报错
  1. [root@box1 pki]# openssl verify -CAfile /var/lib/backupca/ca.pem server-cert.pem client-cert.pem
  2. server-cert.pem: C = CN, ST = ZJ, L = HZ, O = bugfree server, OU = land, CN = www.dtstack.com, emailAddress = server@dtstack.com
  3. error 20 at 0 depth lookup:unable to get local issuer certificate
  4. client-cert.pem: CN = client.dtstack.com
  5. error 20 at 0 depth lookup:unable to get local issuer certificate
复制代码
来源:https://www.cnblogs.com/yunchekeji/p/17956578
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具