【问题标题】:How to use wireshark to capture mysql query sql clearly如何使用wireshark清晰捕获mysql查询sql
【发布时间】:2016-07-03 07:13:29
【问题描述】:

由于我们使用远程Mysql服务器进行开发,所以无法轻松查看查询sql,如果使用本地服务器可以tail - f general_log_file查看调用某个http接口时执行了哪些sql。所以我安装了一个wireshark 来捕获这些从本地发送的查询sql。一开始我使用本地mysql来验证它。

捕获过滤器是

然后我在mysql终端执行了两个查询sql

select version();
select now();

但是很失望我在wireshark中找不到这两个sql包 我只找到了这四个包。

但是从我知道的帖子中

要过滤掉 mysql 数据包,您只需使用过滤器 ‘mysql’ 或 ‘mysql.query != “”‘ 当您只想要请求查询的数据包时。之后,您可以添加一个字段名称为“mysql.query”的自定义列,以获得执行的查询列表。

效果是这样的 只捕获查询sql很方便,并且非常清楚的显示这些查询sql。那么我该如何使用wireshark 来实现呢?


嗨@Jeff S.

我试过你的命令,请看下面

#terminal 1
tshark -i lo0 -Y "mysql.command==3"
Capturing on 'Loopback'

# terminal 2
mysql -h127.0.0.1 -u root -p
select version();
#result: nothing output in terminal 1

并且tshark -i lo0 -Y "mysql.command==3" -T fields -e mysql.querytshark -i lo -Y "mysql.command==3" 相同,也没有任何输出。但是如果我只使用tshark -i lo0,它就有输出

Capturing on 'Loopback'
 1   0.000000    127.0.0.1 -> 127.0.0.1    TCP 68 57881 → 3306 [SYN] Seq=0 Win=65535 Len=0 MSS=16344 WS=32 TSval=1064967501 TSecr=0 SACK_PERM=1
 2   0.000062    127.0.0.1 -> 127.0.0.1    TCP 68 3306 → 57881 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=16344 WS=32 TSval=1064967501 TSecr=1064967501 SACK_PERM=1
 3   0.000072    127.0.0.1 -> 127.0.0.1    TCP 56 57881 → 3306 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=1064967501 TSecr=1064967501
 4   0.000080    127.0.0.1 -> 127.0.0.1    TCP 56 [TCP Window Update] 3306 → 57881 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=1064967501 TSecr=1064967501
...

【问题讨论】:

  • 这正是你必须要做的。如果你在过滤器中输入这个会发生什么?显示列将随您的过滤器而变化。

标签: mysql wireshark tshark


【解决方案1】:

您可以使用 tshark 并保存到 pcap 或只导出您感兴趣的字段。

保存到 pcap (如果你想使用 wireshark 稍后查看):

tshark -i lo -Y "mysql.command==3" -w outputfile.pcap
tshark -i lo -R "mysql.command==3" -w outputfile.pcap
-R is deprecated for single pass filters, but it will depend on your version
-i is interface so replace that with whatever interface you are using (e.g -i eth0)

保存到文本文件:

tshark -i lo -Y "mysql.command==3" -T fields -e mysql.query > output.txt

您还可以将 BPF 过滤器与 tcpdump(和 wireshark 前置过滤器)一起使用。如果您捕获大量流量,它们会更复杂,但对您的系统的负担会更少。

sudo tcpdump -i lo "dst port 3306 and  tcp[(((tcp[12:1]&0xf0)>>2)+4):1]=0x03" -w outputfile.pcap

注意:
*这会在 TCP 有效负载中查找 03(类似 mysql.command==3)。
**由于这是一个非常松散的过滤器,我还添加了 3306 以限制仅发往该端口的流量。 ***过滤器基于您的屏幕截图。我现在无法验证它,所以如果它不起作用,请告诉我。

示例输出:

【讨论】:

  • 我试过你的方法,但没有成功。请看我的帖子。
  • 我刚试过,它对我有用。你用的是什么版本的 tshark?我用屏幕截图编辑了上面的答案。
  • 谢谢! tshark 版本:tshark -v TShark (Wireshark) 2.0.4 (v2.0.4-0-gdd7746e from master-2.0); mysql版本:5.7.12; Mac OS X EI Capitan 版本 10.11.5
  • 我升级到 2.0.4 并且能够看到查询。尝试调整命令以查看是否可以使其正常工作。例如,使用 -Y 'mysql.command>=0' 或您原来的 'mysql.query != “”' 不幸的是,我无法访问 mac 来验证这一点。
  • 嗨@Jeff S 我尝试了另一个tshark 命令,这次它可以成功捕获从本地到远程mysql服务器的查询sql。请在下面查看我的答案。
【解决方案2】:

这里有用的答案: https://serverfault.com/questions/358978/how-to-capture-the-queries-run-on-mysql-server

特别是:SoMoSparky 的回答:

tshark -T fields -R mysql.query -e mysql.query

和 user1038090 的回答:

tcpdump -i any -s 0 -l -vvv -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
  if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
    if (defined $q) { print "$q\n"; }
    $q=$_;
  } else {
    $_ =~ s/^[ \t]+//; $q.=" $_";
  }
}'

【讨论】:

    【解决方案3】:

    我尝试了来自this post 的另一个tshark 命令,它可以捕获从本地到远程mysql 服务器的查询sql。

    tshark -i en0 -d tcp.port==3306,mysql -T fields -e mysql.query 'port 3306'
    Capturing on 'Wi-Fi'
    select version()
    
    
    select now()
    
    
    select rand()
    

    但它也会在这些 sql 之间输出一些空行。我试过下面的命令想要删除空行但失败了

    tshark -i en0 -d tcp.port==6006,mysql -Y "frame.len>10" -T fields -e mysql.query 'port 6006'
    

    不幸的是这个命令不支持捕获查询sql到本地mysql(5.7.12)。

    tshark -i lo -d tcp.port==3306,mysql -T fields -e mysql.query 'port 3306'
    Capturing on 'Loopback'
    

    除了空行没有输出。

    【讨论】:

    • 您看到的是空白行,因为该命令并未仅过滤查询者。看起来您现在在 en0 而不是 lo 上看到了这个流量,所以试试这个: tshark -i en0 -Y "mysql.command==3" -T fields -e mysql.query
    • 谢谢!但用你的方式没有输出。看来 tshark 无法在我的机器上正确解析它。
    【解决方案4】:

    Wireshark 工具支持 MySQL 协议: https://www.wireshark.org/docs/dfref/m/mysql.html

    然后配置wireshark

    a.menu Analyze --> Decode as --> add "field=tcp_port value=3306  current=MySQL"
    b.filter ‘mysql‘ or ‘mysql.query != “”‘ 
    

    【讨论】:

      【解决方案5】:

      我有类似的“问题”

      尝试检查你的mysql ssl

      可能 ssl 已打开,因此流量已加密

      你可以参考这篇文章来检查ssl:https://dba.stackexchange.com/questions/36776/how-can-i-verify-im-using-ssl-to-connect-to-mysql

      【讨论】:

      • 这个。我在端口 3306 中看到数据,但它没有任何意义,mysql 显示过滤器也无能为力。我不得不使用mysql -uroot --ssl-mode=DISABLED 禁用加密,然后在没有加密的情况下连接到服务器。然后 Wireshark 可以显示 mysql 协议。
      猜你喜欢
      • 2013-10-22
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多