Linux利用iptables與firewalld實(shí)現(xiàn)端口訪問(wèn)控制的實(shí)戰(zhàn)指南
前言
在Linux服務(wù)器安全體系中,端口訪問(wèn)控制是基礎(chǔ)而關(guān)鍵的一環(huán)。無(wú)論是保護(hù)數(shù)據(jù)庫(kù)、Web服務(wù)還是API接口,正確的黑白名單配置都能有效防止未授權(quán)訪問(wèn)。然而,從簡(jiǎn)單的iptables命令到復(fù)雜的Docker環(huán)境集成,許多管理員在實(shí)踐中會(huì)遇到各種“坑”。本文將系統(tǒng)性地講解端口訪問(wèn)控制的原理、實(shí)踐和排錯(cuò)方法。
一、核心概念:理解防火墻的工作方式
1.1 iptables三層過(guò)濾體系
iptables工作在Linux內(nèi)核網(wǎng)絡(luò)棧,通過(guò)表和鏈的層級(jí)結(jié)構(gòu)過(guò)濾數(shù)據(jù)包:
數(shù)據(jù)包 → 原始表(PREROUTING) → 過(guò)濾表(FORWARD) → 網(wǎng)絡(luò)地址轉(zhuǎn)換表(POSTROUTING)
↓
過(guò)濾表(INPUT/OUTPUT)
對(duì)于端口訪問(wèn)控制,我們主要操作過(guò)濾表的INPUT鏈,它決定了哪些外部連接可以訪問(wèn)本機(jī)服務(wù)。
1.2 規(guī)則的匹配原則
這是最容易被誤解的部分,請(qǐng)務(wù)必記?。?/p>
iptables規(guī)則從上到下順序匹配,一旦匹配成功就立即執(zhí)行對(duì)應(yīng)動(dòng)作,后續(xù)規(guī)則不再檢查。
這就像公司的門禁系統(tǒng):如果第一條規(guī)則說(shuō)“拒絕所有人進(jìn)入”,那么后面再說(shuō)“允許張三進(jìn)入”就毫無(wú)意義了。
二、iptables實(shí)戰(zhàn):從入門到精通
2.1 基礎(chǔ)命令速查
# 查看規(guī)則(顯示編號(hào)便于管理) iptables -L INPUT -n --line-numbers # 追加規(guī)則到鏈末尾 iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 插入規(guī)則到鏈開(kāi)頭 iptables -I INPUT -p tcp --dport 22 -j ACCEPT # 插入到指定位置(如第3條規(guī)則前) iptables -I INPUT 3 -p tcp --dport 22 -j ACCEPT # 刪除指定規(guī)則 iptables -D INPUT 3 # 清空所有規(guī)則 iptables -F INPUT
2.2 典型白名單配置
讓我們通過(guò)一個(gè)MySQL防護(hù)的完整案例來(lái)理解:
#!/bin/bash
# mysql_whitelist.sh - MySQL端口安全加固腳本
PORT=3306
WHITELIST=("192.168.1.100" "192.168.1.101" "10.0.0.50")
echo "正在配置MySQL端口($PORT)白名單..."
# 步驟1:備份當(dāng)前規(guī)則
iptables-save > /etc/iptables.backup.$(date +%Y%m%d_%H%M%S)
# 步驟2:清除舊規(guī)則(避免重復(fù))
iptables -D INPUT -p tcp --dport $PORT -j DROP 2>/dev/null || true
for ip in "${WHITELIST[@]}"; do
iptables -D INPUT -p tcp --dport $PORT -s $ip -j ACCEPT 2>/dev/null || true
done
# 步驟3:按正確順序添加規(guī)則
# 3.1 允許本地回環(huán)(必須)
iptables -I INPUT -i lo -j ACCEPT
# 3.2 允許已建立的連接(防止斷開(kāi)當(dāng)前會(huì)話)
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 3.3 添加白名單IP
for ip in "${WHITELIST[@]}"; do
iptables -A INPUT -p tcp --dport $PORT -s $ip -j ACCEPT
echo " ? 允許IP: $ip"
done
# 3.4 拒絕其他所有訪問(wèn)(這條規(guī)則必須最后添加!)
iptables -A INPUT -p tcp --dport $PORT -j DROP
echo " ? 拒絕其他所有IP訪問(wèn)"
# 步驟4:保存配置
iptables-save > /etc/sysconfig/iptables
# 步驟5:驗(yàn)證配置
echo -e "\n驗(yàn)證規(guī)則順序:"
iptables -L INPUT -n --line-numbers | grep -E "(dpt:$PORT|policy)"
關(guān)鍵點(diǎn):注意ACCEPT規(guī)則在DROP規(guī)則之前,這是保證白名單生效的前提。
2.3 經(jīng)典錯(cuò)誤案例解析
場(chǎng)景:管理員想先禁止所有訪問(wèn),再開(kāi)放特定IP,結(jié)果白名單失效。
# ? 錯(cuò)誤做法(常見(jiàn)陷阱) iptables -A INPUT -p tcp --dport 3306 -j DROP # 規(guī)則1:拒絕所有 iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.100 -j ACCEPT # 規(guī)則2:允許特定IP(永遠(yuǎn)不會(huì)執(zhí)行!) # ? 正確做法 iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.100 -j ACCEPT # 規(guī)則1:允許特定IP iptables -A INPUT -p tcp --dport 3306 -j DROP # 規(guī)則2:拒絕其他
診斷技巧:
# 查看規(guī)則匹配計(jì)數(shù)器,如果ACCEPT規(guī)則計(jì)數(shù)為0,說(shuō)明從未匹配 iptables -L INPUT -n -v
三、Docker環(huán)境的特殊挑戰(zhàn)
當(dāng)容器技術(shù)遇上防火墻,情況變得復(fù)雜。Docker默認(rèn)會(huì)修改iptables規(guī)則,這可能導(dǎo)致你的配置失效。
3.1 Docker的網(wǎng)絡(luò)管理機(jī)制
Docker啟動(dòng)時(shí)默認(rèn)會(huì):
- 創(chuàng)建
DOCKER、DOCKER-USER、DOCKER-ISOLATION等自定義鏈 - 在
FORWARD鏈中插入跳轉(zhuǎn)規(guī)則 - 為端口映射創(chuàng)建NAT規(guī)則
# 查看Docker創(chuàng)建的鏈 iptables -L -n | grep -i docker # 典型輸出示例: # Chain DOCKER (1 references) # Chain DOCKER-ISOLATION (1 references) # Chain DOCKER-USER (1 references)
3.2 方案一:使用DOCKER-USER鏈(推薦)
Docker 19.03+ 版本引入了DOCKER-USER鏈,專門用于用戶自定義規(guī)則,且不會(huì)被Docker覆蓋。
#!/bin/bash
# docker_whitelist.sh - Docker容器端口白名單
CONTAINER_PORT=80
HOST_PORT=8080
WHITELIST=("192.168.1.100" "192.168.1.0/24")
echo "配置Docker容器端口白名單..."
echo "容器端口: $CONTAINER_PORT, 主機(jī)端口: $HOST_PORT"
# 清空DOCKER-USER鏈(注意:不影響其他Docker規(guī)則)
iptables -F DOCKER-USER
# 添加基礎(chǔ)規(guī)則
iptables -A DOCKER-USER -i lo -j ACCEPT
iptables -A DOCKER-USER -m state --state ESTABLISHED,RELATED -j ACCEPT
# 添加白名單
for ip in "${WHITELIST[@]}"; do
iptables -A DOCKER-USER -p tcp --dport $HOST_PORT -s $ip -j ACCEPT
echo " ? 允許 $ip 訪問(wèn)端口 $HOST_PORT"
done
# 拒絕其他所有訪問(wèn)
iptables -A DOCKER-USER -p tcp --dport $HOST_PORT -j DROP
echo " ? 拒絕其他IP訪問(wèn)"
# 查看結(jié)果
echo -e "\n當(dāng)前DOCKER-USER鏈規(guī)則:"
iptables -L DOCKER-USER -n --line-numbers
3.3 方案二:直接管理INPUT鏈(無(wú)DOCKER鏈時(shí))
如果系統(tǒng)沒(méi)有DOCKER鏈(可能因?yàn)镈ocker配置或版本原因),可以像管理普通服務(wù)一樣操作:
# 檢查是否有DOCKER鏈
if ! iptables -L -n | grep -q "Chain DOCKER"; then
echo "系統(tǒng)無(wú)DOCKER鏈,直接配置INPUT鏈"
# 允許特定IP訪問(wèn)Docker映射的端口
iptables -A INPUT -p tcp --dport 8080 -s 192.168.1.100 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -s 192.168.1.0/24 -j ACCEPT
# 拒絕其他
iptables -A INPUT -p tcp --dport 8080 -j DROP
fi
3.4 方案三:Docker原生限制(簡(jiǎn)單場(chǎng)景)
對(duì)于簡(jiǎn)單的IP限制,可以在運(yùn)行容器時(shí)直接指定:
# 只允許特定IP訪問(wèn) docker run -d \ --name myapp \ -p 192.168.1.100:8080:80 \ nginx # 允許多個(gè)IP訪問(wèn) docker run -d \ --name myapp \ -p 192.168.1.100:8080:80 \ -p 192.168.1.101:8080:80 \ nginx
四、firewalld:現(xiàn)代化的防火墻管理
對(duì)于需要?jiǎng)討B(tài)管理規(guī)則的環(huán)境,firewalld提供了更友好的接口。
4.1 firewalld核心概念
- Zone(區(qū)域):預(yù)定義的信任級(jí)別(public、home、internal等)
- Rich Rule(富規(guī)則):功能強(qiáng)大的規(guī)則語(yǔ)法
- 運(yùn)行時(shí)配置:支持動(dòng)態(tài)修改,無(wú)需重啟服務(wù)
4.2 常用命令示例
# 查看當(dāng)前配置 firewall-cmd --get-default-zone firewall-cmd --list-all # 添加富規(guī)則(永久生效) firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept' # 允許多個(gè)IP firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="22" protocol="tcp" accept' # 添加黑名單 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" reject' # 重新加載(不中斷現(xiàn)有連接) firewall-cmd --reload
4.3 與Docker集成
# 方法1:直接允許端口訪問(wèn) firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="8080" protocol="tcp" accept' # 方法2:使用端口轉(zhuǎn)發(fā)(更靈活) firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="192.168.1.100" forward-port port="8080" protocol="tcp" to-port="80"'
五、高級(jí)優(yōu)化技巧
5.1 使用ipset管理大量IP
當(dāng)白名單包含成百上千個(gè)IP時(shí),使用ipset可以顯著提升性能:
# 創(chuàng)建ipset集合
ipset create mysql_whitelist hash:ip
# 批量添加IP
for ip in {1..100}; do
ipset add mysql_whitelist 192.168.1.$ip
done
# 添加網(wǎng)段
ipset add mysql_whitelist 10.0.0.0/24
# 在iptables中使用
iptables -A INPUT -p tcp --dport 3306 -m set --match-set mysql_whitelist src -j ACCEPT
# 保存配置
ipset save > /etc/ipset.conf
5.2 自動(dòng)化管理腳本
#!/bin/bash
# firewall_manager.sh - 智能防火墻管理
set -euo pipefail
readonly LOG_FILE="/var/log/firewall_manager.log"
readonly BACKUP_DIR="/etc/iptables/backup"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
backup_rules() {
mkdir -p "$BACKUP_DIR"
local backup_file="$BACKUP_DIR/iptables_$(date +%Y%m%d_%H%M%S).rules"
iptables-save > "$backup_file"
log "規(guī)則已備份到: $backup_file"
}
whitelist_port() {
local port=$1
shift
local ips=("$@")
log "開(kāi)始配置端口 $port 白名單"
backup_rules
# 清理舊規(guī)則
iptables -D INPUT -p tcp --dport "$port" -j DROP 2>/dev/null || true
# 添加新規(guī)則
for ip in "${ips[@]}"; do
if ! iptables -C INPUT -p tcp --dport "$port" -s "$ip" -j ACCEPT 2>/dev/null; then
iptables -A INPUT -p tcp --dport "$port" -s "$ip" -j ACCEPT
log "添加白名單: $ip -> 端口 $port"
fi
done
# 添加拒絕規(guī)則(確保在最后)
iptables -A INPUT -p tcp --dport "$port" -j DROP
# 保存
iptables-save > /etc/sysconfig/iptables
log "配置完成"
}
# 使用示例
whitelist_port 3306 "192.168.1.100" "192.168.1.101" "10.0.0.50"
六、故障排查與恢復(fù)
6.1 診斷工具箱
# 1. 檢查規(guī)則順序和匹配計(jì)數(shù) iptables -L INPUT -n -v --line-numbers # 2. 實(shí)時(shí)監(jiān)控規(guī)則匹配 watch -n 1 'iptables -L INPUT -n -v | grep :3306' # 3. 測(cè)試連接并觀察計(jì)數(shù)變化 timeout 5 nc -zv 服務(wù)器IP 3306 && echo "連接成功" || echo "連接失敗" # 4. 查看詳細(xì)日志(如果有LOG規(guī)則) iptables -A INPUT -p tcp --dport 3306 -j LOG --log-prefix "[IPTABLES-DENY] " tail -f /var/log/messages | grep IPTABLES-DENY # 5. 檢查Docker相關(guān)規(guī)則 iptables -t nat -L -n iptables -L FORWARD -n -v
6.2 緊急恢復(fù)方案
如果配置錯(cuò)誤導(dǎo)致自己被鎖定,可以通過(guò)以下方式恢復(fù):
方案A:通過(guò)服務(wù)器控制臺(tái)
# 清空所有規(guī)則(謹(jǐn)慎使用) iptables -F iptables -P INPUT ACCEPT # 或者只恢復(fù)SSH訪問(wèn) iptables -I INPUT -p tcp --dport 22 -j ACCEPT
方案B:使用預(yù)置的恢復(fù)腳本
#!/bin/bash # emergency_recovery.sh - 防火墻緊急恢復(fù) # 創(chuàng)建恢復(fù)標(biāo)記 touch /tmp/firewall_recovery_mode # 設(shè)置寬松策略 iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # 清空所有規(guī)則 iptables -F iptables -t nat -F iptables -t mangle -F # 允許基本服務(wù) iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT echo "緊急恢復(fù)完成,請(qǐng)重新配置防火墻"
6.3 常見(jiàn)問(wèn)題解答
Q1:為什么添加了ACCEPT規(guī)則還是無(wú)法訪問(wèn)?
A:檢查規(guī)則順序,確保ACCEPT在DROP之前;檢查默認(rèn)策略;確認(rèn)端口監(jiān)聽(tīng)正常。
Q2:Docker容器規(guī)則重啟后丟失?
A:Docker重啟會(huì)重建規(guī)則,將自定義規(guī)則放在DOCKER-USER鏈中。
Q3:如何讓iptables規(guī)則永久生效?
# CentOS/RHEL iptables-save > /etc/sysconfig/iptables systemctl enable iptables # Debian/Ubuntu iptables-save > /etc/iptables/rules.v4 apt-get install iptables-persistent
Q4:如何管理大量端口和IP?
A:使用配置管理工具(Ansible/SaltStack)或編寫管理腳本,避免手動(dòng)操作。
七、最佳實(shí)踐總結(jié)
7.1 安全原則
- 最小權(quán)限原則:只開(kāi)放必要的端口給必要的IP
- 默認(rèn)拒絕策略:設(shè)置
iptables -P INPUT DROP,顯式允許 - 分層防護(hù):結(jié)合網(wǎng)絡(luò)層、主機(jī)層、應(yīng)用層防護(hù)
- 變更管理:任何規(guī)則變更前備份、測(cè)試、記錄
7.2 操作規(guī)范
- 使用版本控制:將iptables規(guī)則納入Git管理
- 注釋說(shuō)明:為復(fù)雜規(guī)則添加注釋
iptables -A INPUT -p tcp --dport 3306 -s 10.0.0.50 -j ACCEPT -m comment --comment "允許DBA服務(wù)器訪問(wèn)MySQL"
- 定期審計(jì):每月檢查一次規(guī)則,清理無(wú)效條目
- 監(jiān)控告警:設(shè)置規(guī)則變更告警和異常訪問(wèn)告警
7.3 配置示例模板
#!/bin/bash
# production_firewall_template.sh - 生產(chǎn)環(huán)境防火墻模板
set -e
# 備份
backup_rules() {
iptables-save > /etc/iptables/backup/prod_$(date +%s).rules
}
# 初始化
init_firewall() {
# 設(shè)置默認(rèn)策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 基礎(chǔ)規(guī)則
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ICMP(根據(jù)需要)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
}
# 服務(wù)規(guī)則
setup_services() {
# SSH(限制IP段)
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
# Web服務(wù)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 數(shù)據(jù)庫(kù)(嚴(yán)格白名單)
local db_ips=("192.168.1.100" "192.168.1.101")
for ip in "${db_ips[@]}"; do
iptables -A INPUT -p tcp --dport 3306 -s "$ip" -j ACCEPT
done
iptables -A INPUT -p tcp --dport 3306 -j DROP
}
# 執(zhí)行
backup_rules
init_firewall
setup_services
# 保存
iptables-save > /etc/sysconfig/iptables
echo "防火墻配置完成"
結(jié)語(yǔ)
端口訪問(wèn)控制是Linux系統(tǒng)安全的基石,但也是一把雙刃劍。配置得當(dāng),它能有效阻擋攻擊;配置失誤,可能導(dǎo)致服務(wù)中斷。掌握iptables和firewalld的核心原理,遵循最佳實(shí)踐,結(jié)合自動(dòng)化工具,你就能構(gòu)建既安全又可靠的防火墻體系。
記?。?strong>測(cè)試、備份、漸進(jìn)式變更是防火墻管理的三大黃金法則。每次變更前問(wèn)自己三個(gè)問(wèn)題:
- 這個(gè)規(guī)則真的必要嗎?
- 會(huì)不會(huì)阻斷正常業(yè)務(wù)?
- 如果出問(wèn)題,如何快速恢復(fù)?
安全之路,始于足下。從正確配置第一個(gè)端口白名單開(kāi)始,逐步構(gòu)建完善的防御體系。
以上就是Linux端口訪問(wèn)控制iptables與firewalld的實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于Linux端口訪問(wèn)控制iptables與firewalld的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
銀河麒麟4.0.2(Ubuntu)擴(kuò)展boot分區(qū)過(guò)程介紹
大家好,本篇文章主要講的是銀河麒麟4.0.2(Ubuntu)擴(kuò)展boot分區(qū)過(guò)程介紹,感興趣的同學(xué)快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下哦2021-11-11
阿里云ECS實(shí)例設(shè)置用戶root密碼和遠(yuǎn)程連接的方法
這篇文章主要介紹了阿里云ECS實(shí)例設(shè)置用戶root密碼和遠(yuǎn)程連接的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
一文詳解Linux三種網(wǎng)絡(luò)設(shè)置方式
我們?cè)谑褂锰摂M機(jī)搭建linux系統(tǒng)后,常常需要設(shè)置系統(tǒng)網(wǎng)絡(luò)連接,以方便系統(tǒng)進(jìn)行上網(wǎng)或其他系統(tǒng)連接系統(tǒng)進(jìn)行操作,在linux中網(wǎng)絡(luò)連接分了三類:橋接模式,僅主機(jī)模式,NAT模式,本文我們將對(duì)這三種模式進(jìn)行講解,感興趣的同學(xué)可以參考閱讀2023-06-06
Linux進(jìn)程狀態(tài)和優(yōu)先級(jí)的用法及說(shuō)明
文章詳細(xì)介紹了操作系統(tǒng)中進(jìn)程狀態(tài)(運(yùn)行、阻塞、掛起)的概念及Linux操作系統(tǒng)中的具體狀態(tài)(R、S、D、T、t、X、Z),解釋了進(jìn)程的運(yùn)行、阻塞、掛起狀態(tài)的區(qū)別,具體狀態(tài)標(biāo)識(shí)及操作方法,如使用kill命令或Ctrl+C中斷進(jìn)程等2026-04-04
Linux使用systemctl?restart?network重啟網(wǎng)卡時(shí)報(bào)錯(cuò)的解決方案
在Linux系統(tǒng)中,重啟網(wǎng)卡時(shí)遇到錯(cuò)誤可能是由于network服務(wù)與NetworkManager服務(wù)沖突,解決方法是先停止NetworkManager服務(wù),然后再重啟網(wǎng)卡2025-10-10
linux系統(tǒng)下部署項(xiàng)目訪問(wèn)報(bào)404錯(cuò)誤的解決方法
這篇文章主要為大家詳細(xì)介紹了linux系統(tǒng)下部署項(xiàng)目訪問(wèn)報(bào)404錯(cuò)誤的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
阿里云OSS訪問(wèn)權(quán)限配置(RAM權(quán)限控制)實(shí)現(xiàn)
這篇文章主要介紹了阿里云OSS訪問(wèn)權(quán)限配置(RAM權(quán)限控制)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08

