「抵擋爬蟲」修訂間的差異

出自跨校選修
跳至導覽 跳至搜尋
 
(未顯示同一使用者於中間所作的 24 次修訂)
行 2: 行 2:
 
[[Cloudflare]]頁中有「抵擋爬蟲」的段落
 
[[Cloudflare]]頁中有「抵擋爬蟲」的段落
 
===DS720+ 檢測===
 
===DS720+ 檢測===
 +
==== TCP 交握機制====
 +
<table style='border:none'>
 +
<tr><th colspan=4 style='border:none;font-weight:normal'>TCP 交握過程</th></tr>
 +
<tr><th style='border:none'>Client</th><th style='border:none'></th><th style='border:none;text-align:left'>Server</th><th style='border:none;'>State</th></tr>
 +
<tr><th style='border:none;text-align:right;font-weight:normal;font-size:85%'>SYN</th><th style='border:none;font-size:70%'>--------------------&gt;</th><th style='border:none'></th><th style='border:none;font-weight:normal;font-size:70%'>LISTEN</th></tr>
 +
<tr><th style='border:none'></th><th style='border:none;font-size:70%'>&lt;--------------------</th><th style='border:none;text-align:left;font-weight:normal;font-size:85%'>SYN+ACK</th><th style='border:none;font-weight:normal;font-size:70%'>SYN_RECV</th></tr>
 +
<tr><th style='border:none;text-align:right;font-weight:normal;font-size:85%'>ACK</th><th style='border:none;font-size:70%'>--------------------&gt;</th><th style='border:none'></th><th style='border:none;font-weight:normal;font-size:70%'>ESTABLISHED</th></tr>
 +
<tr><th style='border:none'></th><th style='border:none;font-weight:normal;font-size:70%'>ESTABLISHED</th><th style='border:none'></th></tr>
 +
</table>
 +
# 客戶端送:SYN(Synchronize,同步序號)。意思是:你好,我想建立連線。
 +
# 伺服器回:SYN + ACK(Acknowledgement,確認收到)。意思是:收到你的要求,我也願意建立連線。
 +
# 客戶端回:ACK。意思是:收到你的同意。
 +
# 然後 ESTABLISHED(已確立) 形成正式連線。
 +
各種 TCP 狀態:
 +
# LISTEN:程式正在監聽某個 Port ,等待別人連進來
 +
# SYN_RECV:半完成連線
 +
# ESTABLISHED:TCP 三向交握完成,雙方正在傳輸資料
 +
# FIN_WAIT1:本機想關閉連線,已送出 FIN ,等待對方 ACK 。例如:瀏覽器關閉網頁,通常停留很短。
 +
# FIN_WAIT2:對方已 ACK ,但還沒送 FIN
 +
# LAST_ACK:本機收到對方 FIN ,已回 FIN ,等待最後 ACK
 +
# TIME_WAIT:避免舊封包干擾新連線。Linux 預設會保留:60 秒左右(依系統設定)
 +
 
====找出佔用 CPU 的環節====
 
====找出佔用 CPU 的環節====
 
<ol>
 
<ol>
行 97: 行 119:
 
# netstat -ant | awk '{print $6}' | sort | uniq -c 回應
 
# netstat -ant | awk '{print $6}' | sort | uniq -c 回應
 
       1 established)
 
       1 established)
    23 ESTABLISHED
 
      2 FIN_WAIT1
 
      2 FIN_WAIT2
 
      1 Foreign
 
      2 LAST_ACK
 
    32 LISTEN
 
      3 SYN_RECV
 
    961 TIME_WAIT
 
 
 
 
       1 established)
 
       1 established)

於 2026年6月6日 (六) 20:55 的最新修訂

Cloudflare頁中有「抵擋爬蟲」的段落

DS720+ 檢測

TCP 交握機制

TCP 交握過程
ClientServerState
SYN-------------------->LISTEN
<--------------------SYN+ACKSYN_RECV
ACK-------------------->ESTABLISHED
ESTABLISHED
  1. 客戶端送:SYN(Synchronize,同步序號)。意思是:你好,我想建立連線。
  2. 伺服器回:SYN + ACK(Acknowledgement,確認收到)。意思是:收到你的要求,我也願意建立連線。
  3. 客戶端回:ACK。意思是:收到你的同意。
  4. 然後 ESTABLISHED(已確立) 形成正式連線。

各種 TCP 狀態:

  1. LISTEN:程式正在監聽某個 Port ,等待別人連進來
  2. SYN_RECV:半完成連線
  3. ESTABLISHED:TCP 三向交握完成,雙方正在傳輸資料
  4. FIN_WAIT1:本機想關閉連線,已送出 FIN ,等待對方 ACK 。例如:瀏覽器關閉網頁,通常停留很短。
  5. FIN_WAIT2:對方已 ACK ,但還沒送 FIN
  6. LAST_ACK:本機收到對方 FIN ,已回 FIN ,等待最後 ACK
  7. TIME_WAIT:避免舊封包干擾新連線。Linux 預設會保留:60 秒左右(依系統設定)

找出佔用 CPU 的環節

  1. 監看目前所有程式的執行狀況:top
    • PID: 執行任務的 Process ID
    • USER: 執行任務的使用者是誰
    • PR: 任務的優先度 (Priority)
    • NI: 任務的 Nice Value,負的值代表優先度高,正的值代表優先度低
    • VIRT: 總共用到多少 kB 虛擬記憶體 (Virtual Memory)
    • RES: 實體記憶體 (Resident Size) 大小 kB
    • SHR: 總共用到多少 kB 的共享記憶體 (Shared Memory)
    • S: 狀態 (Status)
      • R 代表執行中
      • D 代表不可中斷睡眠 (不可被 signal 打斷通常在等 I/O)
      • S 代表睡眠 (可被喚醒)
      • T 中斷中或停止,可能是被 SIGSTOPSIGTSTP 停止,或是被 degubber 中斷 (ptrace)
      • Z 代表殭屍,通常發生在 Child 已經執行完,等待 Parent 結束或回收
    • %CPU: 占用到多少 CPU %,注意到一個核心是 100%,所以多核心是可以超過 100% 的
    • %MEM: 占用到多少全部記憶體多少比例
    • TIME+: 已經執行多少時間
    • COMMAND: 任務的指令名稱
  2. 找出目前最吃 CPU 的前 20 個行程:ps aux --sort=-%cpu | head -20
    1. ps aux:列出目前系統中的行程。
    2. --sort=-%cpu:依照 CPU 使用率排序,負號 - 表示由大排到小。
    3. | head -20:顯示前 20 行,因為第一行通常是標題列,所以輸出:標題列 + CPU 使用率最高的 19 個行程。

    常見欄位如下:
    USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    root 1234 85.3 1.2 123456 45678 ? R 10:01 2:33 php-fpm
    mysql 5678 40.1 8.5 987654 345678 ? Sl 09:50 12:10 mariadbd

    各欄大意:
    USER:執行這個行程的使用者
    PID:行程編號
    %CPU:CPU 使用率
    %MEM:記憶體使用率
    VSZ:虛擬記憶體大小
    RSS:實際佔用的實體記憶體
    TTY:連接的終端機
    STAT:行程狀態
    START:啟動時間
    TIME:累積使用 CPU 的時間
    COMMAND:執行的指令

  3. 查連網統計:netstat(Network Statistics)
    常見參數:
    • -a:顯示所有連線與監聽的連接埠。
    • -t:顯示 TCP 協定相關資訊。
    • -u:顯示 UDP 協定相關資訊。
    • -n:以數字形式顯示位址與連接埠(不進行 DNS 反查,速度較快)。
    • -p:顯示佔用該連線的程式名稱與 PID(需具備 root 權限)。
    • -l:僅顯示正在「監聽(Listening)」的服務。

    應用的命令:

    • 「netstat -antp | grep :80」查從 80 進來的工作都在幹嘛
    • 「netstat -tn | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20」
      1. netstat -tn:列出目前的 TCP 網路連線。輸出可能像這樣:
        Proto Recv-Q Send-Q Local Address Foreign Address State
        tcp 0 0 192.168.1.10:80 47.82.8.63:52344 ESTABLISHED
        tcp 0 0 192.168.1.10:443 66.249.66.1:44321 ESTABLISHED
      2. grep ESTABLISHED:只保留 TCP 連線已成功建立,雙方正在或可以傳輸資料的狀態(ESTABLISHED)的連線。排除:LISTEN、TIME_WAIT、CLOSE_WAIT、SYN_SENT、FIN_WAIT等狀態的連線。
      3. awk '{print $5}':取出第 5 欄,也就是遠端位址 Foreign Address。即 47.82.8.63:52344 。
      4. cut -d: -f1:用冒號「:」當分隔符,只取第 1 段。取回 47.82.8.63 。
      5. sort:把 IP 排序,讓相同 IP 排在一起,以便下一步的 uniq -c 能正確統計。
      6. uniq -c:統計連續重複的行數。如「3 47.82.8.63」代表 47.82.8.63 出現 3 次。
      7. sort -nr:依照數字由大到小排序。-n 用數字大小排序;-r 表示反向排序,也就是由大到小。
      8. head -20:只顯示前 20 筆,也就是連線數最多的前 20 個遠端 IP。

      如果你的伺服器前面有 Cloudflare,這個指令看到的遠端 IP 可能會是 Cloudflare 節點 IP,不一定是真正訪客 IP。

  4. 發現是阿里雲上的虛擬伺服器來打爆 DS720+ 。
  5. 封阿里雲常見的掃描來源網段:
    在「DSM / 控制台 / 安全性 / 防火牆 / 防火牆設定檔 / 編輯規則 / 新增」:
    「所有連接埠 | 拒絕 | 特定 IP => IP 範圍:從 47.79.0.0 到 47.79.255.255」。封鎖以下三個阿里雲網段:
    47.79.0.0/16
    47.82.0.0/16
    47.88.0.0/16
  6. 封鎖前後比較:
    狀態封鎖前封鎖後
    ESTABLISHED111527
    CLOSE_WAIT3080
    FIN_WAIT22970
    SYN_SENT920
    CPU50~85%明顯下降
    寫入量很高幾乎歸零

網路請求與交握流程

  1. HTTP

    Apache

    PHP

    MediaWiki

    MariaDB
  2. TCP 的正常流程:ESTABLISHED

    FIN_WAIT

    TIME_WAIT

    消失
  1. http_response_code(503); 能瞬間降低負載。


  1. sudo iostat -xm 1


  1. netstat -ant | awk '{print $6}' | sort | uniq -c 回應
     1 established)

     1 established)
    41 ESTABLISHED
     1 Foreign
    32 LISTEN
   985 TIME_WAIT
  1. 列出 cpu 佔用的前 20 名:「ps aux --sort=-%cpu | head -20」
    發現主要是 mariadbd 和數個 php-fpm worker => 11MB/s 寫入量來自「MediaWiki → PHP → MariaDB」鏈條

檢查儲存裝置被頻繁寫入

發現儲存裝置有 11MB/s 寫入量

  1. 查資料庫請求的增量:「SHOW GLOBAL STATUS LIKE 'Questions';」 60 秒後 再執行一次,看增加多少 => 60 秒增加:76491 => 約 1,275 queries / 秒
  2. 查是哪些請求:「SHOW FULL PROCESSLIST;」秀出運行中的全部請求
    如果太多,先用這個:
    ---------- information_schema 資料庫中的 PROCESSLIST 資料表 ----------
    • SELECT ID,USER,DB,COMMAND,TIME,STATE,LEFT(INFO,300) AS SQL_TEXT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND<>'Sleep' ORDER BY TIME DESC;
      也查資料庫連線來源:
    • SELECT USER,DB,COMMAND,COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY USER,DB,COMMAND ORDER BY COUNT(*) DESC;
    • 查到:
      REPLACE /* SqlBagOStuff::updateTable */ INTO `wiki_objectcache` (keyname,value,exptime) VALUES ('alWiki:messages:zh-tw','………','20380119031407')
    11MB/s 寫入的原因很明確:objectcache 一直被 REPLACE
    ---------- 查快取是否使用 wiki_objectcache ----------
  3. SELECT COUNT(*) FROM wiki_objectcache; 等一分鐘再查一次,如果數量持續增加,是使用 wiki_objectcache
  4. 看 SHOW TABLE STATUS LIKE 'wiki_objectcache'; 中的:
    • Data_length
    • Index_length
    • Update_time
  5. 清快取表:「TRUNCATE TABLE wiki_objectcache;」
  6. sudo synopkg restart MariaDB10 重啟資料庫服務
  7. sudo synopkg restart WebStation 重啟網頁服務
  8. sudo synosystemctl restart pkgctl-WebStation 只重啟 PHP-FPM