官网地址:Protocol Basics
MySQL协议是一种有状态的协议。
当连接建立时,服务器启动一个连接阶段。 一旦执行,连接就进入指令阶段。 命令阶段在连接终止时结束。
进一步阅读:
- Connection Phase连接阶段
- Command Phase指令阶段
连接阶段
连接阶段执行这些任务:
- 交换客户端和服务器的能力
- 如果需要,设置SSL通信通道
- 在服务器验证客户端信息
连接阶段从客户端连接到可能发送ERR数据包并完成握手的服务器,或发送客户端使用握手响应数据包应答初始握手数据包。 在这个阶段,客户端可以请求SSL连接,在这种情况下,SSL通信通道在客户端发送其认证响应之前建立。
如果服务器发送ERR数据包作为第一个数据包,它将在客户端和服务器协商任何功能之前发生。 因此,ERR数据包将不包含SQL状态。
- 初始握手
- Auth阶段快速路径
- 身份验证方法不匹配
- COM_CHANGE_USER命令后进行身份验证
Connection Phase Packets 连接数据包
Protocol::Handshake 握手协议
初始化握手数据报文
当客户端连接到服务器时,服务器将握手数据包发送到客户端。 根据服务器版本和配置选项,发送初始数据包的不同变体。
为了允许服务器添加对较新协议的支持,第一个字节定义了协议版本。
从3.21.0开始,Protocol :: HandshakeV10被发送。
Protocol::HandshakeV10 握手协议V10版本
初始化V10的握手报文。
如果客户端支持SSL(Capabilities Flags&CLIENT_SSL处于打开状态,且客户端的mysql_ssl_mode不是SSL_MODE_DISABLED),则会发送名为Protocol :: SSLRequest的简短包,造成服务器建立SSL层并等待来自 客户。
客户端然后返回Protocol :: HandshakeResponse
在任何时候,如有任何错误,客户只会断开连接。
Protocol::SSLRequest
SSL连接请求数据包
它就像Protocol :: HandshakeResponse但在用户名字段之前被截断。 如果服务器支持CLIENT_SSL功能,则客户端可以发送此数据包来请求安全的SSL连接。 CLIENT_SSL能力标志必须在SSL连接请求数据包内设置。
Protocol::HandshakeResponse
根据服务器对CLIENT_PROTOCOL_41功能的支持以及客户端对该标志的理解,客户端必须发送Protocol :: HandshakeResponse320或Protocol :: HandshakeResponse41。
Protocol::HandshakeResponse320
旧客户端使用的旧握手响应数据包或服务器不支持CLIENT_PROTOCOL_41功能标志标志。
举个例子:
11 00 00 01 85 24 00 00 00 6f 6c 64 00 47 44 53 .....$...old.GDS
43 51 59 52 5f CQYR_
如果auth-response后跟一个数据库字段,它必须以NULL结尾。
Protocol::HandshakeResponse41
由支持CLIENT_PROTOCOL_41功能的4.1版本以上的客户端发送的握手响应数据包如果服务器在其Protocol::Handshake报文中标志,则使用该报文。 否则(与旧服务器通话)必须使用Protocol :: HandshakeResponse320数据包。
在具有CLIENT_PROTOCOL_41, CLIENT_PROTOCOL_41,CLIENT_PLUGIN_AUTH,CLIENT_SECURE_CONNECTION(在8.0中删除)和CLIENT_CONNECT_WITH_DB集的MySQL 5.5.8上,它可能如下所示:
54 00 00 01 8d a6 0f 00 00 00 00 01 08 00 00 00 T...............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 70 61 6d 00 14 ab 09 ee f6 bc b1 32 ....pam........2
3e 61 14 38 65 c0 99 1d 95 7d 75 d4 47 74 65 73 >a.8e....}u.Gtes
74 00 6d 79 73 71 6c 5f 6e 61 74 69 76 65 5f 70 t.mysql_native_p
61 73 73 77 6f 72 64 00 assword.
从MySQL 5.6.6开始,如果CLIENT_CONNECT_ATTRS被设置,客户端可以发送如下信息:
b2 00 00 01 85 a2 1e 00 00 00 00 40 08 00 00 00 ...........@....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 72 6f 6f 74 00 14 22 50 79 a2 12 d4 ....root.."Py...
e8 82 e5 b3 f4 1a 97 75 6b c8 be db 9f 80 6d 79 .......uk.....my
73 71 6c 5f 6e 61 74 69 76 65 5f 70 61 73 73 77 sql_native_passw
6f 72 64 00 61 03 5f 6f 73 09 64 65 62 69 61 6e ord.a._os.debian
36 2e 30 0c 5f 63 6c 69 65 6e 74 5f 6e 61 6d 65 6.0._client_name
08 6c 69 62 6d 79 73 71 6c 04 5f 70 69 64 05 32 .libmysql._pid.2
32 33 34 34 0f 5f 63 6c 69 65 6e 74 5f 76 65 72 2344._client_ver
73 69 6f 6e 08 35 2e 36 2e 36 2d 6d 39 09 5f 70 sion.5.6.6-m9._p
6c 61 74 66 6f 72 6d 06 78 38 36 5f 36 34 03 66 latform.x86_64.f
6f 6f 03 62 61 72 oo.bar
目前,不支持多字节字符集,如UCS2,UTF16和UTF32。
如果客户想要有一个安全的SSL连接并设置CLIENT_SSL标志,它应该首先发送Protocol :: SSLRequest数据包,然后在建立安全连接之后,它应该发送Protocol :: HandshakeResponse数据包。
Caching_sha2_password Message exchanges消息交换
Nonce - 由服务器密码生成的随机数 - 由客户端提供的密码Scramble - XOR(SHA2(密码),SHA2(SHA2(SHA2(密码)),Nonce))
- 案例1A:使用完全身份验证的身份验证成功 - TLS连接
服务器 - >客户端:发送临时客户端 - >服务器:发送扰乱服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送密码服务器 - >客户端:发送确定 - 认证成功 - 案例1B:通过完全认证的认证成功
明文连接| RSA密钥
服务器 - >客户端:发送nonce客户端 - >服务器:发送扰乱服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送用公钥加密的异或(密码,随机数)服务器 - >客户端:发送确认 - - 案例1C:使用完全验证的验证成功
明文连接| -get-server-public-key由客户端设置
服务器 - >客户端:发送nonce客户端 - >服务器:发送Scramble服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送request_server_public_key服务器 - >客户端:发送公钥客户端 - >服务器:发送XOR(密码,随机数) 公钥服务器 - >客户端:发送OK - 认证成功 - 案例2A:身份验证失败,带有完全身份验证 - TLS连接
- 案例3A:使用快速身份验证验证失败 - TLS连接
服务器 - >客户端:发送nonce客户端 - >服务器:发送扰乱服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送密码服务器 - >客户端:发送确认 - 身份验证失败 - 案例2B:使用完全验证纯文本连接|验证失败 RSA密钥和案例3B:使用快速认证的认证失败
明文连接| RSA密钥
服务器 - >客户端:发送nonce客户端 - >服务器:发送扰乱服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送用公钥加密的异或(密码,随机数)服务器 - >客户端:发送确认 -认证失败 - 案例2C:使用完全验证纯文本连接的验证失败| 客户端设置的-get-server-public-key
- 案例3C:使用快速认证的认证成功
明文连接| -get-server-public-key由客户端设置
服务器 - >客户端:发送nonce客户端 - >服务器:发送Scramble服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:发送request_server_public_key服务器 - >客户端:发送公钥客户端 - >服务器:发送XOR(密码,随机数) 公钥服务器 - >客户端:发送OK - 认证失败 - 案例2D:具有完全验证的验证失败 - 明文连接
- 案例3D:使用快速身份验证的身份验证失败 - 明文连接
服务器 - >客户端:发送nonce客户端 - >服务器:发送扰乱服务器 - >客户端:发送perform_full_authentication客户端 - >服务器:连接终止,因为:- 连接没有加密和
- 客户端没有公钥
- get-server-public-key未设置
- 案例4:采用快速认证的认证成功 - 任何连接
服务器 - >客户端:发送nonce客户端 - >服务器:发送Scramble服务器 - >客户端:发送OK - 认证成功 - 案例5A:使用空密码验证成功 - 任何连接
服务器 - >客户端:发送临时客户端 - >服务器:发送空响应服务器 - >客户端:发送确认 - 认证成功 - 案例5B:使用空密码验证失败 - 任何连接
服务器 - >客户端:发送nonce客户端 - >服务器:发送空响应服务器 - >客户端:发送OK - 认证失败
网友评论