1. 程式人生 > >第十四課 主機防火牆(上)

第十四課 主機防火牆(上)

目錄

  1. 防火牆簡介
  2. iptables 與 firewalld
  3. iptables 基礎
    3.1 鏈的概念
    3.2 表的概念
    3.3 鏈與表的關係
    3.4 資料通過的流程
  4. iptables 語法
  5. iptables nat表的應用

1. 防火牆簡介

防火牆是一種應用於網路上的過濾機制,從保護物件上可分為:主機防火牆、網路防火牆,從物理上可分為:硬體防火牆、軟體防火牆

  • 保護物件上的分類:

    • 主機防火牆:針對於單個主機進行防護
    • 網路防火牆:往往部署於網路邊界,對流入以及流出的流量進行過濾
  • 物理上的分類:

    • 硬體防火牆:擁有經過特別設計的硬體及晶片,效能高、成本高
    • 軟體防火牆:應用軟體處理邏輯運行於通用硬體平臺之上的防火牆,效能低、成本低

2. firewalld 與 iptables

2.1 異同點

  • 相同點:firewalld 與 iptables 都是 Linux 中防火牆的管理程式,但其實其角色主要為對於防火牆策略的管理,真正的防火牆執行者是位於核心中的 Netfilter。

  • 不同點:

    • iptables 僅能通過命令列進行配置;而 firewalld提供了圖形介面,類似windows防火牆的操作方式
    • iptables 每一個單獨更改意味著清除所有舊的規則,並從 /etc/sysconfig/iptables 中讀取所有新的規則;而 firewalld 在有規則變動後,可以僅僅執行規則中的不同之處,即在 firewalld 執行時間內,改變設定時可以不丟失現行連結
    • iptables 的配置檔案在 /etc/sysconfig/iptables 中;而 firewalld 的配置檔案在 /usr/lib/firewalld/ 和 /etc/firewalld/ 中的各種 XML 檔案中
    • iptables 沒有守護程序,並不能算是真正意義上的服務;而 firewalld 有守護程序

2.2 關閉 firewalld,開啟 iptables

2.2.1 關閉 firewalld
  • 關閉 firewalld 服務:syctemctl stop firewalld
  • 禁用 firewalld 服務:systemctl disable firewalld
2.2.2 開啟 iptables
  • 安裝 iptables:yum -y install iptables-services
  • 啟用 iptables:systemctl enable iptables
  • 開啟 iptables:systemctl start iptables

3. iptables 基礎

iptables 準確來講並不是防火牆,真正的防火牆是運行於系統核心中的 netfilter,而 iptables 僅僅是 netfilter 的代言人,其所負責的主要功能便是與使用者互動,獲取到使用者的要求,並轉化成 netfilter 可以接受的資訊。

  • 防火牆的實現機制
    防火牆的核心處理機制是過濾,而說到過濾,就必須具有“條件 & 動作”這兩個關鍵要素,而在 iptables 中,這兩種要素分別叫做“rule & target”,可以理解成符合 rule 的流量將會去往 target。

  • 匹配規則的要素
    防火牆的處理物件是網路流量,而對於網路流量來講,標識流量的最重要的資訊便是五元組,包括:S_IP, S_PORT, D_IP, DI_PORT, TCP/UDP,iptables 常用的也往往是根據五元組中的某個或某些要素進行過濾

舉個栗子
防火牆的主要功能是過濾,那我們不妨把防火牆看成是個社群的廢水處理廠,負責將社群的生活廢水收集起來,經過多道工序的處理後,返還給社群。
:既然是要處理廢水,那我們首先要在廢水處理的個別關鍵環節上設定集中處理的“處理鏈”,在“處理鏈”中放置各種不同的過濾網、膜以及化學配方。
:即便是不同的處理鏈中,可能會用到一些相同的處理技術,比如粗濾膜、細濾膜,為了方便這些技術的複用,廢水處理廠將功能類似的處理技術封裝成集合,這樣能夠更加方便地使用

3.1 鏈的概念

3.1.1 什麼是鏈?

就是從報文進入到報文離開這整個期間,計算機處理報文的關鍵環節。
就好比汙水處理廠,汙水進入前得處理一下,進入後得沉澱一下,送回時又得進行一些處理,那麼這3個節點就是關鍵環節。

3.1.2 為何叫做鏈?

因為防火牆是對報文進行規則匹配,然後執行相應動作。但在關鍵環節上,往往不止一條規則,而是有大量的規則,而且這些規則都是按順序排列的,待匹配的報文需要按順序一個一個規則的進行匹配,直到匹配到一條規則為止,所以在每個關鍵環節上的匹配過程,就像是一條有順序的鏈。
好比汙水處理廠,必須在個別關鍵環節部署處理措施,比如在進入廢水廠時,先進行一批處理。處理可能包括粗濾、細濾等各種方式,而且各種方式不能隨意排列,必定是按照一定的順序依次進行,比如先粗濾,再細濾。

3.1.3 iptables 有哪些鏈?

記住,鏈其實就是報文處理的重要環節,所以很容易就得出有以下兩個重要環節:
* INPUT:進入主機
* OUTPUT:離開主機

但還有一種複雜的情況,就是報文的目標並不是本主機,而只是借道本主機,希望通過本主機去往下一臺主機。
就好比我們的這個汙水處理廠只處理生活汙水,並不具備能力可以完全處理工業汙水,但是政府又要求我們要對工業汙水進行一下簡單的處理,之後再傳送給工業汙水處理廠。那麼就容易得出以下兩個重要環節(鏈):

  • PREROUTING:路有前
  • FORWARD:轉發
  • POSTROUTING:路由後

3.2 表的概念

3.2.1 什麼是表?

在每個鏈上都有一堆規則,但是部分規則是相似的,那我們把一些實現相同功能的規則放在一起,就能輕鬆的完成複用了。
好比汙水處理廠,粗濾、細濾基本上是好多關鍵環節都要用到的,那何不將粗濾網與細濾網直接封裝到一根管子裡,要用的時候,直接整根管子接上去就能一次實現兩個功能,豈不方便?

3.2.2 iptables 提供了哪些表?
  • filter:負責過濾功能,核心模組 iptables_filter
  • nat:負責進行網路地址轉換,核心模組 iptable_nat
  • mangle:拆解報文,進行修改,重新封裝,核心模組 iptable_mangle
  • raw:關閉 nat 表上啟用的連線追蹤機制,核心模組 iptable_raw
  • security:安全相關?CentOS 7 裡新增的表,暫且不介紹

ps. 運維中常用的為 filter、nat

3.3 鏈與表的關係

現在應該清楚:鏈是報文流轉過程中的關鍵處理環節,表是某一些相似規則的集合

3.3.1 鏈中的表

但是由於處理環節的分工不同,每個處理環節可能具有不同的表,讓我們看看5個環節中,每個環節都有哪些表

3.3.2 表對應的鏈

但是,實際使用中,往往是以“表”作為操作入口來對規則進行定義的,所以比起知道某個鏈中存在哪些表,不如明確每種表能夠應用於哪些鏈中,這樣能方便實際的使用。

3.3.3 表的優先順序

由上可知,每個鏈中包含多個表。
但是還記得規則是有順序的嗎?那問題來了,同一條鏈中,到底哪個表被先執行呢?

表的優先順序

3.4 規則的概念

之前已經講過,規則主要包含兩部分,即“條件 & 動作”

3.4.1 匹配條件

iptables 主要是通過網路流量的五元組(某個或某些)來進行匹配,包括:
* S_IP:源 IP
* S_PORT:源埠
* D_IP:目的 IP
* D_PORT:目的埠
* TCP/UDP:四層協議

3.4.2 處理動作

iptables 中稱為 target

  • ACCEPT:允許資料包通過。
  • DROP:直接丟棄資料包。不迴應任何資訊,客戶端只有當該連結超時後才會有反應。
  • REJECT:拒絕資料包。會給客戶端傳送一個響應的資訊 。
  • SNAT:源 NAT,解決私網使用者用同一個公網 IP 上網的問題。
  • MASQUERADE:是 SNAT 的一種特殊形式,適用於動態的、臨時會變的 IP 上。
  • DNAT:目的 NAT,解決私網服務端,接收公網請求的問題。
  • REDIRECT:在本機做埠對映。
  • LOG:在 /etc/log/messages 中留下記錄,但並不對資料包進行任何操作。

4. iptables 常用語法

使用 iptables 時,最常用的就是對規則、表進行“增刪改查”

4.1 查詢

4.1.1 Options
  • -L:負責查詢的主要選項
  • -n:不進行IP地址翻譯
  • -v:顯示詳細資訊,包括:命中規則的包數&位元組數、預設策略的包數&位元組數、入向介面,
  • -t <TABLE>:指定需要檢視的表,若不加該選項,預設查詢 filter
  • --line:顯示各鏈的規則行號
4.1.2 簡單檢視

$ iptables -L

$ iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    
  • Chain:所屬的鏈
  • (policy ACCEPT):該鏈的預設規則
  • target:對應的處理動作
  • prot:對應的協議
  • opt:規則對應的選項
  • source:對應的源 IP 地址或網段
  • destination:對應的目的 IP 地址或網段
4.1.3 檢視命中數:-v

iptables -vL

$ iptables -vL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 1305  102K ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  any    any     anywhere             anywhere            
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            
    1    52 ACCEPT     tcp  --  any    any     anywhere             anywhere             state NEW tcp dpt:ssh
    7  1150 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 964 packets, 134K bytes)
 pkts bytes target     prot opt in     out     source               destination   
  • pkts:命中規則的報文個數
  • bytes:命中規則的報文大總和
  • in:規則對應的入向介面
  • out:規則對應的出向介面
4.1.4 檢視特定的表:-t <TABLE>

$ iptables -t filter -L
竟然發現跟 -L 顯示的一模一樣?
翻到前面,看看 filter 表可以在哪些鏈中使用?是不是正好就是 INPUT、FORWARD、OUTPUT 這三條鏈啊!

$ iptables -t filter -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   
4.1.5 檢視特定的鏈

iptables -L <CHAIN>

$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target  prot opt in  out     source          destination         
 1256 98520 ACCEPT  all  --  *   *    0.0.0.0/0       0.0.0.0/0       state RELATED,ESTABLISHED
    0     0 ACCEPT  icmp --  *   *    0.0.0.0/0       0.0.0.0/0           
    0     0 ACCEPT  all  --  lo  *    0.0.0.0/0       0.0.0.0/0           
    1    52 ACCEPT  tcp  --  *   *    0.0.0.0/0       0.0.0.0/0       state NEW tcp dpt:22
    6   921 REJECT  all  --  *   *    0.0.0.0/0       0.0.0.0/0       reject-with icmp-host-prohibited
4.1.6 顯示規則行號:--line
$ iptables -t filter -nvL --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     1542  121K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
2        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
4        1    52 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
5       11  1613 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 1142 packets, 153K bytes)
num   pkts bytes target     prot opt in     out     source               destination   

4.2 增加

4.2.1 Options
  • -I <CHAIN>:insert,插入,排序在指定鏈的規則的首位
  • -I <CHAIN> #:插入到指定鏈的第 # 號規則的位置
  • -A <CHAIN>:append,追加,排序在指定鏈的規則的末尾
  • -s <S_IP>:指定源 IP
  • -j <ACTION>:指定執行的動作,具體動作型別見 3.4.2
4.2.2 插入規則到首位
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 102 packets, 8892 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
$ iptables -t filter -I INPUT -s 1.1.1.1 -j DROP
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 43 packets, 3020 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
4.2.3 插入規則到指定號碼
Chain INPUT (policy ACCEPT 279 packets, 21604 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
3        0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
4        0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
$ 
$ 
$ iptables -I INPUT 3 -s 3.3.3.3 -j ACCEPT
$ iptables -nvL INPUT --line
Chain INPUT (policy ACCEPT 5 packets, 388 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
3        0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
4        0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
5        0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0    
4.2.4 追加到末位
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 50 packets, 3592 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
$ iptables -A INPUT -s 255.255.255.255 -j ACCEPT
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 36 packets, 2600 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       255.255.255.255      0.0.0.0/0  

4.3 刪除

4.3.1 Options
  • -D <CHAIN> <DETAILS>:根據規則的具體匹配條件與動作進行刪除
  • -D <CHAIN> #:根據規則的編號進行刪除
  • -F <CHAIN>:清空指定鏈上的所有規則
  • -t <TABLE> -F:清空某種表在所有鏈上的規則
4.3.2 根據規則的具體情況進行刪除

跟新增時的命令幾乎一模一樣

$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 78 packets, 5684 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       255.255.255.255      0.0.0.0/0           
$ iptables -D INPUT -s 1.1.1.1 -j DROP
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 5 packets, 388 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
    0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       255.255.255.255      0.0.0.0/0       
4.3.3 根據規則編號進行刪除
$ iptables -nvL INPUT --line
Chain INPUT (policy ACCEPT 32 packets, 2417 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
3        0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
4        0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
5        0     0 ACCEPT     all  --  *      *       255.255.255.255      0.0.0.0/0           
$ iptables -D INPUT 5
$ iptables -nvL INPUT --line
Chain INPUT (policy ACCEPT 35 packets, 2784 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
3        0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
4        0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0       
4.3.4 清空

iptables -F <CHAIN> # 清空鏈下的所有規則
iptables -t <TABLE> -F # 清空某個表中、所有鏈上的規則

4.4 修改

說是修改,可能本以為只要在命令中輸入所需修改部分的內容即可,但其實不然。想要修改,必須要像新增時一樣輸全了匹配規則,只是修改的部分進行更改,所以也是麻煩,有時不如刪掉再寫一條來得乾淨。

4.4.1 Options
  • -R <CHAIN> #:修改指定鏈中指定序號的規則
4.4.2 修改指定鏈中指定序號的規則
  • 看一下當前 INPUT 鏈的規則
$ iptables -nvL INPUT --line
Chain INPUT (policy ACCEPT 106 packets, 8413 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
3        0     0 LOG        all  --  *      *       11.11.11.11          0.0.0.0/0            LOG flags 0 level 4
4        0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0   
  • 將 3號規則改為 REJECT(僅鍵入待修改部分)
    怎麼剛一設定完就斷了?
$ iptables -R INPUT 3 -j REJECT
$ 
Socket error Event: 32 Error: 10053.
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(CentOS_7_1804_x64) at 17:23:56.

Type `help' to learn how to use Xshell prompt.
[E:\~]$ 

我們進 tty 看一下到底是怎麼回事。怎麼源 IP 變成 0.0.0.0 (相當於 all)了,當SSH 當然就斷了!


這就是本節開始時所講的,並不是僅鍵入待修改的那部分資訊即可,而需要完整的輸入整條規則,看看下面這個例子。

  • 將 3 號規則改回原樣(全面輸入)
    這回終於可以了

4.5 修改鏈的預設動作

4.5.1 Options
  • -P <CHAIN> <ACTION>:修改指定鏈的預設動作
4.5.2 示例
  • 看看當前 INPUT 鏈的預設動作
$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 104 packets, 9184 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       12.12.12.12          0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       3.3.3.3              0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       11.11.11.11          0.0.0.0/0           
    0     0 DROP       all  --  *      *       10.10.10.10          0.0.0.0/0           
  • 改為 DROP(又得掉線了)
    $ iptables -P INPUT DROP

  • 上 tty 去看一眼,果然改成 DROP 了

5. iptables nat表的應用