PagerDuty 早上很早就出发了,我们的英雄诅咒自己倒霉并接到了电话。他让 PagerDuty 将消息重复两次,但无法理解消息。他按下号码以确认这件事。他打开 MacBook,发现来自 PagerDuty 机器人的 slack 消息信息量更大。他单击了链接,然后将他带到了 Grafana 仪表板。

他盯着红色的心形图标看了几秒,其中一个微服务故障率很高。有一秒钟,他很想更新错误阈值,这样他就可以回去睡觉了。勉强地,他打开 Graylog 并查看日志,注意到 401 响应。他在日志中查找更多信息,但没有找到有用的信息。

他连接到生产 VPN 并使用 kubectl exec 进入其中一个 k8s pod。他想查看原始 HTTP 请求,但不记得服务器监听的端口号。

$ ss -lp
Netid          State                      Local Address:Port     Peer Address:Port
nl             UNCONN                           tcpdiag:kernel               *
nl             UNCONN                           tcpdiag:ss/1355              *
nl             UNCONN                              genl:kernel               *
u_str          LISTEN  /tmp/puma-status-1667909371846-1 403125              * 0             users:(("ruby",pid=68,fd=12),("ruby",pid=58,fd=12),("ruby",pid=1,fd=12))
tcp            LISTEN                           0.0.0.0:8000          0.0.0.0:*             users:(("ruby",pid=68,fd=5),("ruby",pid=58,fd=5),("ruby",pid=1,fd=5))
tcp            LISTEN                           0.0.0.0:9394          0.0.0.0:*             users:(("ruby",pid=1,fd=20))

ss是插座的瑞士军刀。标志 -l 代表监听,-p 代表进程。他向系统询问了所有正在监听任何端口的套接字以及进程级别的详细信息。一旦他查看了输出,他就知道服务器正在侦听8000。仍然昏昏沉沉,他跑了

$ tcpflow -c -e http dst port 8000

100.100.102.033.47106-100.100.102.017.08000: GET /api/me HTTP/1.1
Host: www.ananthakumaran.in
X-Request-ID: b061642af69518f68315242ee8ef330c
X-Real-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: www.ananthakumaran.in
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Scheme: http
X-Forwarded-Proto: https
X-Forwarded-Ssl: on
sec-ch-ua: "Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"
Accept: application/json
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
sec-ch-ua-platform: "Linux"
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://ananthakumaran.in/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,hi;q=0.8,ta;q=0.7
If-None-Match: W/"2b41babef3e0d190ded246a5843cda02"


100.105.004.216.50720-100.100.102.017.08000: GET /api/transactions HTTP/1.1
Host: www.ananthakumaran.in
X-Request-ID: 9f7ed9688726fa3477c769138c87f448
X-Real-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: www.ananthakumaran.in
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Scheme: http
X-Forwarded-Proto: https
X-Forwarded-Ssl: on
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: application/json
User-Agent: Ruby
Content-Type: application/json
Authorization: Bearer 000000000000000


172.025.038.179.38652-100.100.102.017.08000: GET /healthcheck HTTP/1.1
Host: 100.100.102.17:8000
User-Agent: kube-probe/1.19
Accept-Encoding: gzip
Connection: close

tcpflow可以分析通过tcp套接字传输的数据。它可以查看任何活动的 TCP 套接字并显示来回通信。您可能会认为,这听起来与 非常相似tcpdump,只是稍作改动,它就理解 HTTP 协议并以有意义的方式显示 HTTP 请求和响应。标志 -c 将所有输出发送到标准输出,否则,将创建多个文件来表示请求、响应和解码主体。它也可以解码 gzip 编码的响应。

127.000.000.001.04001-127.000.000.001.33378
127.000.000.001.04001-127.000.000.001.33378-HTTPBODY-001.json
127.000.000.001.33378-127.000.000.001.04001

让我们回到我们的故事。当他看到滚动的文字墙时,他很快就意识到了自己的错误。他只对一个 API 端点感兴趣。

$ tcpflow -c -e http dst port 8000 | grep -A 15 "GET /api/transactions"
reportfilename: ./report.xml
tcpflow: listening on eth0
100.105.004.216.50720-100.100.102.017.08000: GET /api/transactions?investor_id=000000000000000 HTTP/1.1
Host: ananthakumaran.in
X-Request-ID: 7adce1452bfd292d587888df58db470e
X-Real-IP: 172.25.79.86
X-Forwarded-For: 172.25.79.86
X-Forwarded-Host: ananthakumaran.in
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Scheme: http
X-Forwarded-Proto: https
X-Forwarded-Ssl: on
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: application/json
User-Agent: Ruby
Content-Type: application/json
Authorization: Bearer 000000000000000

他看着持有者令牌,突然间一切都变得清晰起来。他们上周轮换了 API 密钥,旧密钥的宽限期昨天结束,但其中一位客户仍在使用过期的密钥。他向项目频道发送了一条 slack 消息,然后继续睡觉,很高兴他不需要修理任何东西。

 

via https://ananthakumaran.in/2022/11/12/trace-http-requests.html

使用 tcpflow 跟踪 HTTP 请求
标签: