1)Linux下的防火牆概念
a、一般談到Linux下的防火牆,我們都會首先想到iptables,其實更确切的叫法應該是Netfilter/iptables,iptables和Netfilter其實是存在差别的。
b、盡管它們經常被用來互相替換使用,Netfilter是用來實作Linux核心中防火牆的Linux核心空間程式代碼段,它要麼被直接編譯進核心,要麼被包含在子產品中。
c、而iptables是用來管理Netfilter防火牆的使用者程式,而我這裡提到的iptables是包含Netfiler和iptables。
d、Netfilter/iptables是基于包過濾的防火牆,主要是針對2-4層,另外,iptables也支援7層控制。
2)iptables的組成部分:
iptables有四個表和五個鍊以及一些規則組成:
四個表:filter、nat、mangle、raw
filter表(過濾規則表),nat表(位址轉換規則表),mangle(修改資料标記位規則表),raw(跟蹤資料表規則表)
其中最常用的是filter表以及nat表
五個鍊:INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING
iptables的指令文法:
iptables [-t 表名]<-A|-I|-D|-R>鍊名[規則編号][-i|-o 網卡名稱][-p 協定類型][-s 源IP位址|源子網][–sport 源端口号][-d 目标IP位址|目标子網][–dport 目标端口号]<-j 動作>
3)參數及動作資訊
-A 追加防火牆規則
-D 删除防火牆規則
-I 插入防火牆規則
-F 清空防火牆規則
-L 列出防火牆規則
-R 替換防火牆規則
-Z 清空防火牆資料表統計資訊
-P 設定鍊預設規則
比對參數:
-p 比對協定
-s 比對源位址
-d 比對目标位址
-i 比對入站網卡接口
-o 比對出站網卡接口
–sport 比對源端口
–dport 比對目标端口
–src-range 比對源位址範圍
–dst-range 比對目标位址範圍
–limit 比對資料表速率
–mac-source 比對源MAC位址
–state 比對狀态(INVALID、ESTABLISHED、NEW、RELATED)
–string 比對應用層字串
觸發動作:
ACCEPT 允許資料包通過
DROP 丢棄資料包
REJECT 拒絕資料包通過,并發回封包通知對方
LOG 将資料包資訊記錄syslog日志
DNAT 目标位址轉換
SNAT 源位址轉換(适用于靜态IP)
MASQUERADE 位址欺騙(隻能用于ADSL撥号上網的IP僞裝,也就是主機的IP是由ISP配置設定動态的)
REDIRECT 重定向,将資料包重定向到本機或另外主機的某一個端口,通常能實作透明代理或者對外開放内網的某些服務
4)常用的指令
a、檢視filter表的所有規則:
<code>[root@localhost ~]</code><code># iptables -n -L</code>
<code>Chain INPUT (policy ACCEPT)</code>
<code>target prot opt </code><code>source</code> <code>destination </code>
<code>Chain FORWARD (policy ACCEPT)</code>
<code>Chain OUTPUT (policy ACCEPT)</code>
<code>target prot opt </code><code>source</code> <code>destination</code>
b、清空filter表的所有規則:
<code>[root@localhost ~]</code><code># iptables -F</code>
c、檢視nat表的所有規則:
<code>[root@localhost ~]</code><code># iptables -t nat -n -L</code>
# 記錄10.10.10.1通路主機80端口的日志資訊(/var/log/messages)
<code>[root@localhost ~]</code><code># iptables -I INPUT -s 10.10.10.1 -p tcp --dport 80 -j LOG</code>
<code>[root@localhost ~]</code><code># tail -10 /var/log/messages</code>
<code>Jul 13 14:44:53 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10253 DF PROTO=TCP SPT=62700 DPT=80 WINDOW=253 RES=0x00 ACK FIN URGP=0 </code>
<code>Jul 13 14:44:55 localhost chronyd[829]: Selected </code><code>source</code> <code>202.118.1.130</code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10256 DF PROTO=TCP SPT=62701 DPT=80 WINDOW=256 RES=0x00 ACK FIN URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10257 DF PROTO=TCP SPT=62702 DPT=80 WINDOW=256 RES=0x00 ACK FIN URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10258 DF PROTO=TCP SPT=62703 DPT=80 WINDOW=256 RES=0x00 ACK FIN URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10259 DF PROTO=TCP SPT=62704 DPT=80 WINDOW=256 RES=0x00 ACK FIN URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10260 DF PROTO=TCP SPT=62701 DPT=80 WINDOW=256 RES=0x00 ACK URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10261 DF PROTO=TCP SPT=62702 DPT=80 WINDOW=256 RES=0x00 ACK URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10262 DF PROTO=TCP SPT=62703 DPT=80 WINDOW=256 RES=0x00 ACK URGP=0 </code>
<code>Jul 13 14:44:59 localhost kernel: IN=eno16777736 OUT= MAC=00:0c:29:c5:a0:8d:00:50:56:c0:00:08:08:00 SRC=10.10.10.1 DST=10.10.10.133 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10263 DF PROTO=TCP SPT=62704 DPT=80 WINDOW=256 RES=0x00 ACK URGP=0</code>
# 将來自10.10.10.0/24網段的主機并通路80端口的請求給予拒絕
<code>[root@localhost ~]</code><code># iptables -I INPUT -s 10.10.10.0/24 -p tcp --dport 80 -j DROP</code>
<code>DROP tcp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:80</code>
<code>LOG tcp -- 10.10.10.1 0.0.0.0</code><code>/0</code> <code>tcp dpt:80 LOG flags 0 level 4</code>
# 禁止10.10.10.0/24網段内的主機ping。ICMP類型為8
<code>[root@localhost ~]</code><code># iptables -A INPUT -s 10.10.10.0/24 -p icmp --icmp-type 8 -j DROP</code>
<code>說明:禁止10.10.10.0</code><code>/24</code><code>網段内的主機</code><code>ping</code>
# 檢視filter表中防火牆規則并顯示規則編号:
<code>[root@localhost ~]</code><code># iptables -nL --line-number</code>
<code>num target prot opt </code><code>source</code> <code>destination </code>
<code>1 DROP tcp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:80</code>
<code>2 LOG tcp -- 10.10.10.1 0.0.0.0</code><code>/0</code> <code>tcp dpt:80 LOG flags 0 level 4</code>
<code>3 DROP icmp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>icmptype 8</code>
<code>num target prot opt </code><code>source</code> <code>destination</code>
# -D參數,删除INPUT鍊的第三條規則:
<code>[root@localhost ~]</code><code># iptables -D INPUT 3</code>
# -R參數,替換第二條規則
<code>[root@localhost ~]</code><code># iptables -R INPUT 2 ! -s 10.10.10.1 -p tcp --dport 80 -j ACCEPT</code>
<code>2 ACCEPT tcp -- !10.10.10.1 0.0.0.0</code><code>/0</code> <code>tcp dpt:80</code>
# 檢視iptables的版本号:
<code>[root@localhost ~]</code><code># iptables -V</code>
<code>iptables v1.4.21</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -i lo -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -nL</code>
<code>ACCEPT all -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code>
# CentOS7下iptables的安裝:
<code>CentOS 7 預設使用firewalld來管理iptables規則,由于防火牆規則變動的情況很少,動不動态變得無所謂了。但是總是感覺不太習慣。</code>
<code>使用下面的辦法來恢複原來的習慣,同時解決iptables開機啟動的問題。</code>
<code># yum install iptables-services -y</code>
<code># systemctl enable iptables</code>
<code>這樣的話,iptables服務會開機啟動,自動從</code><code>/etc/sysconfig/iptables</code> <code>檔案導入規則。</code>
<code>為了讓</code><code>/etc/init</code><code>.d</code><code>/iptables</code> <code>save 這條指令生效,需要這麼做</code>
<code># cp /usr/libexec/iptables/iptables.init /etc/init.d/iptables</code>
<code># /etc/init.d/iptables save</code>
<code>而chkconfig iptables 指令會自動重定向到sytemctl </code><code>enable</code> <code>iptables</code>
# 定義iptables預設政策
預設政策的定義格式為:
iptables [-t 表名] <-P> <鍊名> <動作>
檢視iptables的狀态
<code>[root@ip-172-31-22-8 ~]</code><code># /etc/init.d/iptables status</code>
<code>Table: filter</code>
<code>[root@localhost ~]</code><code># iptables -I INPUT -s 10.10.10.0/24 -p tcp --dport 80 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -I INPUT -s 10.10.10.0/24 -p tcp --dport 22 -j ACCEPT</code>
<code>ACCEPT tcp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:22</code>
<code>ACCEPT tcp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:80</code>
5)iptables的狀态state
下面解釋iptables的幾種狀态:
NEW:如果你的主機向遠端主機發出一個請求連接配接,這個資料包的狀态就是NEW
ESTABLISHED:已建立的連接配接(完成TCP的三次握手後),遠端主機和你的主機通信資料狀态為ESTABLISHED
RELATED:正在啟動新連接配接,比如FTP服務傳輸,21端口負責傳送指令,20端口負責傳輸資料,在已有的21端口建立好連接配接後發生指令,這時候20端口或其他端口傳送FTP-DATA,狀态就是RELEATED
INVALID:非法或無法識别的資料包,不能被識别屬于哪個連接配接或者沒有任何狀态,通常這種狀态包會被丢棄
iptables腳本的基本模闆:
<code>#!/bin/bash</code>
<code>#created by molewan 2016/07/16</code>
<code>#email:[email protected]</code>
<code>iptables -F</code>
<code>iptables -F -t nat</code>
<code>iptables -X</code>
<code>iptables -Z</code>
<code>iptables -P INPUT DROP</code>
<code>iptables -A INPUT -m state --state NEW -j DROP</code>
<code>iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT</code>
6)生産環境中我們如何維護我們的iptables
系統運維人員在維護iptables的時候,經常會發現誤操作了iptables導緻無法進入了系統,這個時候隻有去機房重新開機iptables,其實這個也是有辦法解決的,可以通過配置
計劃任務的方式來處理:
<code>[root@ip-172-31-22-8 ~]</code><code># crontab -l</code>
<code>*</code><code>/5</code> <code>* * * * </code><code>/etc/init</code><code>.d</code><code>/iptables</code> <code>stop</code>
7)iptables防火牆應用案例:
案例1:允許任意用戶端通路主機的日常服務(HTTP、HTTPS、DNS、NTP、SMTP、POPS3、SSH)
<code>[root@localhost ~]</code><code># iptables -A INPUT -p tcp --dport 22 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -p udp --dport 25 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -P tcp --dport 53 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -p udp --dport 53 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -p tcp --dport 80 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -p tcp --dport 110 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -p tcp --dport 143 -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -P INPUT DROP</code>
<code>[root@localhost ~]</code><code># iptables -P OUTPUT ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -P FORWARD DROP</code>
<code>Chain INPUT (policy DROP)</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:22</code>
<code>ACCEPT udp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>udp dpt:25</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:53</code>
<code>ACCEPT udp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>udp dpt:53</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:80</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:110</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>tcp dpt:143</code>
<code>Chain FORWARD (policy DROP)</code>
<code>[root@localhost ~]</code><code># cat /etc/services #可以在此檔案中檢視服務的名稱</code>
案例2:公司擁有一個公有IP,使用防火牆實作區域網路中所有主機通過SNAT共享上網。
原理:使用CentOS7作為公司軟路由,将内網192.168.0.0/24的資料包源位址修改為路由器上的公有IP 124.126.199.84,使用SNAT規則,以及NAT表的POSTROUTING鍊
先開啟系統上的路由轉發:
<code># vim /etc/sysctl.conf</code>
<code>net.ipv4.ip_forward = 1</code>
<code># sysctl -p</code>
<code># iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 124.126.199.84</code>
案例3:公司對外有一個公網IP,公司内部有HTTP、MAIL兩台核心伺服器,通過防火牆實作客戶可以從網際網路的任意位置通路公司内部的兩台伺服器資源
<code>拓撲;</code>
<code>Internet <--124.126.199.84(防火牆)-->192.168.0.0</code><code>/24</code>
<code>http:192.168.0.100</code>
<code>postfix:192.168.0.101</code>
<code>處理過程:</code>
<code>開啟路由轉發:</code>
<code>針對80端口的</code>
<code># iptables -t nat -I PREROUTING -d 124.126.199.84 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100</code>
<code>針對25端口和110端口</code>
<code># iptables -t nat -I PREROUTING -d 124.126.199.84 -p tcp --dport 25 -j DNAT --to-destination 192.168.0.101</code>
<code># iptables -t nat -I PREROUTING -d 124.126.199.84 -p tcp --dport 110 -j DNAT --to-destination 192.168.0.101</code>
案例4:目前網絡的攻擊手法層出不窮,很多攻擊會采用發生大量無效的資料包給伺服器,造成伺服器無法響應正常的請求包,iptables提供了一個limit擴充功能,可以限制機關時間内資料包的個數。下面的規則是當每秒鐘資料包個數為500接受入站連接配接,負責拒絕連接配接。
<code>[root@localhost ~]</code><code># iptables -I INPUT -m limit --limit 500/sec -j ACCEPT</code>
<code>ACCEPT all -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>limit: avg 500</code><code>/sec</code> <code>burst 5</code>
<code>target prot opt </code><code>source</code>
案例5:根據資料連接配接狀态設定防火牆規則,放行所有出站資料包,拒絕入站的新連接配接請求和無效連接配接,放行入站的回應請求
<code>[root@localhost ~]</code><code># iptables -X</code>
<code>[root@localhost ~]</code><code># iptables -Z</code>
<code>[root@localhost ~]</code><code># iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT</code>
<code>[root@localhost ~]</code><code># iptables -I INPUT -m state --state NEW -j DROP</code>
<code>DROP all -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>state NEW</code>
<code>ACCEPT all -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>state RELATED,ESTABLISHED</code>
案例6:公司采用基于Linux的軟路由裝置,要求在路由裝置上設定防火牆規格,記錄10.0.0.1至10.0.0.128位址段内所有的主機發送給路由要求轉發的資料包,并允許轉發這些資料包
<code>[root@localhost ~]</code><code># iptables -A FORWARD -m iprange --src-range 10.0.0.1-10.10.0.11 -p tcp --dport 80 -j LOG</code>
<code>[root@localhost ~]</code><code># iptables -A FORWARD -m iprange --src-range 10.0.0.1-10.10.0.11 -p tcp --dport 80 -j ACCEPT[root@localhost ~]# iptables -n -L</code>
<code>LOG tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>source</code> <code>IP range 10.0.0.1-10.10.0.11 tcp dpt:80 LOG flags 0 level 4</code>
<code>ACCEPT tcp -- 0.0.0.0</code><code>/0</code> <code>0.0.0.0</code><code>/0</code> <code>source</code> <code>IP range 10.0.0.1-10.10.0.11 tcp dpt:80</code>
一次性允許多端口通過:
<code>[root@localhost ~]</code><code># iptables -I INPUT -s 10.10.10.0/24 -p tcp -m multiport --dport 21,22,23,80 -j ACCEPT</code>
<code>ACCEPT tcp -- 10.10.10.0</code><code>/24</code> <code>0.0.0.0</code><code>/0</code> <code>multiport dports 21,22,23,80</code>
本文轉自 冰凍vs西瓜 51CTO部落格,原文連結:http://blog.51cto.com/molewan/1900163,如需轉載請自行聯系原作者