t4g 的 CPU credit 被吃完了

這個站 blog.gslin.org 掛了三個多小時:

先連機器 SSH 看起來是正常的,但習慣性的 w 看一下情況發現 CPU load 有 6.x,用 top 看一下就看到幾隻 php82-fpm 跑滿 CPU,心裡大概有底是被砍站了...

先把 nginx 停下來,瞄了一下 /var/log/nginx 下面的 log 就知道是 ClaudeBot 造成的,看起來都是從 AWSus-east-1 機器打過來的。

然後翻一下 log 看看什麼時候開始打的,先看 log 已經被 gzip 起來的這些:

$ echo /var/log/nginx/blog.gslin.org_ssl-access.log.{?,??}.gz | xargs -n1 | xargs -n1 -I% sh -c "echo %; zgrep ClaudeBot % | wc"
/var/log/nginx/blog.gslin.org_ssl-access.log.2.gz
  13031  169403 1986719
/var/log/nginx/blog.gslin.org_ssl-access.log.3.gz
    459    5967   85350
/var/log/nginx/blog.gslin.org_ssl-access.log.4.gz
  14533  188929 2219819
/var/log/nginx/blog.gslin.org_ssl-access.log.5.gz
   6502   84526 1026178
/var/log/nginx/blog.gslin.org_ssl-access.log.6.gz
  32483  422279 4905919
/var/log/nginx/blog.gslin.org_ssl-access.log.7.gz
  21304  276952 3221877
/var/log/nginx/blog.gslin.org_ssl-access.log.8.gz
   7921  102973 1199356
/var/log/nginx/blog.gslin.org_ssl-access.log.9.gz
      0       0       0
/var/log/nginx/blog.gslin.org_ssl-access.log.10.gz
      0       0       0
/var/log/nginx/blog.gslin.org_ssl-access.log.11.gz
      0       0       0
/var/log/nginx/blog.gslin.org_ssl-access.log.12.gz
      0       0       0
/var/log/nginx/blog.gslin.org_ssl-access.log.13.gz
      0       0       0
/var/log/nginx/blog.gslin.org_ssl-access.log.14.gz
      0       0       0

看起來是從 blog.gslin.org_ssl-access.log.8.gz 這邊開始的,大概是 1/25 開始 (機器上面是 UTC 時間):

-rw-r----- 1 www-data adm   1894325 Jan 26 00:00 /var/log/nginx/blog.gslin.org_ssl-access.log.8.gz

然後再來看一下最近的 log,看起來是這兩天打的特別重,到五萬多:

$ echo /var/log/nginx/blog.gslin.org_ssl-access.log{,.?} | xargs -n1 | xargs -n1 -I% sh -c "echo %; grep ClaudeBot % | wc"
/var/log/nginx/blog.gslin.org_ssl-access.log
  29436  382668 4387703
/var/log/nginx/blog.gslin.org_ssl-access.log.1
  51712  672256 7852345

拉了 AWS 的圖來看跟預期的差不多:

機器是 t4g.micro 而且沒開 burstable,先前差不多都是略低於 10% 的線在跑,剛好利用 CPU credit 的概念,這幾天看起來就是被打而跑上去。

好像該補一下 alarm,丟到我自己的 Slack 以及 Pushover...

最近 Linux 核心安全性問題的 Dirty Pipe 故事很有趣...

Hacker News 上看到「The Dirty Pipe Vulnerability」這個 Linux kernel 的安全性問題,Hacker News 上相關的討論在「The Dirty Pipe Vulnerability (cm4all.com)」這邊可以看到。

這次出包的是 splice() 的問題,先講他寫出可重製 bug 的程式碼,首先是第一個程式用 user1 放著跑:

#include <unistd.h>
int main(int argc, char **argv) {
  for (;;) write(1, "AAAAA", 5);
}
// ./writer >foo

然後第二個程式也放著跑 (可以是不同的 user2,完全無法碰到 user1 的權限):

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv) {
  for (;;) {
    splice(0, 0, 1, 0, 2, 0);
    write(1, "BBBBB", 5);
  }
}
// ./splicer <foo |cat >/dev/null

理論上不會在 foo 裡面看到任何 BBBBB 的字串,但卻打穿了... 透過 git bisect 的檢查,他也確認了是在「pipe: merge anon_pipe_buf*_ops」這個 commit 時出的問題。

不過找到問題的過程拉的頗長,一開始是有 web hosting 服務的 support ticket 說 access log 下載下來發現爛掉了,無法解壓縮:

It all started a year ago with a support ticket about corrupt files. A customer complained that the access logs they downloaded could not be decompressed. And indeed, there was a corrupt log file on one of the log servers; it could be decompressed, but gzip reported a CRC error.

然後他先手動處理就把票關起來了:

I fixed the file’s CRC manually, closed the ticket, and soon forgot about the problem.

接下來過幾個月後又發生,經過幾次的 support ticket 後他手上就有一些「資料」可以看:

Months later, this happened again and yet again. Every time, the file’s contents looked correct, only the CRC at the end of the file was wrong. Now, with several corrupt files, I was able to dig deeper and found a surprising kind of corruption. A pattern emerged.

然後因為發生的頻率也不是很高,加上邏輯上卡到死胡同,所以他也沒有辦法花太多時間在上面:

None of this made sense, but new support tickets kept coming in (at a very slow rate). There was some systematic problem, but I just couldn’t get a grip on it. That gave me a lot of frustration, but I was busy with other tasks, and I kept pushing this file corruption problem to the back of my queue.

後來真的花時間下去找,利用先前的 pattern 掃了一次系統 log,發現有規律在:

External pressure brought this problem back into my consciousness. I scanned the whole hard disk for corrupt files (which took two days), hoping for more patterns to emerge. And indeed, there was a pattern:

  • there were 37 corrupt files within the past 3 months
  • they occurred on 22 unique days
  • 18 of those days have 1 corruption
  • 1 day has 2 corruptions (2021-11-21)
  • 1 day has 7 corruptions (2021-11-30)
  • 1 day has 6 corruptions (2021-12-31)
  • 1 day has 4 corruptions (2022-01-31)

The last day of each month is clearly the one which most corruptions occur.

然後就試著寫各種 reproducible code,最後成功的版本就是開頭提到的,然後他發現這個漏洞可以是 security vulnerability,就回報出去了,可以看到前後從第一次的 support ticket 到最後解決花了快一年的時間,不過 Linux kernel 端修正的速度蠻快的:

  • 2021-04-29: first support ticket about file corruption
  • 2022-02-19: file corruption problem identified as Linux kernel bug, which turned out to be an exploitable vulnerability
  • 2022-02-20: bug report, exploit and patch sent to the Linux kernel security team
  • 2022-02-21: bug reproduced on Google Pixel 6; bug report sent to the Android Security Team
  • 2022-02-21: patch sent to LKML (without vulnerability details) as suggested by Linus Torvalds, Willy Tarreau and Al Viro
  • 2022-02-23: Linux stable releases with my bug fix (5.16.11, 5.15.25, 5.10.102)
  • 2022-02-24: Google merges my bug fix into the Android kernel
  • 2022-02-28: notified the linux-distros mailing list
  • 2022-03-07: public disclosure

整個故事還蠻精彩的 XD

AWS 推出 CloudWatch Metric Streams

AWS 推出了 CloudWatch Metric Streams,把 CloudWatch Metric 的資料往 Kinesis Data Firehose 裡面丟:「CloudWatch Metric Streams – Send AWS Metrics to Partners and to Your Apps in Real Time」。

其中一個賣點是即時性比用 API 去拉好很多:

In order to make it easier for AWS Partners and others to gain access to CloudWatch metrics faster and at scale, we are launching CloudWatch Metric Streams. Instead of polling (which can result in 5 to 10 minutes of latency), metrics are delivered to a Kinesis Data Firehose stream.

格式上可以是 JSON 或是 Open Telemetry

When you set up a stream you choose between the binary Open Telemetry 0.7 format, and the human-readable JSON format.

另外一個賣點是價位,每千次 $0.003:

Pricing – You pay $0.003 for every 1000 metric updates, and for any charges associated with the Kinesis Data Firehose. To learn more, check out the pricing page.

另外算一下 Kinesis Data Firehose 的價錢,是以資料量的大小計費,不過最小計價單位是 5KB (一筆應該是不會到),單價是 $0.029/GB (us-east-1) 或是 $0.037/GB (ap-southeast-1),算了一下跟 CloudWatch Metrics Streams 比起來只是零頭...

之前如果要自己拉出來的話是透過 API call 抓,每 1000 次是 USD$0.01,這個方法相較起來便宜不少,不過數量多的時候還是一筆費用 (而且有不少 metrics 是一分鐘更新一次)。

如果只是要備份起來或是跑分析的話,也許先前用 API 拉的作法可能還是比較好?一個小時拉一次對於備份與分析應該都很夠了,而 alarm 的機制還是掛在 CloudWatch 上。

這次產品的定位看起來是要把 ecosystem 做起來:

We designed this feature with the goal of making it easier & more efficient for AWS Partners including Datadog, Dynatrace, New Relic, Splunk, and Sumo Logic to get access to metrics so that the partners can build even better tools.

英國的 ISP 開始記錄使用者的連線資訊

從「Two UK Broadband ISPs Trial New Internet Snooping System」這邊看到英國的 ISP 開始記錄使用者的連線資訊,簡化後的 log 樣子像是這樣:

Two unnamed broadband or mobile ISPs are reportedly helping the UK Home Office and the National Crime Agency (NCA) to trial a new internet snooping system on their customers, which is being conducted as part of the controversial 2016 UK Investigatory Powers Act (aka – snoopers charter).

加上「T-Mobile US 打算要賣使用者的瀏覽記錄了」這篇,繼續推廣 DNS over HTTPDNS over TLS,以及 ECH (Encrypted Client Hello)。

kernel.org 推動 git push 的簽名

LWN 上看到 kernel.org 解釋並且推動 git push 的電子簽名:「Signed pushes for kernel.org」。

在「Signed git pushes」這篇裡面解釋了除了 git commit 本身的簽名外,另外 git push 的簽名也有重要性。

而在「Introducing the kernel.org git transparency log」這邊則是公開了對應的 git transparency log。

這個方法讓 kernel.org 上的 git repository 會更透明,加上 kernel.org 上的 git repository 會被很多人 mirror,在真的出問題的時候,大家手上也都有資料可以交叉比對...

前陣子爆出「不保留記錄的 VPN」保留了大量的客戶與連線資訊

前陣子 comparitech 發現了宣稱不保留記錄的 VPN 廠商 UFO VPNElasticsearch 伺服器沒有設定好,造成外部可以直接存取,然後發現裡面包含了大量記錄:「“Zero logs” VPN exposes millions of logs including user passwords, claims data is anonymous」,這篇文章的小標把重點先說完了:

UFO VPN exposed millions of log files about users of its service, including their account passwords and IP addresses, despite claiming that it keeps no logs.

目前還是建議在有能力的情況下都自己架,一般常見就是用 OpenVPN,但設定上會比較麻煩一些。如果要方便的話可以用 Openconnect VPN Server (ocserv) 架 server,然後在手機上可以直接用 Cisco 官方提供的用戶端接,像是 Cisco AnyConnect (iOS) 與 AnyConnect (Android),在桌機上一般則是用 OpenConnect 自家的軟體連接。

家裡有 HiNet 的網路的話,可以申請一個固定 IP (透過 PPPoE 的),然後用一台 Raspberry Pi 之類的設備架設。

倒不是說這些 VPN 廠商的服務不能用,只是你必須認知這些 VPN 是拿來繞過地區限制的,而不是為了安全性或是隱私,所以如果是人在外面使用網路,想要避免被商家或是外面的 ISP 看到流量內容,透過自己架設的 VPN 應該會好不少。

CloudFront 的 access log 多了一些欄位

CloudFront 的 access log 多了一些欄位可以抓:「Amazon CloudFront now provides seven new data fields in access logs」。

官方這次加了七個欄位,看起來後面六個都還蠻有用的... (第一個 c-port 是 client 的 port,目前只想的到 debug 時可以拿出來看...)

而第二個的 time-to-first-byte 可以拿來分析效能,這是從 CloudFront 的角度來看的。

第三個的 x-edge-detailed-result-type 是錯誤時的處理,讓管理者可以從 access log 直接粗略分析。

剩下的四個都是跟 content type 與 length/range 有關,之前居然沒有嗎...

Amazon Detective:用 Machine Learning 分析可能的安全問題

也是這次 AWS re:Invent 發表的服務,透過 Machine Learning 分析可能的安全問題:「Introducing Amazon Detective」。

透過現有的各種 log 建立模型分析:

Amazon Detective can analyze trillions of events from multiple data sources such as Virtual Private Cloud (VPC) Flow Logs, AWS CloudTrail, and Amazon GuardDuty, and automatically creates a unified, interactive view of your resources, users, and the interactions between them over time.

依照 log 的量算錢的,然後 preview 階段不收費,所以有興趣的人可以開起來跑看看?