netfilter/iptables 簡介: (1)IP數據包過濾系統由 netfilter 和 iptables 兩個組件構成。 (2)netfilter是集成在內核中的一部分,其作用是定義、保存相應的規則, (3)iptables是一種工具,用來修改信息的過濾規則及其他配置,而這些規則會保存在內核空間之中。 (4)netfilter是Linux核心中的一個通用架構,其提供了一系列的表(tables)每個表由若干個鏈(chains)組成,而每條鏈可以由一條或若干條規則(rules)組成。 防火牆工作流程:
報文流向: (1)流入本機:PREROUTING --> INPUT ==> 用戶空間進程。 (2)流出本機:用戶空間進程==> OUTPUT --> POSTROUTING (3)轉發:PREROUTING --> FORWARD --> POSTROUTING 注釋:==> 進入用戶空間, --> 進入系統空間。 四表(同一鏈上的不同的表的規則優先級 高-->低): (1):raw:關閉在nat表啟用的連接追蹤機制。 表與鏈關系:PREROUTING -> OUTPUT (2):mangle:拆解報文,按需修改。 表與鏈關系:PREROUTING -> INPUT -> FORWARD -> OUTPUT -> POSTROUTING (3):nat:network address translation (ip層地址,傳輸層地址)。 表與鏈關系:PREROUTING -> INPUT -> OUTPUT -> POSTROUTING (4):filter:過濾,防火牆。 表與鏈關系:INPUT -> FORWARD -> OUTPUT 五鏈(netfilter):五個參考點實現報文管理功能。 (1):PREROUTING: 數據包進入路由表之前 (2):INPUT: 通過路由表後目的地為本機 (3):FORWARD: 通過路由表後,目的地不為本機 (4):OUTPUT: 由本機產生,向外轉發 (5):POSTROUTIONG:發送到網卡接口之前 ================================================= iptables 使用: 服務應用: CentOS 7 ~]# systemctl stop firewalld.service ~]# systemctl disable firewalld.service CentOS 6 ~]# service iptables stop ~]# chkconfig iptables off ........................................................................................................................................................................... (1)命令 格式:iptables [-t table] SUBCOMMAND chain [matches...] [target] iptables [-t 表名] 命令選項 [鏈名] [條件匹配] [-j 目標動作或跳轉] ........................................................................................................................................................................... -t table: raw, mangle, nat, [filter] ~]# iptables -t raw -nvL ~]# iptables -t mangle -nvL ~]# iptables -t nat -nvL ~]# iptables -nvL ........................................................................................................................................................................... (2)SUBCOMMAND: (2.1) 鏈管理: -N: new:新增一條自定義鏈。 ~]# iptables -N test -X:delete:刪除自定義的空鏈。 ~]# iptables -X mytest -P:policy:設置鏈的默認策略。 ACCEPT:接受 DROP:丟棄 REJECT:拒絕:互聯網訪問時最好不要使用REJECT。 ~]# iptables -t filter -P FORWARD DROP ~]# iptables -t filter -P INPUT DROP ~]# iptables -t filter -P OUTPUT DROP 備注:設置 filter 規則控制時要先將 FORWARD,INPUT,OUTPUT 設為 DROP 或者 REJECT -E:rename:重命名自定義的未被引用(引用計數為0)的鏈。 ~]# iptables -E test mytest (2.2) 規則管理: -A:append:插入到末尾(最後一個)。 -I:insert:插入到開始(第一個)。 -D:delete:刪除。 1:rule specification 2:rule number ~]# iptables -D OUTPUT 1 -R:replace:替換。 -F:flush:清洗,清空。 -Z:zero:清 0。 iptables的每條規則都有兩個計數器。 1:由本規則匹配到的所有的packets。 2:由本規則匹配到的所有的bytes。 S:selected,以 iptables-save 命令的格式顯示鏈上的規則。 (2.3)查看: -L: list,列出規則 -n:numeric,以數字格式顯示地址和端口; -v:verbose,詳細信息;-vv, -vvv -x:exactly,顯示計數器的精確值而非單位換算後的結果 --line-numbers:顯示鏈上的規則的編號 ~]# iptables -nvL --line-numbers 組合:-nvL ~]# iptables -nvL ........................................................................................................................................................................... (3)matches 匹配條件: 1:基本匹配:netfilter自帶的匹配機制 [!] -s, --source address[/mask][,...]:原地址匹配 ~]# iptables -A INPUT -s 172.18.0.0/16 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.0.0/16 -j ACCEPT ~]# iptables -A FORWARD -s 172.18.0.0/16 -j ACCEPT [!] -d, --destination address[/mask][,...]:目標地址匹配 ~]# iptables -A INPUT -s 172.18.21.72 -d 172.18.21.62 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -d 172.18.21.72 -j ACCEPT [!] -i, --in-interface name:限制報文流入的接口,只能用於PREROUTING,INPUT及FORWARD。 [!] -o, --out-interface name:限制報文流出的接口,只能用於OUTPUT,FORWARD及POSTROUTING。 [!] -p {tcp|udp|icmp}:限制協議 ~]# iptables -I INPUT -s 172.18.21.72 -d 172.18.21.62 -p tcp -j ACCEPT ~]# iptables -I OUTPUT -s 172.18.21.62 -d 172.18.21.72 -p tcp -j ACCEPT 2:擴展匹配:經由擴展模塊引入的匹配機制,-m matchname 注釋: 隱式擴展:可以不用使用-m選項專門加載相應模塊;前提是要使用-p選項可匹配何種協議。 顯式擴展:必須由-m選項專門加載相應模塊。 (1):隱式擴展: [!] -p, --protocol PROTOCOL PROTOCOL: 協議:tcp, udp, icmp, icmpv6, esp, ah, sctp, mh or "all" tcp: 隱含指明了“-m tcp”,有專用選項: [!] --source-port,--sport port[:port]:匹配報文中的tcp首部的源端口;可以是端口范圍。 [!] --destination-port,--dport port[:port]:匹配報文中的tcp首部的目標端口;可以是端口范圍。 ~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 22 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 22 -j ACCEPT 注釋:放行ssh連接。 ~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 80 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 80 -j ACCEPT 注釋:開放 80 端口 [!] --tcp-flags mask comp:檢查報文中mask指明的tcp標志位,而要這些標志位comp中必須為1; --tcp-flags syn,fin,ack,rst syn --tcp-flags syn,fin,ack,rst ack,fin [!] --syn: --syn相當於“--tcp-flags syn,fin,ack,rst syn”;tcp三次握手的第一次; udp:隱含指明了“-m udp”,有專用選項: [!] --source-port,--sport port[:port]:匹配報文中的udp首部的源端口;可以是端口范圍; [!] --destination-port,--dport port[:port]:匹配報文中的udp首部的目標端口;可以是端口范圍; icmp:隱含指明了“-m icmp”,有專用選項: [!] --icmp-type {type[/code]|typename} type/code: 0/0:echo reply:請求 8/0:echo request :響應 ~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT ~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT ~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT 注釋:icmp type:http://baike.baidu.com/link?url=rph8HhXWXtekVwXLMz2FcUHaPru6DgG7-fDXFJOUt4qGann-4pwVaCTnF0JiGNiCzeiOg51fQzhWY8XEP_tyE_#7 (2):顯式擴展: (1):multiport:多端口匹配:以離散方式定義多端口匹配,最多可以指定15個端口; [!] --source-ports,--sports port[,port|,port:port]... [!] --destination-ports,--dports port[,port|,port:port]... [!] --ports port[,port|,port:port]... ~]# iptables -I INPUT -s 0/0 -d 172.18.21.62 -p tcp -m multiport --dports 22,80 -j ACCEPT ~]# iptables -I OUTPUT -d 0/0 -s 172.18.21.62 -p tcp -m multiport --sports 22,80 -j ACCEPT (2):iprange:指明一段連續的ip地址范圍做為源地址或目標地址匹配; [!] --src-range from[-to]:源地址范圍 [!] --dst-range from[-to]:目標地址范圍 ~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 23 -m iprange --src-range 172.18.21.1-172.18.21.100 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -p tcp --sport 23 -m iprange --dst-range 172.18.21.1-172.18.21.100 (3):string:對報文中的應用層數據做字符串匹配檢測; --algo {bm|kmp}:(bm = Boyer-Moore, kmp = Knuth-Pratt-Morris) 算法 [!] --string pattern:給定要檢查的字符串模式; [!] --hex-string pattern:給定要檢查的字符串模式; ~]# iptables -I OUTPUT -s 172.18.100.6 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "old" -j REJECT ~]# iptables -I OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "old" -j REJECT (4):time:根據收到報文的時間/日期與指定的時間/日期范圍進行匹配。 --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:起始日期時間。 --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:結束日期時間。 --timestart hh:mm[:ss]:起始時間。 --timestop hh:mm[:ss]:結束時間。 [!] --monthdays day[,day...]:匹配一個月中的哪些天。 [!] --weekdays day[,day...]:匹配一個周中的哪些天。 ~]# iptables -R INPUT 4 -d 172.18.100.6 -p tcp --dport 23 -m iprange --src-range 172.18.100.1-172.18.100.100 -m time --timestart 09:00:00 --timestop 16:00:00 --weekdays 1,2,3,4,5 -j ACCEPT ~]# iptables -I INPUT -d 172.18.21.62 -p tcp --dport 23 -m iprange --src-range 172.18.21.1-172.18.21.100 -m time --timestart 09:00:00 --timestop 18:00:00 -j ACCEPT (5):connlimit:根據每客戶端主機做並發連接數限制,即每客戶端最多可同時發起的連接數量; --connlimit-upto n:連接數量小於等於n則匹配; --connlimit-above n:連接數量大於n則匹配; ~]# iptables -A INPUT -s 0/0 -d 172.18.100.6 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT ~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT ~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT (6):limit:基於令牌桶算法對報文的速率做匹配; --limit rate[/second|/minute|/hour|/day] --limit-burst number ~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 3 -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT (7):state:是conntrack的子集,用於對報文的狀態做連接追蹤 [!] --state state INVALID:無法識別的連接。 ESTABLISHED:連接追蹤模板當中存在記錄的連接。 NEW:連接追蹤模板當中不存的連接請求。 RELATED:相關聯的連接。 UNTRACKED:未追蹤的連接。 1:已經追蹤到的並記錄下來的連接:cat /proc/net/nf_conntrack 2:連接追蹤功能所能夠記錄的最大連接數量(可調整): /proc/sys/net/nf_conntrack_max ~]# sysctl -w net.nf_conntrack_max=300000 #第一種方式 net.nf_conntrack_max = 300000 ~]# echo 200000 > /proc/sys/net/nf_conntrack_max #第二種方式 ~]# cat /proc/sys/net/nf_conntrack_max 200000 conntrack所能夠追蹤的連接數量的最大值取決於/proc/sys/net/nf_conntrack_max的設定;已經追蹤到的並記錄下來的連接位於/proc/net/nf_conntrack文件中,超時的連接將會被刪除;當模板滿載時,後續的新連接有可能會超時;解決辦法: (1) 加大nf_conntrack_max的值; (2) 降低nf_conntrack條目的超時時長; 不同協議的連接追蹤時長:/proc/sys/net/netfilter/ 示例1: ~]# iptables -A INPUT -s 172.18.0.0/16 -d 172.18.21.62 -p tcp -m multiport --dports 22,23,80 -m state --state NEW,ESTABLISHED -j ACCEPT ~]# iptables -A OUTPUT -d 172.18.0.0/16 -s 172.18.21.62 -p tcp -m multiport --sports 22,23,80 -m state --state ESTABLISHED -j ACCEPT ~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -j ACCEPT ~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT 示例2: ~]# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT ~]# iptables -A INPUT -d 172.18.21.62 -p tcp -m multiport --dports 22,23,80 -m state --state NEW -j ACCEPT ~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT ~]# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT 示例3: ~]# modinfo nf_conntrack_ftp ~]# modprobe nf_conntrack_ftp ~]# lsmod | grep ftp nf_conntrack_ftp 11953 0 nf_conntrack 79206 7 nf_conntrack_ftp,xt_connlimit,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state ~]# service vsftpd restart ~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 21 -m state --state NEW -j ACCEPT ~]# iptables -I INPUT -d 172.18.21.62 -m state --state ESTABLISHED -j ACCEPT ........................................................................................................................................................................... (4):保存與啟動規則 1:保存: CentOS 6: ~]# service iptables save ~]# iptables-save > /etc/sysconfig/iptables ~]# iptables-save > /PATH/TO/SOME_RULE_FILE CentOS 7: ~]# iptables -S > /PATH/TO/SOME_RULE_FILE ~]# iptables-save > /PATH/TO/SOME_RULE_FILE 2:啟動: 手動: ~]# iptables-restore < /PATH/FROM/SOME_RULE_FILE CentOS 6:service iptables restart 備注:自動從 /etc/sysconfig/iptables 文件中重載規則。 自動: (1):/etc/rc.d/rc.local ~]# vi /etc/rc.d/rc.local iptables-restore < /PATH/FROM/SOME_RULE_FILE (2):/usr/bin/iptables.sh ~]# vi /usr/bin/iptables.sh iptables-restore < /PATH/FROM/SOME_RULE_FILE ........................................................................................................................................................................... (4)處理動作: -j targetname [per-target-options] 1:ACCEPT, DROP, REJECT 2:RETURN:返回調用的鏈 示例: ~]# iptables -N web ~]# iptables -A web -s 10.0.1.0/24 -p tcp --dport 80 -j ACCEPT ~]# iptables -I web 1 -m string --alog kmp --string "old" -j REJECT ~]# iptables -I web 2 -p tcp -m state --state ESTABLISHED -j ACCEPT ~]# iptables -A FORWARD -p tcp -j web ~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 22 -m state --state NEW -J ACCEPT ~]# iptables -A web -j RETURN 注釋:返回調用者(默認隱含)。 3:REDIRECT:端口重定向,端口映射:僅使用在 PREROUTING 和 OUTPUT 鏈。 --to-ports port[-port] 示例: ~]# 修改監聽端口為 8080 。 ~]# iptables -t nat -A PREROUTING -d 172.18.21.72 -p tcp --dport 80 -j REDIRECT --to-ports 8080 訪問: http://172.18.21.72:8080 http://172.18.21.72 4:LOG:日志 --log-level level:等級(默認為4):emerg, alert, crit, error, warning, notice, info or debug. --log-prefix prefix:指定前綴 示例: ~]# iptables -I FORWARD 2 -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "(new connctions)" 日志記錄位置: ~]# cat /var/log/messages 5:MARK:防火牆標記 6:SNAT:源地址轉換:修改IP報文中的源IP地址:POSTROUTING 和 INPUT (CentOS 7 支持) 鏈 --to-source [ipaddr[-ipaddr]] 示例: ~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.21.71 ~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.21.70-172.18.21.100 備注:讓本地網絡中的主機可使用統一地址與外部主機通信,從而實現地址偽裝 請求:由內網主機發起,修改源IP,如果修改則由管理員定義 響應:修改目標IP,由nat自動根據會話表中追蹤機制實現相應修改 7:DNAT:目標地址轉換:修改IP報文中的目標IP地址:RPEROUTING 和 OUTPUT (CentOS 7)鏈 --to-destination [ipaddr[-ipaddr]][:port[-port]] 示例1: ~]# iptables -t nat -A PREROUTING -d 172.18.21.71 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.2 ~]# curl http://172.18.21.71/ 示例2: ~]# 修改 10.0.1.2 監聽地址為 Listen 8090 ~]# iptables -t nat -A PREROUTING -d 172.18.21.71 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.2:8090 ~]# curl http://172.18.21.71/ 備注:讓本地網絡中服務器使用統一的地址向外提供服務(發布服務),但隱藏了自己的真實地址。 請求:由外網主機發起,修改其目標地址,由管理員定義。 響應:修改源地址,但由nat自動根據會話表中的追蹤機制實現對應修改。 8:MASQERADE:地址偽裝,地址動態偽裝 示例: ~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j MASQUERADE 9:recent: ........................................................................................................................................................................... 完整的示例: 設置網卡地址:nmtui
基本設置: 關閉 CentOS6 的iptables 和 CentOS7的 firewalld。 清空三台主機的防火牆規則: ~]# iptables -F 主機:172.18.21.71 查看是否打開網卡轉發: ~]# cat /proc/sys/net/ipv4/ip_forward 開啟網卡轉發: ~]# echo 1 > /proc/sys/net/ipv4/ip_forward 備注:地址屬於內核不屬於網卡。 注釋: 1:10.0.1.1未設置網關的時候不能 ping 通172.18.21.71,但是可以ping通10.0.1.1 2:172.18.21.71設置轉發後可以 ping 通172.18.21.72,但是得不到 ping 回應。 主機:10.0.1.1 ~]# ping 172.18.21.72 主機:172.18.21.72:抓包查看。 ~]# tcpdump -i eno16777736 icmp 注釋:172.18.21.72主機回應了但是回應到了網關。 添加路由: 主機:172.18.21.72 ~]# route add -net 10.0.1.0/24 gw 172.18.21.71 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.18.0.1 0.0.0.0 UG 100 0 0 eno16777736 10.0.1.0 172.18.21.71 255.255.255.0 UG 0 0 0 eno16777736 172.18.0.0 0.0.0.0 255.255.0.0 U 100 0 0 eno16777736 注釋:此時 10.0.1.2主機ping請求172.18.21.72得到回應。 主機:172.18.21.71 ~]# iptables -P FORWARD DROP ~]# tcpdump -i eno16777736 -nn icmp -vv 基礎寫法: 內網 ping 外網 ~]# iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT ~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 0 -j ACCEPT 外網 ping 內網 ~]# iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 0 -j ACCEPT ~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 8 -j ACCEPT 合並寫法: ~]# iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT 內部 ping 外部 ~]# iptables -A FORWARD -s 10.0.1.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT 外網 ping 內網 ~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT 同時允許內網和外網互 ping ~]# iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT ~]# lsmod | grep ftp 內網訪問外網服務 80和21 ~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT ~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT ~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 21 -m state --state NEW -j ACCEPT ~]# modprobe nf_conntrack_ftp 合並寫法: ~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT ~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21 -m state --state NEW -j ACCEPT