[翻译]mysql通信协议(5)-Protocol Basics 之 Connection Lifecycle

官网地址:Protocol Basics

MySQL协议是一种有状态的协议。
当连接建立时,服务器启动一个连接阶段。 一旦执行,连接就进入指令阶段。 命令阶段在连接终止时结束。
进一步阅读:

  • Connection Phase连接阶段
  • Command Phase指令阶段

连接阶段

连接阶段执行这些任务:

  • 交换客户端和服务器的能力
  • 如果需要,设置SSL通信通道
  • 在服务器验证客户端信息

连接阶段从客户端连接到可能发送ERR数据包并完成握手的服务器,或发送客户端使用握手响应数据包应答初始握手数据包。 在这个阶段,客户端可以请求SSL连接,在这种情况下,SSL通信通道在客户端发送其认证响应之前建立。
如果服务器发送ERR数据包作为第一个数据包,它将在客户端和服务器协商任何功能之前发生。 因此,ERR数据包将不包含SQL状态。

在初始握手之后,服务器通知客户端有关用于认证的方法(除非在握手期间已建立),并且认证交换继续,直到服务器通过发送OK_Packet接受连接或通过ERR_Packet拒绝它。
  • 初始握手
  • Auth阶段快速路径
  • 身份验证方法不匹配
  • COM_CHANGE_USER命令后进行身份验证

Connection Phase Packets 连接数据包

Protocol::Handshake 握手协议

初始化握手数据报文
当客户端连接到服务器时,服务器将握手数据包发送到客户端。 根据服务器版本和配置选项,发送初始数据包的不同变体。
为了允许服务器添加对较新协议的支持,第一个字节定义了协议版本。
从3.21.0开始,Protocol :: HandshakeV10被发送。

Protocol::HandshakeV10 握手协议V10版本

初始化V10的握手报文。


如果客户端支持SSL(Capabilities FlagsCLIENT_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 :: HandshakeResponse320Protocol :: 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_41CLIENT_PROTOCOL_41CLIENT_PLUGIN_AUTHCLIENT_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 - 认证失败

你可能感兴趣的:([翻译]mysql通信协议(5)-Protocol Basics 之 Connection Lifecycle)