目錄
安全管理
一、SELinux安全上下文
1、SELinux 簡介
2、基礎操作命令
1. 查看SELinux狀態
2. 切換工作模式*
3、安全上下文(Security Context)
1. 查看上下文*
2. 修改上下文
chcon命令
semanage 命令
4、SELinux布爾值(Booleans)
5、日志分析與故障排除
1. 查看SELinux日志
2. 生成解決方案建議
6、常見問題與解決方案
場景1:Web服務器無法訪問文件
場景2:服務無法綁定非標準端口
7、注意事項
8、練習與測試
二、Linux防火墻-Firewalld
1、 概述
2、 Linux防火墻
防火墻結構
firewalld防火墻
區域分類
區域功能
firewall-cmd命令用法
3、 課后實驗
實驗拓撲
實驗拓撲
實驗要求
**注意 : 該實驗只需要配置指定策略即可,不用驗證!!!**
三、Linux防火墻-Iptables
1、 Iptables概述
2、 Iptables 組成
表(Table)
鏈(Chain)
鏈表對應關系
數據包過濾的匹配流程
規則匹配策略
3、 Iptables防火墻配置
iptables命令
常用管理選項
常用控制類型
匹配條件
命令操作
添加新的規則
查看規則
刪除規則
清空規則
修改規則
4、 規則的匹配
1、通用匹配
2、隱含匹配
協議端口匹配
tcp標記匹配 [了解]
ICMP類型匹配
3、顯式匹配
多端口匹配
ip范圍匹配
mac地址匹配【了解】
狀態匹配【了解】
常見的連接狀態
5、Iptables配置NAT地址轉換
1、 配置SNAT
應用場景
模擬實驗環境
轉換為固定公網ip
轉換為非固定的公網ip(動態)
2、配置DNAT
應用場景
模擬實驗環境
轉換為私網ip
6、iptables防火墻策略的備份和恢復
實驗
實驗拓撲
網絡規劃
實驗要求
8、實驗具體步驟:
一、環境準備(虛擬機基礎配置)
1. 禁用 firewalld 并安裝 iptables
2. 配置網卡與 IP 轉發(同 firewalld 方案)
二、實驗功能實現(防火墻 sf1 配置)
1. 需求 1:pc1 通過 SNAT 訪問外網,但無法 ping 內網網關
2. 需求 2:服務器 s1 通過 DNAT 發布服務到外網
3. 需求 3:pc2 可訪問 s1 服務,但無法 ping/ssh 連接
三、驗證步驟
四、關鍵配置分析
五、故障排查命令
安全管理
一、SELinux安全上下文
1、SELinux 簡介
-
是什么? SELinux(Security-Enhanced Linux)是Linux內核的強制訪問控制(MAC)安全子系統,提供更細粒度的權限控制,防止進程或用戶越權操作。
-
核心思想
-
最小權限原則:進程/用戶只能訪問其明確需要的資源。
-
基于標簽的訪問控制:所有資源(文件、端口、進程)被賦予安全上下文(Security Context)。
-
工作模式(*)
模式 描述 Enforcing 強制執行策略,拒絕非法操作并記錄日志。 Permissive 僅記錄違規操作,不阻止(用于調試)。 Disabled 完全關閉SELinux(需重啟生效)。
2、基礎操作命令
1. 查看SELinux狀態
getenforce# 查看當前模式 sestatus# 詳細狀態(模式/策略類型)
2. 切換工作模式*
setenforce 0# 切換到Permissive模式 setenforce 1# 切換到Enforcing模式
注意:setenforce僅臨時生效,永久修改需編輯 /etc/selinux/config 文件。
3、安全上下文(Security Context)
1. 查看上下文*
ls -Z /var/www/html # 查看文件/目錄的上下文 ps -Z -C httpd# 查看進程的上下文
2. 修改上下文
chcon命令
選項 | 說明 | 示例消息 |
---|---|---|
-t, --type TYPE | 設置安全上下文的類型部分 | 已將 file.txt 的類型更改為 httpd_sys_content_t |
-u, --user USER | 設置安全上下文的用戶部分 | 已將 file.txt 的用戶更改為 system_u |
-r, --role ROLE | 設置安全上下文的角色部分 | 已將 file.txt 的角色更改為 object_r |
--reference=FILE | 使用指定文件的安全上下文 | 已從 ref_file 復制上下文到 target_file |
-R, --recursive | 遞歸處理文件和目錄 | 已遞歸更改 dir/ 及其內容的上下文 |
-h, --help | 顯示幫助信息 | 顯示幫助菜單 |
-v, --verbose | 顯示操作詳情 | 正在更改 file.txt 的安全上下文 |
--version | 顯示版本信息 | chcon (GNU coreutils) 8.32 |
選項使用案例
-
設置文件類型 將 /var/www/html/index.html 的上下文類型設為 httpd_sys_content_t:
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
-
設置用戶部分 將 /etc/nginx/nginx.conf 的用戶部分設為 system_u:
sudo chcon -u system_u /etc/nginx/nginx.conf
-
設置角色部分 將 /home/user/file.txt 的角色部分設為 object_r:
sudo chcon -r object_r /home/user/file.txt
-
參照文件上下文 將 file2 的上下文設置為與 file1 一致:
sudo chcon --reference=file1 file2
-
遞歸操作目錄 遞歸修改 /var/www/html/ 目錄下所有文件的上下文類型:
sudo chcon -R -t httpd_sys_content_t /var/www/html/
-
顯示幫助信息
chcon --help
-
顯示版本信息
chcon --version
-
詳細模式操作 啟用詳細輸出,修改 ~/.ssh/config 的上下文類型:
sudo chcon -v -t ssh_home_t ~/.ssh/config
說明:
-
實際執行時,若未添加 -v 參數,chcon 默認不輸出成功信息,僅在出錯時顯示錯誤。
-
使用 -v 參數可查看操作詳情(如上述表格中的“示例消息”)。
chcon -t httpd_sys_content_t /var/www/html/index.html # 臨時修改文件類型 restorecon -v /var/www/html/index.html # 恢復默認上下文
semanage 命令
子命令/選項 | 用途說明 | 常用選項 | 示例消息/操作 |
---|---|---|---|
semanage login | 管理SELinux用戶與Linux賬戶的映射關系 | -a (添加)、-d (刪除)、-m (修改) | 將用戶 user1 映射到 SELinux 用戶 staff_u |
semanage user | 管理SELinux用戶及其角色和權限 | -a、-d、-R (角色)、-L (限制) | 創建新SELinux用戶 web_user 并分配角色 httpd_role |
semanage port | 管理網絡端口與SELinux類型的綁定關系 | -a、-d、-t (類型)、-p (協議) | 將TCP端口 8080 綁定到 http_port_t 類型 |
semanage interface | 管理網絡接口與SELinux類型的綁定關系 | -a、-d、-t | 將接口 eth1 綁定到 netif_t 類型 |
semanage module | 管理SELinux策略模塊(啟用/禁用) | -a、-d、-e (啟用)、-D (禁用) | 啟用策略模塊 my_custom_module |
semanage fcontext | 管理文件/目錄的默認SELinux上下文規則 | -a、-d、-t、-s (范圍) | 添加規則:/webapps(/.*)? 的上下文類型為 httpd_sys_content_t |
semanage boolean | 管理SELinux布爾值(開關策略功能) | -1 (查看)、--on、--off | 啟用布爾值 httpd_can_network_connect |
semanage dontaudit | 管理dontaudit規則(是否記錄特定訪問拒絕事件) | --on、--off | 關閉對 sshd 的 dontaudit 規則 |
-h / --help | 顯示幫助信息 | - | 顯示子命令的幫助菜單 |
-v / --verbose | 顯示詳細操作信息 | - | 顯示添加端口 8080 的詳細過程 |
-n / --noheading | 輸出時隱藏列標題 | - | 僅顯示端口列表數據,無標題行 |
選項使用案例
-
管理端口綁定
將TCP端口 8080 標記為HTTP服務端口:
sudo semanage port -a -t http_port_t -p tcp 8080
說明:允許Apache等HTTP服務使用8080端口。
-
管理文件上下文規則
為自定義Web目錄 /opt/webapps 設置默認上下文:
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/webapps(/.*)?" sudo restorecon -Rv /opt/webapps
說明:添加規則后需運行 restorecon 立即生效。
-
管理SELinux用戶映射
將Linux用戶 dev_user 映射到SELinux用戶 user_u:
sudo semanage login -a -s user_u dev_user
說明:限制用戶 dev_user 的SELinux權限。
-
啟用布爾值
允許HTTP服務訪問網絡:
sudo semanage boolean --on httpd_can_network_connect
說明:無需重啟服務,立即生效。
-
管理策略模塊
禁用自定義策略模塊 mymodule:
sudo semanage module -D mymodule
說明:禁用后相關規則不再生效。
-
查看當前端口綁定
列出所有HTTP相關端口:
semanage port -l | grep http_port_t
輸出示例:
http_port_t ? tcp ? 80, 443, 8080
-
刪除文件上下文規則
移除對 /tmp/custom_dir 的上下文規則:
sudo semanage fcontext -d "/tmp/custom_dir(/.*)?"
注意事項
-
權限要求:大多數操作需 sudo 或 root 權限。
-
持久化存儲:semanage 修改的規則會保存到策略庫(默認路徑 /etc/selinux/targeted),重啟后仍有效。
-
結合工具使用:修改文件上下文后,需運行 restorecon 或重啟服務使更改生效。
4、SELinux布爾值(Booleans)
SELinux策略通過布爾值動態調整權限控制(例如允許Apache訪問用戶家目錄)。
getsebool -a | grep httpd# 查看所有與Apache相關的布爾值 setsebool -P httpd_enable_homedirs=on # 啟用布爾值(-P永久生效)
5、日志分析與故障排除
1. 查看SELinux日志
tail -f /var/log/audit/audit.log # 直接查看原始日志 ausearch -m AVC -ts recent# 使用工具過濾日志
2. 生成解決方案建議
grep "avc: denied" /var/log/audit/audit.log | audit2allow -M mypolicy semodule -i mypolicy.pp# 編譯并加載自定義策略
6、常見問題與解決方案
場景1:Web服務器無法訪問文件
-
現象:Apache返回403錯誤,但文件權限正常。
-
解決:
-
檢查文件上下文:ls -Z /var/www/html
-
修復上下文:restorecon -Rv /var/www/html
-
場景2:服務無法綁定非標準端口
-
現象:Nginx無法監聽8080端口。
-
解決:
semanage port -a -t http_port_t -p tcp 8080# 添加端口到SELinux策略
7、注意事項
-
不要隨意禁用SELinux:優先使用Permissive模式調試。
-
謹慎使用chcon:錯誤修改上下文可能導致系統不穩定。
-
備份策略:修改策略前備份 /etc/selinux 目錄。
8、練習與測試
-
將SELinux切換為Permissive模式,測試服務異常是否由SELinux引起。
-
使用audit2why分析日志,生成解決方案并應用。
-
為FTP服務配置允許上傳文件到自定義目錄。
推薦工具:
-
sealert:生成更友好的日志分析報告。
-
semanage:管理SELinux策略(需安裝policycoreutils-python-utils)。
二、Linux防火墻-Firewalld
1、 概述
按表現形式劃分:
軟件防火墻: 集成在系統內部,Linux系統: iptables、firewalld、ufw; windows系統下: windows defender
硬件防火墻: 華為防火墻、思科防火墻、奇安信防火墻、深信服防火墻等
按技術劃分:
包過濾防火墻: 檢查數據包的源IP、目的IP、源端口、目的端口、TCP的syn控制位
七層防火墻:除了上述檢查外,還會檢查數據內容
防火墻的作用:
阻止來自網絡外部的攻擊、進行流量控制
2、 Linux防火墻
防火墻結構
用戶態:
iptables: 使用iptables命令對防火墻規則進行管理,必須深度理解網絡技術和四表五鏈,對于初學者或者網絡技術不達標的人員不友好
firewalld:使用firewall-cmd命令對防火墻進行管理,采用的是區域劃分的形式。不需要連接底層的四表五鏈,對于初學者比較友好
ufw: 使用ufw命令對防火墻進行管理,命令簡單易懂。
內核態:
四表: 從內核->用戶的順序: raw -> mangle -> nat -> filter
五鏈: input、output、forward、prerouting、postrouting
firewalld防火墻
區域分類
九大區域: block、dmz、drop、external、home、internal、public、trusted、work
區域功能
public:公共區域,默認區域
public (active) target: default #區域類型規則 icmp-block-inversion: no interfaces: ens33 #屬于該區域的接口 sources:#來源 services: dhcpv6-client ssh #放行服務的名稱 ports:#放行端口號 protocols:#放行協議 masquerade: no#NAT地址轉換 forward-ports:#轉發端口 source-ports:#源端口 icmp-blocks:#ICMP的阻塞類型,ping的阻塞 rich rules:#富規則
home: 家庭區域
home target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
work: 工作區域
work target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
trusted: 完全信任區域
trusted target: ACCEPT#不采用默認規則,放行一切 icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
internal: 內部區域 (連接內部網絡)
internal target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
external: 外部區域 (連接外部網絡,例如: internet網絡)
ternal target: default icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: masquerade: yes#默認進行NAT地址轉換 forward-ports: source-ports: icmp-blocks: rich rules:
dmz: 非軍事化管理區域(內部的服務器放于該區域)
dmz target: default icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
drop: 丟棄區域(丟棄一切流量,不給出任何回應)
drop target: DROP icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
block: 阻塞區域 (拒絕任何流量,但給出回應)
block target: %%REJECT%% icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
firewall-cmd命令用法
關鍵字:
--list-* --get-* --set-* --add-* --remove-* --change-* --zone=
命令分類:
查看:
#查看所有區域的詳細信息 [root@localhost ~]# firewall-cmd --list-all-zones #查看指定區域的詳細信息 [root@localhost ~]# firewall-cmd --list-all --zone=public #查看指定區域的放行服務 [root@localhost ~]# firewall-cmd --list-services --zone=public #查看指定區域的放行端口 [root@localhost ~]# firewall-cmd --list-ports --zone=public #查看指定區域包含的網絡接口 [root@localhost ~]# firewall-cmd --list-interfaces --zone=public #查看指定區域的放心協議 [root@localhost ~]# firewall-cmd --list-protocols --zone=public #查看指定區域的ICMP阻塞類型 [root@localhost ~]# firewall-cmd --list-icmp-blocks --zone=public #查看指定區域的放行源地址 [root@localhost ~]# firewall-cmd --list-sources --zone=public #查看指定區域的源端口 [root@localhost ~]# firewall-cmd --list-source-ports --zone=public #查看指定區域的富規則 [root@localhost ~]# firewall-cmd --list-rich-rules --zone=public #查看指定區域的轉發端口 [root@localhost ~]# firewall-cmd --list-forward-ports --zone=public #查看firewalld支持的服務類型 [root@localhost ~]# firewall-cmd --get-services #查看firewalld的默認區域 [root@localhost ~]# firewall-cmd--get-default-zone #查看firewalld支持的ICMP的阻塞類型 [root@localhost ~]# firewall-cmd--get-icmptypes #查看firewalld所有的活動區域 [root@localhost ~]# firewall-cmd --get-active-zones #查看指定網絡接口所屬區域 [root@localhost ~]# firewall-cmd --get-zone-of-interface=ens33 #查看所有區域名稱 [root@localhost ~]# firewall-cmd --get-zones
添加:
#添加指定服務到指定區域 [root@localhost ~]# firewall-cmd --add-service=http --zone=public success #添加端口到指定區域 [root@localhost ~]# firewall-cmd --add-port=80/tcp --zone=public success #添加指定協議到指定區域 [root@localhost ~]# firewall-cmd --add-protocol=ah --zone=public success #添加ICMP阻塞類型到指定區域 [root@localhost ~]# firewall-cmd --add-icmp-block=echo-request --zone=public success #windows端驗證 C:\Users\zzh>ping 192.168.115.129 ? 正在 Ping 192.168.115.129 具有 32 字節的數據: 來自 192.168.115.129 的回復: 無法訪問目標主機。 來自 192.168.115.129 的回復: 無法訪問目標主機。 來自 192.168.115.129 的回復: 無法訪問目標主機。 #添加指定網絡接口到指定區域 [root@localhost ~]# firewall-cmd --add-interface=ens33 --zone=work success #添加指定區域的放行源地址 [root@localhost ~]# firewall-cmd --add-source=192.168.1.0/24 --zone=work success #添加指定區域的放行源端口 [root@localhost ~]# firewall-cmd --add-source-port=999/tcp --zone=work success #添加轉發端口到指定區域 [root@localhost ~]# firewall-cmd --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=192.168.115.115 --zone=work success #添加地址轉換功能到指定區域 [root@localhost ~]# firewall-cmd --add-masquerade --zone=work success #驗證添加 [root@localhost ~]# firewall-cmd --list-all --zone=public
修改:
#修改默認區域 [root@localhost ~]# firewall-cmd --set-default-zone=work success #修改網絡接口所屬區域 [root@localhost ~]# firewall-cmd --change-interface=ens33 --zone=internal success [root@localhost ~]# firewall-cmd --change-zone=ens33 --zone=external success #追加指定區域的放行源地址 [root@localhost ~]# firewall-cmd --change-source=192.168.2.0/24 --zone=work success
刪除:
#刪除指定服務到指定區域 [root@localhost ~]# firewall-cmd --remove-service=http --zone=public success #刪除端口到指定區域 [root@localhost ~]# firewall-cmd --remove-port=80/tcp --zone=public success #刪除指定協議到指定區域 [root@localhost ~]# firewall-cmd --remove-protocol=ah --zone=public success #刪除ICMP阻塞類型到指定區域 [root@localhost ~]# firewall-cmd --remove-icmp-block=echo-request --zone=public success #刪除指定網絡接口到指定區域 [root@localhost ~]# firewall-cmd --remove-interface=ens33 --zone=work success #刪除指定區域的放行源地址 [root@localhost ~]# firewall-cmd --remove-source=192.168.1.0/24 --zone=work success #刪除指定區域的放行源端口 [root@localhost ~]# firewall-cmd --remove-source-port=999/tcp --zone=work success #刪除轉發端口到指定區域 [root@localhost ~]# firewall-cmd --remove-forward-port=port=8080:proto=tcp:toport=80:toremover=192.168.115.115 --zone=work success #刪除地址轉換功能到指定區域 [root@localhost ~]# firewall-cmd --remove-masquerade --zone=work success #驗證刪除 [root@localhost ~]# firewall-cmd --list-all --zone=public
保存規則:
#逐行規則保存 [root@localhost ~]# firewall-cmd --remove-masquerade --zone=work --permanent #一次性保存所有規則 [root@localhost zones]# firewall-cmd --runtime-to-permanent success #保存的規則存儲路徑 /etc/firewalld/zones
案例:
禁止外部主機ping本機
#本機IP:192.168.115.129 ens33 NAT #外部IP:192.168.115.128 #防火墻配置 [root@localhost ~]# firewall-cmd --add-interface=ens33 --zone=work success [root@localhost ~]# firewall-cmd --add-icmp-block=echo-request --zone=work success #驗證 [root@localhost ~]# ping -c 4 192.168.115.129 PING 192.168.115.129 (192.168.115.129) 56(84) bytes of data. From 192.168.115.129 icmp_seq=1 Destination Host Prohibited From 192.168.115.129 icmp_seq=2 Destination Host Prohibited From 192.168.115.129 icmp_seq=3 Destination Host Prohibited From 192.168.115.129 icmp_seq=4 Destination Host Prohibited ? --- 192.168.115.129 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3001ms
允許外部主機訪問本機的http服務
#本機IP:192.168.80.128 ens34 vmnet3 #外部IP:192.168.80.129 #######環境配置 開始######### ##本機安裝httpd服務 #改變SElinux的規則 [root@localhost ~]# setenforce 0 [root@localhost ~]# yum install -y httpd ##啟動httpd服務 [root@localhost ~]# systemctl start httpd ##修改httpd服務的監聽IP [root@localhost ~]# vim /etc/httpd/conf/httpd.conf Listen 192.168.80.128:80 ##重啟httpd服務 [root@localhost ~]# systemctl restart httpd ##驗證服務監聽狀態 [root@localhost ~]# netstat -naptu | grep :80 tcp00 192.168.80.128:800.0.0.0:* LISTEN5884/httpd #######環境配置 結束######### #防火墻配置 [root@localhost ~]# firewall-cmd --change-interface=ens34 --zone=dmz success ##客戶端驗證訪問## [root@localhost ~]# curl 192.168.80.128 curl: (7) Failed connect to 192.168.80.128:80; 拒絕連接 ##發現無法訪問### #服務端查看dmz區域信息 [root@localhost ~]# firewall-cmd --list-all --zone=dmz dmz (active) target: default icmp-block-inversion: no interfaces: ens34 sources: services: ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: #發現沒有放心http服務 #配置dmz區域http服務放行策略 [root@localhost ~]# firewall-cmd --add-service=http --zone=dmz success dmz (active) target: default icmp-block-inversion: no interfaces: ens34 sources: services: http ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
允許外部主機訪問本機的某個端口號
#前置環境如上 #防火墻配置 [root@localhost ~]# firewall-cmd --add-port=801/tcp --zone=dmz success #放行服務的本質實際上是放行了該服務的默認端口號!!! #假如服務改變了監聽端口號,只需放行對應的端口號即可!!! #客戶端驗證 [root@localhost ~]# curl 192.168.80.128:801?
三、Linux防火墻-Iptables
1、 Iptables概述
Iptables 是一個用戶空間程序,可以用于設置和管理 Linux 操作系統的內核級防火墻。它通過表、鏈和規則組成,可以靈活地根據不同的需求進行配置。
iptables 具有以下特點:
-
Iptables 作為內核級別的防火墻,具有高效、穩定、安全等優點。
-
Iptables 的表、鏈、規則結構非常靈活,可適應各種不同的網絡環境和應用場景。
-
Iptables 相對于其他防火墻工具而言比較容易學習和掌握,并且拓展性非常強。
2、 Iptables 組成
Iptables 的核心是由表(table)、鏈(chain)和規則(rule)三部分組成的。
表(Table)
在 iptables 中,表是一個規則的集合,每個表都包含若干個鏈和一些相關的規則。常用的五種 table 如下:
-
raw表:確定是否對該數據包進行狀態跟蹤。包含兩個規則鏈,OUTPUT、PREROUTING。
-
mangle表:修改數據包內容,用來做流量整形的,給數據包設置標記。包含五個規則鏈,INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING。
-
nat表:負責網絡地址轉換,用來修改數據包中的源、目標IP地址或端口。包含三個規則鏈,OUTPUT、PREROUTING、POSTROUTING。
-
filter表:負責過濾數據包,確定是否放行該數據包(過濾)。包含三個規則鏈,INPUT、FORWARD、OUTPUT。
表之間的優先級
數據包到達防火墻時,規則表之間的優先順序 ? raw > mangle > nat > filter
鏈(Chain)
在 iptables 中,鏈是一個規則的集合,每個鏈都包含一些相關聯的規則。
-
INPUT鏈: 當接收到防火墻本機地址的數據包(入站)時,應用此鏈中的規則。
-
OUTPUT鏈: 當防火墻本機向外發送數據包(出站)時,應用此鏈中的規則。
-
FORWARD鏈: 當接收到需要通過防火墻發送給其他地址的數據包(轉發)時,應用此鏈中的規則。
-
PREROUTING鏈: 在對數據包作路由選擇之前,應用此鏈中的規則,用來修改目的地址,如DNAT。
-
POSTROUTING鏈: 在對數據包作路由選擇之后,應用此鏈中的規則,用來修改源地址,如SNAT,端口映射等。
鏈表對應關系
數據包過濾的匹配流程
-
入站
入站數據包從A網絡發到B網絡,首先發到防火墻,先后順序經過有PREROUTING鏈的三個表(raw、mangle、nat),如果都是放通狀態的會經過路由選擇,然后根據目的地址一層一層往上送,經過有INPUT的兩個表(mangle、filter),一直送到應用程序。
-
轉發
目的地不是本機,數據包先從A網絡過濾,經過PREROUTING鏈,看是否是自己的目的地址,如果是外網到內網需要用nat轉換成內網IP,找到內網用戶,經過FORWARD鏈進行過濾,允許放通的到達POSTROUING鏈,再把內網地址轉換成公網,這樣數據包才能回去;如果是內網往外網發順序就是反過來。
-
出站
從本機的應用程序發出來, 經過路由選擇,讓路由知道從哪里發,先后順序經過有OUTPUT鏈的四個表(raw、mangle、nat、filter),都放通后到達POSTROUING鏈的兩個表(mangle、nat),如果沒有什么轉換地址,就出站。
-
總結
當一個數據包進入網卡時,數據包首先進入PREROUTING鏈,內核根據數據包目的IP判斷是否需要轉送出去。
如果數據包是進入本機的,數據包就會沿著圖向上移動,到達INPUT鏈。數據包到達INPUT鏈后, 任何進程都會收到它。本機上運行的程序可以發送數據包,這些數據包經過OUTPUT鏈,然后發送出去。
如果數據包是要轉發出去的,且內核允許轉發,數據包就會向右移動,經過FORWARD鏈,然后到達POSTROUTING鏈輸出。
規則匹配策略
3、 Iptables防火墻配置
-
iptables命令
語法 iptables [-t 表名] 管理選項 [鏈名] [匹配條件] [-j 控制類型]
?
注意:鏈名必須大寫;控制類型必須大寫
?
選項 | 作用 |
---|---|
-t | 指定表名(raw、mangle、nat、filter) |
-j | 指定控制類型 |
常用管理選項
選項 | 作用 |
---|---|
-A (--append) | 在指定鏈的末尾追加一條新的規則 |
-I (--insert) | 在指定鏈的開頭插入一條新的規則;未指定序號時默認作為第一條規則 |
-R (--replace) | 修改、替換指定鏈中的某一條規則,可指定規則序號或具體內容 |
-P (--policy) | 設置指定鏈的默認策略 |
-D (--delete) | 刪除指定鏈中的某一條規則,可指定規則序號或具體內容 |
-F (--flush) | 清空指定鏈中的所有規則;若未指定鏈名,則清空表中的所有鏈 |
-L (--list) | 列出指定鏈中所有的規則;若未指定鏈名,則列出表中的所有鏈 |
-n (--numeric) | (搭配-L使用)使用數字形式顯示輸出結果,如顯示IP地址而不是主機名 |
-v | (搭配-L使用)顯示詳細信息,包括每條規則的匹配包數量和匹配字節數 |
--line-numbers | (搭配-L使用)查看規則時,顯示規則的序號 |
常用控制類型
控制類型 | 作用 |
---|---|
ACCEPT | 允許數據包通過 |
DROP | 直接丟棄數據包,不給出任何回應消息 |
REJECT | 拒絕數據包通過,會給數據發送端一個響應信息 |
SNAT | 修改數據包的源地址 |
DNAT | 修改數據包的目的地址 |
MASQUERADE | 偽裝成—個非固定公網IP地址 |
LOG | 在/var/log/messages文件中記錄日志信息,然后將數據包傳遞給下一條規則。(沒有真正處理數據包) |
匹配條件
匹配條件 | 說明 |
---|---|
-p | 指定要匹配的數據包的協議類型 |
-s | 指定要匹配的數據包的源IP地址 |
-d | 指定要匹配的數據包的目的IP地址 |
-i | 指定數據包進入本機的網絡接口 |
-o | 指定數據包離開本機做使用的網絡接口 |
--sport | 指定源端口號 |
--dport | 指定目的端口號 |
命令操作
添加新的規則
##-A 在filter表的INPUT鏈末行添加拒絕icmp的規則 [root@localhost ~]# iptables -t filter -A INPUT -p icmp -j REJECT ? ##-I 不指定行,是在指定鏈首行插入規則(允許tcp 22端口) [root@localhost ~]# iptables -t filter -I INPUT -p tcp --dport 22 -j ACCEPT ? ##-I 指定行,是在指定鏈的指定行上插入規則 [root@localhost ~]# iptables -t filter -I INPUT 2 -p tcp --dport 22 -j ACCEPT
查看規則
##查看指定表的規則(不加鏈名顯示所有鏈的所有規則) [root@localhost ~]# iptables -t filter -L ? ##-nL 以數字形式顯示 [root@localhost ~]# iptables -t filter -nL ? ##-nvL 以數字形式顯示,并顯示詳細信息 [root@localhost ~]# iptables -t filter -nvL ? ##--line-numbers 顯示規則序號(指定鏈名,就顯示指定鏈的規則) [root@localhost ~]# iptables -t filter -nvL INPUT --line-numbers 編號 包數量 大小 規則 協議選項 入站網卡 出站網卡源地址 目的地址 條件 num pkts bytes target prot opt in out source destination 12 168 ACCEPT icmp --** 192.168.1.2500.0.0.0/0 29 844 REJECT icmp --** 0.0.0.0/00.0.0.0/0reject-with icmp-port-unreachable 392041 ACCEPT tcp--** 192.168.1.2500.0.0.0/0tcp dpt:22 4346 24461 ACCEPT tcp--** 192.168.1.2520.0.0.0/0tcp dpt:22 5 312548 REJECT tcp--** 0.0.0.0/00.0.0.0/0tcp dpt:22 reject-with icmp-port-unreachable ?
刪除規則
注意?
若規則列表中有多條相同的規則時,按內容匹配只刪除的序號最小的一條?
按號碼匹配刪除時,確保規則號碼小于等于已有規則數,否則報錯 按內容匹配刪數時,確保規則存在,否則報錯
##根據規則序號刪 [root@localhost ~]# iptables -D INPUT 3 ? ##根據規則內容刪(相當于操作一遍創建指定規則的步驟加上-D選項刪除) [root@localhost ~]#iptables -D INPUT -p icmp -j REJECT ? ##有相同的規則會刪除第一個 [root@localhost ~]#iptables -nL ? [root@localhost ~]#iptables -D INPUT -p tcp --dport 22 -j ACCEPT
清空規則
注意?
-F僅僅是清空鏈中的規則,并不影響-Р設置的默認規則,默認規則需要手動進行修改?
-P設置了默認規則為DROP后,使用-F一定要小心,因為iptables的修改是立刻生效的! 防止把允許遠程連接的相關規則清除后導致無法遠程連接主機,此情況如果沒有保存規則可重啟主機解決
如果不寫表名和鏈名,默認清空filter表中所有鏈里的所有規則
##清空指定鏈中所有規則 [root@localhost ~]# iptables -F OUTPUT ##不指定鏈名默認清空所有規則 [root@localhost ~]# iptables -F
修改規則
##-R 修改已有的規則 [root@localhost ~]# iptables -t filter -R INPUT 1 -p icmp -j ACCEPT ? ##-P 修改默認策略(修改為丟棄轉發數據包) [root@localhost ~]# iptables -P FORWARD DROP
4、 規則的匹配
1、通用匹配
可直接使用,不依賴其他條件或擴展包括網絡協議、IP地址、網絡接口等條件。
類型 | 選項 |
---|---|
協議匹配 | -p 協議名 |
地址匹配 | -s 源地址 -d 目的地址(可以是IP、網段、域名、空(代表任何地址)) |
接口匹配 | -i 入站網卡 -o 出站網卡 |
##(使用!取反)不是icmp協議的其他數據包全部接受 ##雖然不是icmp包都接受,但是沒有指定icmp包的規則,所以icmp包默認還是接受的 [root@localhost ~]# iptables -A INPUT ! -p icmp -j ACCEPT ? ##將指定主機192.168.116.20的數據包丟棄 [root@localhost ~]# iptables -A INPUT -s 192.168.116.20 -j DROP ? ##拒絕指定網段的數據包從ens33網卡進入 [root@localhost ~]# iptables -I INPUT -i ens33 -s 192.168.110.0/24 -j REJECT?
2、隱含匹配
某些條件,如端口、TCP標記、ICMP類型,隱含要求以特定的協議匹配作為前提。
-
協議端口匹配
--sport 和 --dsport 必須配合 -p 指定協議使用!!!
詳細用法
類型 | 作用 |
---|---|
--sport 1000 | 匹配源端口是1000的數據包 |
--sport 1000:3000 | 匹配源端口是1000-3000的數據包 |
--dport :3000 | 匹配目標端口是3000及以下的數據包 |
--dport 1000: | 匹配目標端口是1000及以上的數據包 |
##允許tcp的20和21端口通過(即允許ftp數據包) [root@localhost ~]# iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT ? ##丟棄192.168.11.0網段轉發的tcp 24000到24500 端口的數據包 [root@localhost ~]# iptables -I FORWARD -d 192.168.11.0/24 -p tcp --dport 24000:24500 -j DROP
-
tcp標記匹配 [了解]
--tcp-flags 配合 -p tcp 使用,指定tcp標記(SYN、ACK、RST、URG、PSH、FIN)
##丟棄SYN請求包,允許其他指定的數據包 [root@localhost ~]# iptables -A INPUT -p tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT ? ##SYN,RST,ACK SYN前面指定包范圍,空格后再指定 ##表明前面指定的里面,除了這空格后面的SYN,其他都放行 ? ##tcp三次握手第一次接受SYN,拒絕其他,第二次發送SYN和ACK [root@localhost ~]# iptables -I INPUT -p tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSHSYN -j REJECT [root@localhost ~]# iptables -I OUTPUT -p tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT
-
ICMP類型匹配
--icmp-type 配合 -p icmp 使用,指定icmp類型(字符串或數字代碼) icmp類型可用iptables -p icmp -h 查看幫助信息
類型 | 含義 |
---|---|
Echo-Request(代碼為8) | 請求 |
Echo-Reply (代碼為0) | 回顯 |
Destination-Unreachable(代碼為3) | 目標不可達 |
##丟棄icmp請求包(使別人不能ping通本機,但本機默認情況可以ping通別人) [root@localhost ~]# iptables -A INPUT -p icmp --icmp-type 8 -j DROP ? ##丟棄icmp回顯包(本機發送ping請求,但是別人回顯的包被本機丟棄,默認情況下本機不能ping通別人) [root@localhost ~]# iptables -A INPUT -p icmp --icmp-type 0 -j DROP ? ##當ping不通時,允許顯示目標不可達 [root@localhost ~]# iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
3、顯式匹配
要求以 -m (擴展模塊)的形式明確指出類型,包括多端口、MAC地址、IP范圍、數據包狀態等條件。
-
多端口匹配
-m multiport --sport 源端口列表 -m multiport --dport 目的端口列表
##允許tcp的20,21,22,53端口 [root@localhost ~]# iptables -A INPUT -p tcp -m multiport --dport 20,21,22,53 -j ACCEPT Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp--0.0.0.0/00.0.0.0/0multiport dports 20,21,22,53 ##允許udp的53,67,68端口 [root@localhost ~]# iptables -A INPUT -p udp -m multiport --dport 53,67,68 -j ACCEPT
-
ip范圍匹配
-m iprange --src-range 源IP范圍 -m iprange --dst-range 目的IP范圍
##禁止轉發源ip范圍是192.168.10.100-192.168.10.200的udp數據包 [root@localhost ~]# iptables -A FORWARD -p udp -m iprange --src-range 192.168.10.100-192.168.10.200 -j DROP Chain FORWARD (policy ACCEPT) target prot opt source destination DROP udp--0.0.0.0/00.0.0.0/0source IP range 192.168.1.1-192.168.1.10 ##禁止發送目的ip范圍是192.168.10.100-192.168.10.200的udp數據包 [root@localhost ~]# iptables -A INPUT -p udp -m iprange --dst-range 192.168.10.100-192.168.10.200 -j DROP ?
-
mac地址匹配
-m mac --mac-source 源MAC地址
-
狀態匹配
-m state --state 連接狀態
常見的連接狀態
狀態 | 含義 |
---|---|
NEW | 本機要連接目標主機,在目標主機上看到的第一個想要連接的包 |
ESTABLISHED | 本機已與目標主機進行通信,判斷標準只要目標主機回應了第一個包,就進入該狀態 |
RELATED | 本機已與目標主機進行通信,目標主機發起新的鏈接方式,一般與ESTABLISHED配合使用 |
INVALID | 無效的封包,例如數據破損的封包狀態 |
##第一個包我只看22端口的包(-p tcp是隱含匹配,可以省略-m tcp) [root@localhost ~]# iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT ? ##允許放通tcp和udp的這些端口號 [root@localhost ~]# iptables -A INPUT -p tcp -m multiport --dport 443,80,22,21,20,53 -j ACCEPT [root@localhost ~]# iptables -A INPUT -p udp -m multiport --dport 53 -j ACCEPT ? ##使已建立連接的包以及該鏈接相關的包允許通過 [root@localhost ~]# iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT ? ##默認策略設為drop,以上所有配置就成了一個tcp相關包的白名單,通過第一步的檢測后允許相關包通過 [root@localhost ~]# iptables -P INPUT DROP
5、Iptables配置NAT地址轉換
1、 配置SNAT
應用場景
局域網主機共享轉換的公網ip接入internet公網(內 --> 外)
模擬實驗環境
私網客戶端一臺、網關服務器一臺(設置iptables防火墻)、外網web服務端(有httpd服務) 三臺都需要關閉默認防火墻firewalld和selinux 準備私網客戶端:設置網卡網段為192.168.1.0/24;ip設為192.168.1.1;網關設為192.168.1.254。 準備網關服務器:一個網卡設為192.168.1.0/24網段,并設置ip為192.168.1.254;另一個網卡設為10.0.0.0/8網段,并設置ip為10.0.0.100;添加路由轉發功能;下載 iptables-services 并開始iptables之后做防護墻策略。 準備外網web服務端:設置網卡網段為10.0.0.0/8;ip設為10.0.0.1;下載并開啟httpd服務。
轉換為固定公網ip
iptables -t nat -A POSTROUTING -s 源網段 -o 出站網卡 -j SNAT --to 轉換的公網地址 iptables -t nat -A POSTROUTING -s 源網段 -o 出站網卡 -j SNAT --to-source 轉換的公網地址范圍(如10.0.0.1-10.0.0.10) 注:每一個做轉換的公網ip,一般可以支持內網100~200臺主機。
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens33 -j SNAT --to 10.0.0.100 [root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens33 -j SNAT --to-source 10.0.0.1 10.0.0.10
轉換為非固定的公網ip(動態)
iptables -t nat -A POSTROUTING -s 源網段 -o 出站網卡 -j MASQUERADE
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
2、配置DNAT
應用場景
在internet公網中發布位于企業局域網的服務器(外 --> 內)
模擬實驗環境
私網客戶端一臺(有httpd服務)、網關服務器一臺(設置iptables防火墻)、外網web服務端 三臺都需要關閉默認防火墻firewalld和selinux 可參考上個模擬場景,再為私網主機增設httpd服務使之成為私網web服務端,將原來的外網主機當做客戶端。 為私網主機添加httpd服務并啟用
轉換為私網ip
iptables -t nat -A PREROUTING -i 連接外部網絡的接口名稱 -d 外部接口IP地址 -p tcp --dport 發布的端口號 -j DNAT --to-destination 服務器內部網絡地址:服務實際端口號
[root@localhost ~]# iptables -t nat -A PREROUTING -i ens33 -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2
6、iptables防火墻策略的備份和恢復
iptables的配置存放在/etc/sysconfig/iptables 文件中,我們對iptables所做的策略修改,雖然會立刻生效,但是并沒有保存下來,當我們重啟iptables防火墻時,會讀取配置文件中設置的策略,我們之前修改過的策略便失效了。所以需要對修改的iptables策略進行備份和恢復。
iptables-save > 備份文件 將修改的iptables策略導入到備份文件中 iptables-restore < /opt/iptables.bak 將備份文件中的策略還原到配置文件中 systemctl restart iptables.service 重啟服務生效
##查看配置文件中的默認策略 [root@localhost opt]#cat /etc/sysconfig/iptables-config ? ##使用iptables -nL查看修改過的策略 [root@localhost opt]#iptables -nL ? ##對自定義的iptables策略做備份(將命令導入一個備份文件iptables.bak) [root@localhost opt]# iptables-save > /opt/iptables.bak [root@localhost opt]# cd /opt [root@localhost opt]# cat iptables.bak ? ##重啟服務(用作模擬未保留修改的策略),再查看發現策略又恢復成了配置文件中的默認策略 [root@localhost opt]# systemctl restart iptables.service ? [root@localhost opt]# iptables -nL ? ##將備份文件中的策略恢復到配置文件中,再重啟服務就還原成功了 [root@localhost opt]# iptables-restore < /opt/iptables.bak ? [root@localhost opt]# systemctl restart iptables.service ? [root@localhost opt]# iptables -nL ?
實驗
實驗拓撲
網絡規劃
-
內部PC1位于內網區域,地址段為: 192.168.1.0/24,pc1地址為:192.168.1.1/24,網關地址為:192.168.1.254/24
-
服務器S1位于服務器區域,地址段為: 192.168.2.0/24,pc1地址為:192.168.2.1/24,網關地址為:192.168.2.254/24
-
PC2位于互聯網區域,模擬外部互聯網,地址段為:10.0.0.0/8,pc2地址為:10.0.0.1/8
-
Linux防火墻的三塊網卡為別連接不同的網絡區域,地址分別為 :ens33 192.168.1.254/24;ens34 10.0.0.100/8;ens35 192.168.2.254/24
實驗要求
-
內部網絡中的pc1采用SNAT訪問外部互聯網,但是無法ping到內部網關。
-
內部網絡服務器s1通過DNAT發布服務到互聯網。
-
互聯網主機pc2能夠訪問DMZ(s1)區域的服務器,但是不能夠進行ping和ssh連接。
8、實驗具體步驟:
一、環境準備(虛擬機基礎配置)
1. 禁用 firewalld 并安裝 iptables
# 禁用 firewalld 并安裝 iptables-services systemctl stop firewalld systemctl disable firewalld yum install -y iptables-services systemctl enable --now iptables
2. 配置網卡與 IP 轉發(同 firewalld 方案)
確保防火墻 sf1
的三塊網卡(ens33
/ens34
/`ens37)配置正確,并開啟 IP 轉發:
# 開啟 IP 轉發 echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-ipforward.conf sysctl -p /etc/sysctl.d/99-ipforward.conf
二、實驗功能實現(防火墻 sf1
配置)
1. 需求 1:pc1 通過 SNAT 訪問外網,但無法 ping 內網網關
# 清空現有規則并設置默認策略 iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP ?# 默認拒絕所有轉發流量 ? # SNAT 配置:pc1 訪問外網時源 IP 轉換為防火墻外網口 IP iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens34 -j SNAT --to-source 10.0.0.100 ? # 拒絕 pc1 ping 內網網關(192.168.1.254) iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.254 -p icmp --icmp-type echo-request -j DROP
2. 需求 2:服務器 s1 通過 DNAT 發布服務到外網
# DNAT 配置:外網訪問防火墻 80 端口轉發到 s1 的 80 端口 iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.2.1:80 ? # 允許轉發 HTTP 流量(從 ens34 到 ens35) iptables -A FORWARD -i ens34 -o ens35 -d 192.168.2.1 -p tcp --dport 80 -j ACCEPT iptables -A FORWARD -i ens35 -o ens34 -s 192.168.2.1 -p tcp --sport 80 -j ACCEPT
3. 需求 3:pc2 可訪問 s1 服務,但無法 ping/ssh 連接
# 允許 pc2 訪問 s1 的 HTTP 服務 iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.1 -p tcp --dport 80 -j ACCEPT iptables -A FORWARD -i ens35 -o ens34 -s 192.168.2.1 -d 10.0.0.0/8 -p tcp --sport 80 -j ACCEPT ? # 拒絕 pc2 ping s1 iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.0/24 -p icmp --icmp-type echo-request -j DROP ? # 拒絕 pc2 ssh 連接 s1 iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.0/24 -p tcp --dport 22 -j DROP
三、驗證步驟
-
驗證 SNAT 與 ping 限制:
# 在 pc1 上測試 ping 10.0.0.1 ? ? ? # 應能 ping 通 pc2 ping 192.168.1.254 ?# 應無法 ping 通網關 curl 10.0.0.1 ? ? ? # 若 pc2 開啟 HTTP 服務,應能訪問
[root@localhost network-scripts]# systemctl stop firewalld.service [root@localhost network-scripts]# ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. From 192.168.1.254 icmp_seq=1 Destination Host Unreachable From 192.168.1.254 icmp_seq=2 Destination Host Unreachable From 192.168.1.254 icmp_seq=3 Destination Host Unreachable From 192.168.1.254 icmp_seq=4 Destination Host Unreachable ^C --- 10.0.0.1 ping statistics --- 5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4088ms pipe 4 [root@localhost network-scripts]# ping 192.168.1.254 PING 192.168.1.254 (192.168.1.254) 56(84) bytes of data. 64 bytes from 192.168.1.254: icmp_seq=1 ttl=64 time=0.417 ms 64 bytes from 192.168.1.254: icmp_seq=2 ttl=64 time=0.333 ms 64 bytes from 192.168.1.254: icmp_seq=3 ttl=64 time=0.294 ms 64 bytes from 192.168.1.254: icmp_seq=4 ttl=64 time=0.276 ms ^C --- 192.168.1.254 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3101ms rtt min/avg/max/mdev = 0.276/0.330/0.417/0.054 ms [root@localhost network-scripts]# curl 10.0.0.1 [root@localhost network-scripts]# curl 10.0.0.1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> ? <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><title>Test Page for the Nginx HTTP Server on Roc ?
-
驗證 DNAT 發布:
# 在 pc2 上測試 curl http://10.0.0.100 ?# 應返回 s、1 的 HTTP 頁面內容
[root@localhost ~]# curl http://10.0.0.100 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> ? <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><title>Test Page for the Nginx HTTP Server on Rocky Linux</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><style type="text/css">/*<![CDATA[*/body {background-color: #fff; ?
-
驗證 pc2 訪問限制:
# 在 pc2 上測試 ping 192.168.2.1 ? # 應無法 ping 通 s1 ssh 192.168.2.1 ? ?# 應無法建立 SSH 連接 curl http://10.0.0.100 ?# 應能正常訪問 HTTP 服務
root@localhost ~]# ping 192.168.2.1 connect: 網絡不可達 [root@localhost ~]# ssh 192.168.2.1 ssh: connect to host 192.168.2.1 port 22: Network is unreachable root@localhost ~]# curl 10.0.0.100 111 ? ?
四、關鍵配置分析
功能 | iptables 核心規則 | 說明 |
---|---|---|
SNAT 上網 | POSTROUTING 鏈的 SNAT 規則 | 改寫源 IP,使內網主機可訪問外網 |
ping 限制 | INPUT 鏈拒絕特定 ICMP 類型 | 阻止內網主機 ping 防火墻網關 |
DNAT 發布服務 | PREROUTING 鏈的 DNAT 規則 | 將外網請求轉發到內網服務器 |
pc2 訪問限制 | FORWARD 鏈的精準過濾 | 僅放行 HTTP 流量,拒絕 ICMP 和 SSH |
五、故障排查命令
# 查看當前 iptables 規則 iptables -L -n -v iptables -t nat -L -n -v ? # 查看網絡連接狀態 netstat -tulpn ? # 檢查數據包計數(驗證規則是否生效) iptable-n -v -x
防火墻配置: [root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:61:3a:30 brd ff:ff:ff:ff:ff:ffaltname enp2s1inet 192.168.1.254/24 brd 192.168.1.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe61:3a30/64 scope link valid_lft forever preferred_lft forever 3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:61:3a:3a brd ff:ff:ff:ff:ff:ffaltname enp2s2inet 10.0.0.100/8 brd 10.255.255.255 scope global noprefixroute ens34valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe61:3a3a/64 scope link valid_lft forever preferred_lft forever 4: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:61:3a:44 brd ff:ff:ff:ff:ff:ffaltname enp2s5inet 192.168.2.254/24 brd 192.168.2.255 scope global noprefixroute ens37valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe61:3a44/64 scope link valid_lft forever preferred_lft forever 5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000link/ether 52:54:00:3f:34:5d brd ff:ff:ff:ff:ff:ffinet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0valid_lft forever preferred_lft forever [root@localhost ~]# systemctl stop firewalld [root@localhost ~]# iptables -F [root@localhost ~]# iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? ? Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? ? Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? [root@localhost ~]# iptables -P INPUT ACCEPT [root@localhost ~]# iptables -P OUTPUT ACCEPT [root@localhost ~]# iptables -P FORWARD DROP [root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens34 -j SNAT --to-source 10.0.0.100 [root@localhost ~]# iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.254 -p icmp --icmp-type echo-request -j DROP [root@localhost ~]# iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.2.1:80 [root@localhost ~]# iptables -A FORWARD -i ens34 -o ens35 -d 192.168.2.1 -p tcp --dport 80 -j ACCEPT [root@localhost ~]# iptables -A FORWARD -i ens35 -o ens34 -s 192.168.2.1 -p tcp --sport 80 -j ACCEPT [root@localhost ~]# iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.1 -p tcp --dport 80 -j ACCEPT [root@localhost ~]# iptables -A FORWARD -i ens35 -o ens34 -s 192.168.2.1 -d 10.0.0.0/8 -p tcp --sport 80 -j ACCEPT [root@localhost ~]# iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.0/24 -p icmp --icmp-type echo-request -j DROP [root@localhost ~]# iptables -A FORWARD -i ens34 -o ens35 -s 10.0.0.0/8 -d 192.168.2.0/24 -p tcp --dport 22 -j DROP ? [root@localhost ~]# iptables -L -n -v Chain INPUT (policy ACCEPT 109 packets, 16120 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 76 11521 LIBVIRT_INP all -- * ? ? * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? ? Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 LIBVIRT_FWX all -- * ? ? * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? 0 ? ? 0 LIBVIRT_FWI all -- * ? ? * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? 0 ? ? 0 LIBVIRT_FWO all -- * ? ? * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? ? Chain OUTPUT (policy ACCEPT 90 packets, 8812 bytes)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 51 3973 LIBVIRT_OUT all -- * ? ? * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? ? Chain LIBVIRT_INP (1 references)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 ACCEPT ? ? udp -- virbr0 * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? udp dpt:530 ? ? 0 ACCEPT ? ? tcp -- virbr0 * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? tcp dpt:530 ? ? 0 ACCEPT ? ? udp -- virbr0 * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? udp dpt:670 ? ? 0 ACCEPT ? ? tcp -- virbr0 * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? tcp dpt:67 ? Chain LIBVIRT_OUT (1 references)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 ACCEPT ? ? udp -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? udp dpt:530 ? ? 0 ACCEPT ? ? tcp -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? tcp dpt:530 ? ? 0 ACCEPT ? ? udp -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? udp dpt:680 ? ? 0 ACCEPT ? ? tcp -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? tcp dpt:68 ? Chain LIBVIRT_FWO (1 references)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 ACCEPT ? ? all -- virbr0 * ? ? ? 192.168.122.0/24 ? ? 0.0.0.0/0 ? ? ? ? ? 0 ? ? 0 REJECT ? ? all -- virbr0 * ? ? ? 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? reject-with icmp-port-unreachable ? Chain LIBVIRT_FWI (1 references)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 ACCEPT ? ? all -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 192.168.122.0/24 ? ? ctstate RELATED,ESTABLISHED0 ? ? 0 REJECT ? ? all -- * ? ? virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? reject-with icmp-port-unreachable ? Chain LIBVIRT_FWX (1 references)pkts bytes target ? ? prot opt in ? ? out ? ? source ? ? ? ? ? ? ? destination ? ? ? ? 0 ? ? 0 ACCEPT ? ? all -- virbr0 virbr0 0.0.0.0/0 ? ? ? ? ? 0.0.0.0/0 ? ? ? ? ? ?