獲取 Cloudflare IP 列表
在設定防火牆之前,必須先取得 Cloudflare 官方提供的 IP 位段。這包含 IPv4 與 IPv6 兩個部分。你可以直接從 Cloudflare 官網查看,或是使用 curl 指令在終端機抓取。
使用 UFW 設定步驟
UFW 是 Ubuntu 內建較簡單的防火牆工具。設定的邏輯是先拒絕所有連入 80 與 443 埠的流量,再逐一放行 Cloudflare 的 IP。
首先,確保你的 SSH 連線(通常是 22 埠)已經放行,否則你會把自己鎖在伺服器外:
sudo ufw allow 22/tcp
接著,利用迴圈將 Cloudflare 的 IP 加入允許清單:
# 允許 IPv4
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do sudo ufw allow from $ip to any port 80,443 proto tcp; done
# 允許 IPv6
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do sudo ufw allow from $ip to any port 80,443 proto tcp; done
最後啟用防火牆並檢查狀態:
sudo ufw enable
sudo ufw status
使用 iptables 設定方式
如果你偏好使用 iptables,原理相同,即針對特定的來源 IP 開放目的連接埠。
# 允許 IPv4
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do sudo iptables -I INPUT -p tcp -s $ip --dport 80 -j ACCEPT; sudo iptables -I INPUT -p tcp -s $ip --dport 443 -j ACCEPT; done
請注意,iptables 的設定在重啟後會失效,建議安裝 iptables-persistent 來儲存規則。
自動化更新腳本
Cloudflare 的 IP 偶爾會變動。為了避免失效,建議將上述指令寫成一個 shell 腳本,並利用 crontab 設定每週執行一次。這樣當 Cloudflare 增加新機房時,你的防火牆規則也會自動同步,確保網站服務不會中斷。
如何設定 crontab 來定期自動執行這些指令?
建立自動化更新腳本
為了確保防火牆規則永遠跟隨 Cloudflare 的最新 IP 清單,我們可以寫一個簡單的腳本。請在你的家目錄建立一個檔案,例如叫 update_cf_ips.sh。
#!/bin/bash
# 先刪除現有的 Cloudflare UFW 規則(可選,或直接覆蓋)
# 這裡建議直接執行允許指令,UFW 會自動處理重複的規則
# 下載最新的 IPv4 並加入 UFW
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo ufw allow from $ip to any port 80,443 proto tcp
done
# 下載最新的 IPv6 並加入 UFW
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
sudo ufw allow from $ip to any port 80,443 proto tcp
done
# 重新載入防火牆
sudo ufw reload
儲存後,記得給予執行權限:
chmod +x update_cf_ips.sh
設定 Crontab 定期執行
接著我們使用 crontab 讓系統每週一凌晨三點自動執行這個腳本。
輸入以下指令進入編輯介面:
sudo crontab -e
在檔案最後面加入這行(請將路徑替換成你實際存放腳本的位置):
0 3 * * 1 /home/youruser/update_cf_ips.sh > /dev/null 2>&1
驗證規則是否生效
設定完成後,你可以從外部直接輸入你的伺服器 IP(而非網域名稱)來測試。如果防火牆運作正常,瀏覽器應該會顯示連線逾時,因為你的個人電腦 IP 不在 Cloudflare 的允許清單內。只有透過 Cloudflare 代理的流量才能順利讀取網頁。
使用對象與權限的區別
sudo crontab -e 是用來編輯個別使用者的排程。即便你加上 sudo,它通常也是針對 root 這個帳號的個人排程。每個使用者都有自己的 crontab 檔案,這些檔案存放在特定的系統目錄下,不建議直接手動改動。
vi /etc/crontab 則是編輯系統層級的排程。這是一個純文字檔,通常只有系統管理員會去動它。這裡定義的是整個系統要跑的任務,而不是針對某個特定的人。
格式上的關鍵不同
這兩者在語法上最大的差別在於有沒有使用者欄位。
在 sudo crontab -e 裡面,每一行只有五個時間參數加上指令。因為系統已經知道這是 root 的排程,所以不需要再特別註明由誰執行。
在 /etc/crontab 裡面,時間參數後面必須多加一個欄位,指定要用哪個帳號執行指令。例如你想用 root 權限跑程式,就得在指令前寫上 root。如果漏掉這個欄位,排程就不會動。
安全性與自動檢查
使用 crontab -e 有一個很大的好處,就是它會幫你檢查語法。如果你寫錯了,儲存離開時它會提醒你,甚至不讓你存檔。這可以避免因為一個小空格打錯,導致所有排程失效。
直接用 vi 修改 /etc/crontab 就沒有這種防護機制。如果你打錯字或格式不對,系統不會報錯,但任務就是不會執行。對於新手來說,用指令編輯會安全很多。
環境變數的設定
/etc/crontab 是一個設定檔,裡面通常會預設好 PATH 等環境變數。這讓管理系統任務變得比較直觀。
個別使用者的 crontab 往往比較乾淨,環境變數可能跟你的 shell 環境不太一樣。所以寫個人排程時,建議指令都要寫絕對路徑,才不會發生找不到程式的情況。