wireshark之redis协议分析

redis协议简介

redis使用的通信协议是RESP(REdis Serialization Protocol), 是一种简便, 可读性很好的通信协议

以下内容摘自RESP2的文档内容, 参考地址: https://redis.io/topics/protocol

RESP3的文档地址: https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md, 对RESP2进行了扩充, 比如以","开头的浮点数返回,1.23<CR><LF>, 感兴趣的可以看看, 帮助你更好的了解和使用redis.

redis响应格式:

简单字符串

第一个字节是 “+”

用于非二进制安全的简短字符串应答, 以CRLF结束, 网络字节值为0x0d0x0a, 字符串"\r\n"

注意, 一般情况是"\r\n"的字节编码就是0x0d,0x0a, 但是有些编码格式则不同, 这种情况会发生错误

例如: +PONG<CR><LF> , +OK<CR><LF>

错误信息:

第一个字节是"-"

类似于简单字符串信息, 只是用于表达错误信息, 也是以CRLF结束

例如:

-Error message<CR><LF>

-ERR unknown command 'foobar'<CR><LF>

-WRONGTYPE Operation against a key holding the wrong kind of value<CR><LF>

整数信息:

第一个字节是":"

用于进行整数信息回复, 比如命令: INCR, LLEN, LASTSAVE等

例如:

:0<CR><LF>

:10000<CR><LF>

大容量字符串:

第一个字节是:"$"

单行二进制安全字符串响应, 最大长度512mb, "$"后面的数组表示内容长度

例如:

$6<CR><LF>foobar<CR><LF>

$-1<CR><LF> 回复一个空(NULL)字符串, 相当于null, nil, 客户端请求一个nil对象时, 会返回这个, 这个不同于"", ""表示格式是 $0<CR><LF>

数组列表信息:

第一个字节是: “*”

返回一个列表信息, "*"后面的数字表示元素个数, LRANGE之类的指令会返回这种格式信息

例如:

*0<CR><LF> 表示空列表

*2<CR><LF>$3<CR><LF>foo<CR><LF>$3<CR><LF>bar<CR><LF> 长度为2的列表, 俩个元素内容分别为foo和bar

*-1<CR><LF> NULL列表, BLPOP如果超时了, 就会返回这种信息

*2<CR><LF> *3<CR><LF>:1<CR><LF>:2<CR><LF>:4<CR><LF> *2<CR><LF>+OK<CR><LF>-ERR<CR><LF>这是一个嵌套列表信息

使用wireshark 抓取redis数据包

配置抓包过滤 host 10.229.99.168 10.229.99.168是redis的服务地址

点击开始抓取进行抓包

写一个redistemplate 的测试类, 向redis发送数据

RedisSentinelConfiguration rsc = new RedisSentinelConfiguration();
        rsc.addSentinel(
                new RedisNode("10.229.99.168", 7379));
        rsc.setPassword("我是密码");

        rsc.setMaster("master1");

        JedisPoolConfig jpc = new JedisPoolConfig();

        jpc.setMaxTotal(10);
        jpc.setMaxIdle(5);
        jpc.setTestOnBorrow(true);
        jpc.setMaxWaitMillis(500L);

        JedisConnectionFactory factory =  new JedisConnectionFactory(rsc, jpc);
        factory.afterPropertiesSet();
        RedisTemplate<String, String> redisT = new RedisTemplate<>();
        redisT.setConnectionFactory(factory);
        redisT.setDefaultSerializer(new StringRedisSerializer());
        redisT.afterPropertiesSet();
        redisT.opsForList().leftPush("tlist", "test");
        redisT.delete("tlist");

运行, 这时可以在wireshark中查看redis数据包了

分析sentinel数据包

配置显示过滤, 先过滤出sentinel数据包, tcp.port eq 7379 7379是redis sentinel的接口

首先看到三次握手, 建立tcp连接

1	0.000000	172.24.123.111	10.229.99.168	TCP	66	51606 → 7379 [SYN] Seq=467271664 Win=64680 Len=0 MSS=1470 WS=256 SACK_PERM=1
2	0.043827	10.229.99.168	172.24.123.111	TCP	60	7379 → 51606 [SYN, ACK] Seq=4095492181 Ack=467271665 Win=14600 Len=0 MSS=1460
3	0.043964	172.24.123.111	10.229.99.168	TCP	54	51606 → 7379 [ACK] Seq=467271665 Ack=4095492182 Win=64680 Len=0

接着客户端给redis-sentinel服务发送数据:

4	0.051048	172.24.123.111	10.229.99.168	TCP	115	55750 → 7379 [PSH, ACK] Seq=957963677 Ack=344093169 Win=64680 Len=61

数据内容显示如下

*3
$8
SENTINEL
$23
get-master-addr-by-name
$7
master1

服务端发送ack数据包, 确认收到数据:

5	0.094628	10.229.99.168	172.24.123.111	TCP	60	7379 → 55750 [ACK] Seq=344093169 Ack=957963738 Win=14600 Len=0

服务端接着发送客户端指令get-master-addr-by-name的响应数据

6	0.095346	10.229.99.168	172.24.123.111	TCP	87	7379 → 55750 [PSH, ACK] Seq=344093169 Ack=957963738 Win=14600 Len=33

数据内容显示如下:

*2
$12
10.229.99.168
$4
6480

返回了redis master server 的地址和端口号, 10.229.99.168:6480 , 6480位redis master server的端口号, 接着这个sentinel连接会随着客户端发送rst包强制断开。

新的sentinel连接会开启,顺序如下:

  1. 三次握手, 建立连接

  2. 客户端发送指令 *3$8SENTINEL$23get-master-addr-by-name$7master1, 请求获取主服务地址

  3. 服务端响应, *2$1210.229.99.168$46480

  4. 客户端会发送订阅主服务切换指令

    14	0.219555	172.24.123.111	10.229.99.168	TCP	94	55751 → 7379 [PSH, ACK] Seq=2989715116 Ack=3319979599 Win=64647 Len=40
    

    数据包内容如下:

    *2
    $9
    SUBSCRIBE
    $14
    +switch-master
    
  5. sentinel服务端返回订阅成功的信息

    15	0.267211	10.229.99.168	172.24.123.111	TCP	98	7379 → 55751 [PSH, ACK] Seq=3319979599 Ack=2989715156 Win=14600 Len=44
    

    数据包内容如下:

    *3
    $9
    subscribe
    $14
    +switch-master
    :1
    
  6. 保持连接, 如果服务器上redis服务发生主从切换, sentinel服务端会返回信息如下:

    *3
    $7
    message
    $14
    +switch-master
    $43
    master1 10.229.99.168 6480 10.229.99.168 6479
    

    redis主服务从10.229.99.168:6480切换到0.229.99.168:6479

  7. 这就是redis sentinel的数据交互的过程, 再看下redis服务的数据交互

分析redis server数据包

配置显示过滤为 tcp.port in {6479, 6480} 6480, 6479分别为 redis 主, 从服务端口

这时候, 我们就把redis server交互的数据包过滤出来了。

  1. 首先是三次握手, 建立连接

    17	0.489588	172.24.123.111	10.229.99.168	TCP	66	55752 → 6480 [SYN] Seq=2488491565 Win=64680 Len=0 MSS=1470 WS=256 SACK_PERM=1
    18	0.533252	10.229.99.168	172.24.123.111	TCP	60	6480 → 55752 [SYN, ACK] Seq=2932666663 Ack=2488491566 Win=14600 Len=0 MSS=1460
    19	0.533311	172.24.123.111	10.229.99.168	TCP	54	55752 → 6480 [ACK] Seq=2488491566 Ack=2932666664 Win=64680 Len=0
    
  2. 客户端向redis server服务端发送认证请求

    *2
    $4
    AUTH
    $14
    Password-value
    

    Password-value是redis server配置中的认证密码

  3. 服务端返回认证成功的指令+OK<CR><LF>, 如果密码错误的话, 会返回错误信息: -ERR invalid password<CR><LF>

  4. 客户端发送PING指令

    *1
    $4
    PING
    
  5. 服务端响应PONG

    +PONG<CR><LF>
    
  6. 客户端发送存储列表数据指令

    *3
    $5
    LPUSH
    $5
    tlist
    $4
    test
    
  7. 服务端响应存入列表的元素个数

    :1<CR><LF>
    
  8. 客户端发送PING

  9. 服务端响应PONG

  10. 客户端发送删除tlist指令

    *2
    $3
    DEL
    $5
    tlist
    
  11. 服务端响应删除键的个数

    :1<CR><LF>
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Wireshark是一款开源的网络协议分析工具,它可以用于捕获和分析网络数据包。通过Wireshark,你可以深入了解TCP协议的工作原理和网络通信过程。 在进行TCP协议分析时,你可以使用Wireshark来捕获网络数据包,并对这些数据包进行详细的解析和分析。以下是使用Wireshark进行TCP协议分析的一般步骤: 1. 下载和安装Wireshark:你可以从Wireshark官方网站下载并安装适合你操作系统的版本。 2. 打开Wireshark并选择网络接口:启动Wireshark后,选择你要进行抓包的网络接口。Wireshark将开始捕获该接口上的数据包。 3. 过滤TCP协议:在Wireshark的过滤器栏中输入"tcp",以便只显示与TCP协议相关的数据包。 4. 分析捕获的数据包:Wireshark将显示捕获到的数据包列表。你可以点击每个数据包以查看其详细信息,包括源IP地址、目标IP地址、端口号、序列号、确认号等。 5. 分析TCP会话:通过查看TCP数据包的序列号和确认号,你可以了解TCP会话的建立、维护和关闭过程。你还可以查看TCP头部中的各个字段,如标志位(SYN、ACK、FIN等)和窗口大小等。 6. 分析TCP流:Wireshark还提供了TCP流功能,可以将同一TCP会话中的数据包组合在一起,以便更好地分析和理解数据传输过程。 7. 进行统计和过滤:Wireshark还提供了各种统计功能,如流量统计、延迟分析等。你可以使用过滤器来筛选出特定条件下的数据包,以便更精确地进行分析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值