nginx + AWStats

AWStats 是個很老牌的分析工具,直接對 access log 分析後提供報表,本來以為是完全沒在動的專案,但從版本記錄發現 2020 年與 2023 年各有一版修安全性問題,看起來還是有在維護?

會想到要裝是因為這幾天被砍站,CPU credit balance 低到觸發我設定的 alarm:

除了處理外,也想快速看一下發生什麼事情,而這種砍站的在 JavaScript 類的分析服務上不會看到,需要直接對 server log 分析,所以就想到 AWStats 了...

Ubuntu 可以透過 sudo apt install -y awstats 安裝,裝完以後會看到 /etc/cron.d/awstats 裡面每十分鐘會自己跑一次。

預設的設定目錄在 /etc/awstats 裡面,而且有系統預設的 awstats.conf 與讓使用者蓋過去的 awstats.conf.local,可以避免升級時直接把使用者自己設定的值蓋掉。

最少有幾個要設定需要設,可以參考官方文件「AWStats configuration directives/options」裡面的說明:

LogFile="/var/log/nginx/blog.gslin.org_ssl-access.log"
LogFormat=1
SiteDomain=blog.gslin.org

接下來因為 AWStats 是 CGI script,但 nginx 不直接支援 CGI,所以需要找工具透過 FastCGICGI 程式,在這邊我是用 fcgiwrap 轉,這個軟體可以直接裝:

sudo apt install -y fcgiwrap

網路上翻文件看到也不少人是用 PHP 轉的 (應該是互相 copy & paste),也是個方法...

接下來就是去 document root 下面把 cgi-bin 以及 icon 目錄先接起來:

cd /srv/www.example.com/public
sudo ln -s /usr/share/awstats/icon awstats-icon
sudo mkdir cgi-bin
cd cgi-bin
sudo ln -s /usr/lib/cgi-bin/awstats.pl .

然後是 nginx 這邊的設定,我只放 awstats.pl 給 fcgiwrap:

    location /cgi-bin/awstats.pl {
        include fastcgi.conf;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
    }

另外在意的人可以用 nginx 的 auth_basicauth_basic_user_file 指定帳號密碼,擋外部的存取。

過個十分鐘 (或是半小時,如果 access log 比較多,第一次跑比較慢的話) 就可以直接在 https://www.example.com/cgi-bin/awstats.pl 上看到了。

這報表有種懷舊感...

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...

Google SRE 團隊整理出過去二十年的十一條心得

Google 的 SRE 團隊整理出過去二十年的心得,當看故事的心態在看的:「Lessons Learned from Twenty Years of Site Reliability Engineering」,在 Hacker News 上也有討論:「Lessons Learned from Twenty Years of Site Reliability Engineering (sre.google)」。

裡面的項目大多都會在公司成長時不斷的導入,都是夠大就會遇到的。

比較有趣的是第六條,這是唯一一條全部都用大寫字母列出來的:

COMMUNICATION CHANNELS! AND BACKUP CHANNELS!! AND BACKUPS FOR THOSE BACKUP CHANNELS!!!

到 Google 這個規模的架構,這邊就會規劃找完全獨立於 Google 架構的方案來用;我猜應該是傳統的 colocation 機房 (像是 AT&T 之類的),上面跑 IRC server 之類的?

在 Hacker News 上面也有其他人提到 Netflix 也有類似的規劃,需要有一個備援的管道是完全獨立於 AWS 的;另外同一則 comment 裡也有提到 Reddit 的作法是在辦公室裡面放 IRC server 備援:

Yes! At Netflix, when we picked vendors for systems that we used during an outage, we always had to make sure they were not on AWS. At reddit we had a server in the office with a backup IRC server in case the main one we used was unavailable.

IRC 還是很好用的 XD

Ansible 的爭論

前幾天在 Hacker News Daily 上看到「Five Ansible Techniques I Wish I’d Known Earlier」這篇,裡面提到了一些 Ansible 的用法還蠻有用的,算是開始用 Ansible 後應該都會有幫助的用法... 不過 Hacker News 上的討論「Ansible Techniques I Wish I’d Known Earlier (zwischenzugs.com)」比較精彩...

目前在頂端的留言對 Ansible 幹到不行,尤其是那個 YAML 格式:

Ansible is abysmal. I don't know why anyone still chooses it. It's a mess of yaml and what feels like a million yaml files that is always extremely hard to follow. Honestly writing some python, or bash is a lot easier to follow, read, and understand. The only thing it has going for it is the inventory system. I wish ansible would die already.

然後講到 bash 與 python 之類的工具時有人提到 idempotent:

>bash and python
Neither of those of idempotent.

馬上就有人幹勦,大多數人在寫 Ansible playbook 時根本沒人在注意 idempotent,而且一堆 shell script 的東西被塞進 YAML 只能說痛苦 XDDD

Most of the ansible roles I come across written by my team are not idempotent either, its a huge lie that Ansible is idempotent. Its idempotent if you put the effort into make it be but if I see tons of shell or command module invocations without prerequisite checks to see if the work should be done. Most devs I see using Ansible treat it like a shell script written in YAML and to that purpose it sucks.

我自己目前會挑 Ansible 主要還是因為 server 不需要另外裝軟體,是個 production 為導向的設計,再更大的時候就要想一下要怎麼繼續搞下去了...