Linux 防火牆設定教學:VPS 使用 UFW 與 firewalld(含 IPv6)
新安裝的 Linux 伺服器,任何服務開啟的連接埠都會直接對外回應,因此主機防火牆是最先要設定的項目之一。本文說明如何在 Debian / Ubuntu 用 UFW 設定 Linux 防火牆,以及在 CentOS、Rocky Linux、AlmaLinux 使用 firewalld:先放行 SSH、開放網站連接埠、把敏感服務限制為特定來源 IP、同時保護 IPv6,以及不小心把自己鎖在外面時如何救回。JUSTG 位於約翰尼斯堡、莫斯科、東京、首爾的雲端伺服器都免費提供 IPv6,所以 IPv6 規則和 IPv4 一樣重要。
步驟 1:檢查已開啟的連接埠與 SSH 連接埠
寫規則之前,先確認實際有哪些服務在監聽,以及 SSH 使用哪個連接埠。如果您已把 SSH 改到自訂連接埠,以下所有 SSH 規則都要改用該連接埠,而不是 22。
# Which ports are services actually listening on?
ss -tulpn
# Which port does SSH use?
sshd -T | grep -i '^port'
步驟 2:啟用防火牆前先準備安全網
一條錯誤的規則就可能切斷 SSH 連線。在背景設定一個計時器,時間到就自動關閉防火牆,等於替自己留一條退路。從新的終端機確認仍可登入後,再取消計時器。
# Safety net: turn the firewall off again in 10 minutes unless you cancel it
nohup sh -c 'sleep 600; ufw disable' >/dev/null 2>&1 & # UFW
nohup sh -c 'sleep 600; systemctl stop firewalld' >/dev/null 2>&1 & # firewalld
# Everything works? Cancel the timer:
pkill -f 'sleep 600'
步驟 3:在 Debian / Ubuntu 設定 UFW 防火牆
UFW(Uncomplicated Firewall)是核心防火牆的簡易前端。先把預設政策設為拒絕所有連入,接著優先放行 SSH,最後才啟用防火牆。ufw limit 會允許 SSH,但若同一位址短時間內連線過多次,就暫時封鎖。
apt update && apt install -y ufw
# Make sure IPv6 rules are managed too
grep '^IPV6' /etc/default/ufw # should print IPV6=yes
ufw default deny incoming
ufw default allow outgoing
# SSH FIRST (use your real SSH port if you changed it)
ufw limit 22/tcp # allow + basic brute-force rate limit
# Web server
ufw allow 80,443/tcp
ufw enable # answer "y"
ufw status verbose
步驟 4:用 UFW 限制來源 IP(IPv4 與 IPv6)
資料庫、管理後台與監控代理程式絕不應對整個網際網路開放,只允許已知位址連線即可。UFW 依順序比對規則,因此拒絕規則必須插入在範圍較大的允許規則之前。
# Allow MySQL only from one office IPv4 and one IPv6 network
ufw allow from 198.51.100.25 to any port 3306 proto tcp
ufw allow from 2001:db8:10::/64 to any port 3306 proto tcp
# Block an abusive network (insert at the top so it is matched first)
ufw insert 1 deny from 203.0.113.0/24
# List rules with numbers and delete one
ufw status numbered
ufw delete 4
步驟 5:在 CentOS / Rocky Linux / AlmaLinux 設定 firewalld
firewalld 以「區域(zone)」運作,網路介面通常屬於 public 區域,預設已允許 SSH。加上 --permanent 的規則重開機後仍會保留,但必須執行 --reload 才會生效。
dnf install -y firewalld # CentOS 7: yum install -y firewalld
systemctl enable --now firewalld
firewall-cmd --get-default-zone # usually "public"
# SSH FIRST (or: --add-port=2222/tcp for a custom port)
firewall-cmd --permanent --add-service=ssh
# Web server
firewall-cmd --permanent --add-service=http --add-service=https
# Close what you do not use
firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --reload
firewall-cmd --list-all
--add-port 加入該連接埠,再移除 ssh 服務。在 Rocky 與 AlmaLinux 上,該連接埠也必須在 SELinux 中允許。步驟 6:用 firewalld Rich Rule 限制來源 IP
Rich rule 可以在一行中同時指定來源位址、連接埠與動作。每條規則只適用一種位址族,所以 IPv4 與 IPv6 要各寫一條。
# Allow MySQL from one IPv4 address and one IPv6 network only
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.25" port port="3306" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="2001:db8:10::/64" port port="3306" protocol="tcp" accept'
# Drop all traffic from an abusive network
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" drop'
firewall-cmd --reload
firewall-cmd --list-rich-rules
步驟 7:確認 IPv6 也有被防火牆過濾
常見錯誤是 IPv4 規則寫得很完整,同樣的服務卻在 IPv6 上完全敞開。UFW 只有在 IPV6=yes 時才管理 IPv6(ufw status 會出現「(v6)」規則);firewalld 的區域與服務則自動涵蓋兩種位址。請從另一台機器測試:
# Your server's IPv6 address
ip -6 addr show scope global
# From ANOTHER machine: test a port over IPv4 and IPv6
nc -vz 203.0.113.50 443
nc -vz 2001:db8:50::10 443
nc -vz 2001:db8:50::10 3306 # should fail from a non-allowed address
步驟 8:注意 Docker 對外發布的連接埠
Docker 會自行寫入 iptables 規則,因此用 -p 8080:80 發布的連接埠,即使 UFW 或 firewalld 應該擋下,仍可能被外部存取。建議把容器發布在 127.0.0.1,前面再加反向代理,或自行管理 DOCKER-USER 鏈。
# Publish a container port on localhost only, then proxy it with Nginx
docker run -d -p 127.0.0.1:8080:80 nginx
步驟 9:被防火牆鎖住時如何救回
修改後 SSH 沒有回應時,可先等待步驟 2 的計時器。否則請開啟 VNC 主控台:登入 JUSTG 客戶中心 → 我的產品與服務 → 選擇伺服器 → 管理/控制面板(如找不到主控台可提交工單)。以 root 登入後重新放行 SSH:
# Debian / Ubuntu (UFW)
ufw allow 22/tcp # or: ufw disable
# CentOS / Rocky / AlmaLinux (firewalld)
firewall-cmd --panic-off 2>/dev/null
firewall-cmd --add-service=ssh # runtime only; add --permanent once fixed
# last resort
systemctl stop firewalld
常見問題
UFW 和 firewalld 可以同時使用嗎?
不建議。兩者管理同一組核心規則表,會互相衝突。Debian/Ubuntu 用 UFW,CentOS/Rocky/AlmaLinux 用 firewalld,另一個若有安裝請停用。
為什麼重開機後 firewalld 規則不見了?
因為新增時沒有加 --permanent,只修改了執行中的設定。可執行 firewall-cmd --runtime-to-permanent 把目前規則存成永久設定。
可以封鎖正在攻擊伺服器的 IP 嗎?
可以:UFW 用 ufw insert 1 deny from 203.0.113.66,firewalld 則用帶 drop 的 rich rule。若是大流量攻擊,主機防火牆無法單獨處理,請聯絡技術支援。
如設定 Linux 防火牆時仍遇到問題,請至 https://www.justg.com/submitticket.php 提交工單,JUSTG 技術支援團隊會協助您處理。