Iptables 實操

HammerZe發表於2021-12-27

Iptables之實操

image

簡介

Netfilter/Iptables (以下簡稱Iptables)是unix/linux自帶的一款優秀且開放原始碼的完全自由的基於包過濾的防火牆工具,它的功能十分強大,使用非常靈活,可以對流入和流出伺服器的資料包進行很精細的控制。特別是它可以在一臺非常低的硬體配置下跑的非常好(本人曾經在賽揚500HZ cpu 64M記憶體的情況部署閘道器防火牆)提供近400人的上網服務絲毫不遜色企業級專業路由器防火牆)
Iptables是linux 2.4及2.6核心中整合的服務。其功能與安全性比其老一輩Ipfwadn,ipchains強大的多,Iptables主要工作在OSI七層的二、三四層,如果重新編譯核心,Iptables也可以支援7層控制(squid 代理+iptables)。

名稱概念:

  • 容器:包含或者說屬於的關係

  • Netfilter/Iptables是表(四表)的容器

  • 四表

    • filter:過濾資料包
    • nat:用於網路地址轉換(IP、埠)
    • mangle:修改資料包的服務型別、TTL、並且可以配置路由實現QOS
    • raw表:決定資料包是否被狀態跟蹤機制處理
    • 前三個常用
  • IP tables的表又是鏈(五鏈)的容器

    • INPUT鏈:過濾進入主機的資料包
    • OUTPUT鏈:處理從主機發出去的資料包
    • FORWARD鏈:負責轉發流經主機的資料包,起轉發的作用,和Nat表關係很大
    • PREROUTING鏈:主機外報文進入位置,所有的資料包進來的時侯都先由這個鏈處理
    • POSTROUTING鏈:報文經過路由被轉發出去,所有的資料包出來的時侯都先由這個鏈處理
    • 注意鏈名大寫
  • 鏈(chains)是規則的容器

  • 規則(policy):一條條過濾的語句

注意:對於filter表的控制是我們實現本機防火牆功能的重要手段,特別是對INPUT鏈的控制

四表中常用的表

Nat表

負責網路地址轉換,即來源與目的ip地址和port的轉換。應用:和主機本身無關。一般用於區域網共享上網或者特殊的埠轉換服務相關
NAT功能一般企業工作場景:
1))用於做企業路由(zebra)或閘道器(iptables),共享上網(POSTROUTING)2)做內部外部P地址一對一對映(dmz),硬體防火牆對映I到內部伺服器,ftp服務。(PREROUTING).
3 ) web,單個埠的對映,直接對映80埠(PREROUTING)。
這個表定義了三個鏈(Chains),nat 功能就相當於網路的 acl控制。和網路交換機 acl類似

表相關的鏈

  • OUTPUT:和主機發出去的資料包相關
  • INPUT:和進入主機的資料包相關
  • PREROUTING:資料包到達防火牆時進行路由判斷之前執行的規則,作用是改變資料包的目的地址,埠等,(通俗比喻,就是收信時,根據規則重寫收件人的地址,這看上去很不地道啊!哈哈。)例如:把公網IP:124.42.60.113對映到區域網的10.0.0.19伺服器上。如果是web服務,可以把80轉為區域網的伺服器上9000埠。
  • POSTROUTING:在資料包離開防火牆時進行路由判斷之後執行的規則,作用是改變資料包的源地址、源埠等,(通俗比喻,就是寄信時,寫好發件人的地址,要讓人家回信時能夠有地址可回。) ,例如:我們現在的筆記本和虛擬機器都是10.0.0.0/24,就是出網的時候被我們企業路由器把源地址改成了公網地址了。生產應用:區域網共享上網。

Filter表

強調:主要和主機自身有關,真正負責主機防火牆功能的(過濾流入流出主機的資料包)。filter表是iptables 預設使用的表。這個表定義了三個鏈(Chains):.企業工作場景:主機防火牆。

表相關的鏈

  • INPUT負責過濾所有目標地址是本機地址的資料包。通俗的講,就是過濾進入主機的資料包
  • FORWARD:負載流經主機的資料包,作用是轉發的功能,和nat表關係很大
  • OUTPUT:負責處理從主機發出去的資料包

Iptables過程(寫這助理解)

流入本機:PREROUTING  -->  INPUT  --> PROCESS(程式)
經過本機:PREROUTING  --> FORWARD --> POSTROUTING
從本機流出:PROCESS(程式) -->  OUTPUT --> POSTROUTING

iptables表和鏈的工作流程圖

image


iptables過濾圖

iptables是採用資料包過濾機制工作的,所以它會對請求的資料包的包頭資料進行分析,並根據我們預先設定的規則進行匹配來決定是否可以進入主機。

image

* 防火牆是層層過濾的。實際是按照配置規則的順序從上到下,從前到後進行過濾的
* 如果匹配上規則,即明確表明是阻止還是通過,資料包就不再向下匹配新規則了
* 如果所有規則中沒有明確表明是阻止還是通過,也就是沒有匹配規則,向下進行匹配直到匹配預設規則得到明確的阻止還是通過
* 防火牆預設規則是對應鏈的所有的規則執行完才會執行的
* Iptalbes防火牆規則的執行順序預設從前到後(從上到下)依次執行,遇到匹配的規則就不在繼續向下檢查,只有遇到不匹配的規則才會繼續向下進行匹配。
	
# 注意 :拒絕規則DROP如果寫在最上層,下面的規則都將不匹配執行,所以插入新的規則可以用-I引數插到最上層

Iptables安裝

  • 檢視是否安裝了iptables:systemctl status iptables
  • 安裝iptables:yum install iptables* -y
  • 啟動iptables:systemctl start iptables
  • 關閉防火牆: systemctl disable --now firewalld
  • 關閉selinux:vim /etc/selinux/config

image


Iptables 命令說明

格式:iptables [-t 表名] [引數 鏈名] [引數 協議] [引數 埠] [引數 動作]

參數列如下:

引數符號 說明
-t 指定操作的表
-L 列出當前的規則
-v 顯示資料包和資料包大小
-n 不反解地址
-A 追加一條規則到鏈中
-I 插入一條規則,插入到頂部
-F 清空
-Z 清空計數器(包數量 、包大小)
-D 刪除鏈中的規則
-R 修改規則
-S 列出所有的規則
-N 建立一個自定義鏈
-X 刪除一個自定義鏈
-P 指定鏈的預設策略

iptables使用協議表如下:

條件/協議名 說明
TCP 按TCP協議匹配,http歸屬到TCP中
UDP 按UDP協議匹配
ICMP 按ICMP協議匹配,類似ping
ALL 所有協議都可以

?[UDP協議和TCP協議](TCP/UDP協議_百度百科 (baidu.com))

?[ICMP協議](ICMP_百度百科 (baidu.com))

埠搭配引數

引數 說明
--sport 源埠,傳送請求的埠
--dport 目標埠,訪問的埠

” 動作 “ 表如下:

“動作名” 說明
ACCEPT 將資料包放行,進行完此處理動作後,將不再比對其它規則,直接跳往下一個規則鏈
REJECT 攔阻該資料包,並傳送資料包通知對方
DROP 丟棄包不予處理,進行完此處理動作後,將不再比對其它規則,直接中斷過濾程式
REDIRECT 將包重新導向到另一個埠,進行完此處理動作後,將會繼續比對其它規則

-i,-o,-m,-j,-s,-d引數,可以指定網路卡,模組,動作,協議,地址

引數 說明
-i 進來的網路卡
-o 出去的網路卡
-m 指定模組
-j 執行的動作(上表)
-p 指定協議
-s 源地址,傳送請求的地址
-d 目標地址,訪問的地址

Iptables常用命令

iptables -h 查詢幫助

iptables -L -v 列出(filter表)所有規則

iptables -L -n 列出(filter表,預設的)所有規則(區別-v,-n是不反解版)

iptables -L -n -t nat 列出(nat表)所有規則

iptables -F 清除(filter表)所有規則

iptables -F -t nat 清除(nat表)中所有規則

service iptables save 儲存配置(儲存配置後必須重啟iptables)

systemctl restart iptables 重啟

Iptables常用語法

-A:追加到規則的最後一條

-D:刪除記錄

-I:新增到規則的第一條

-p:(proto)規定通訊協議,常見的協議有:tcp、udp、icmp、all

-j:(jump)指定要跳轉的目標,常見的目標有:ACCEPT(接收資料 包)、DROP(丟棄資料包)、REJECT(重定向)三種,但是一 般不適用重定向,會帶來安全隱患

常見案例

案例1:只允許22埠(目標埠)可以訪問,其他埠全部無法訪問
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 22 -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP
[root@m01 ~]# iptables -L -v
# 檢視(結果太長不寫了)
[root@m01 ~]# iptables -L -v

案例2:只允許22,80,443埠可以訪問(目標埠),其他埠全部無法訪問。 
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 22  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 80  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 443  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP   -j DROP
# 這時獲取百度就響應超時了,不知道curl的埠
[root@m01 ~]# curl www.baidu.com
curl: (7) Failed connect to www.baidu.com:80; Connection timed out

案例3:只允許22,80,443埠可以訪問,其他埠全部無法訪問,但是本機可以訪問百度。 
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 22  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 80  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 443  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP

案例4:要求能夠通過22埠(目標埠)去連結地址192.168.15.81(目標地址),但是其他的不行
# 通俗理解:通過22埠可以連線到192.168.15.81地址,192.168.15.81:22
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -d 192.168.15.81 --dport 22  -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP
# 可以通過新開視窗測試,或者新開虛擬機器測試	

案例5:要求地址192.168.15.71(源地址)允許通過22埠(目標埠)連線地址192.168.15.81(目標地址),其他不行
[root@m01 ~]# iptables -t filter -A INPUT -p  TCP -s 192.168.15.71  -d 192.168.15.81 --dport 22 -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP
# 可以從71去連線81,81已經斷開

案例6:要求192.168.15.71對外部不可見
[root@prometheus ~]# iptables -t filter -A INPUT -p TCP -d 192.168.15.71 -j DROP
# 相當於虛擬機器裡的這個地址對外不可見,會連線不上虛擬機器

案例7:要求使用eth0網路卡的所有請求全部拒絕(進來的網路卡,連線虛擬機器)
[root@prometheus ~]# iptables -t filter -A INPUT -p TCP -i etho -j DROP
案例8:使用eth1網路卡登入進來的視窗,不允許訪問百度。(出去的網路卡,連線虛擬機器)
[root@prometheus ~]# iptables -t filter -I OUTPUT -p TCP -o eth1 -j DROP

案例9:要求訪問伺服器的8080埠轉發至80埠
[root@m01 ~]# iptables -t nat -A PREROUTING -p TCP --dport 8080 -j REDIRECT --to-port 80

案例10:要求只允許windows通過ssh連線192.168.15.81,其他的拒絕
# 先檢視windows下的地址:ipconfig > WMnet8 >IPV4地址
[root@m01 ~]# iptables -t filter -I INPUT -p TCP -s 192.168.15.1 -d 192.168.15.81 --dport 22 -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 22 -j DROP


# IP過濾
# 禁止192.168.1.3 IP地址的所有型別資料訪問
iptables -A INPUT ! -s 192.168.1.3 -j DROP

# 開放80埠
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #開放80埠

# 開放埠範圍
iptables -I INPUT -p tcp --dport 22:80 -j ACCEPT #開發22-80範圍的埠

# 不允許80埠流出
iptables -I OUTPUT -p tcp --dport 80 -j DROP

# filter是預設的表,可以不指定,也可以指定



模組

-m:指定模組

multiport模組

連續匹配多個埠

  • 引數:--dports 的意思是指定多個埠(不同埠之間以逗號分割,連續的埠使用冒號分割)
# 案例:要求將22,80,443以及30000-50000之間所有的埠向外暴露,其他埠拒絕
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -m multiport --dports 22,80,443,30000:50000 -j ACCEPT
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP

iprange模組

指定一段連續的ip地址範圍

  • 引數:
    • --src-range from[-to]:源地址範圍
    • --dst-range from[-to]:目標地址範圍
# 案例:要求192.168.15.1 - 192.168.15.10之間的所有IP能夠連線192.168.15.81,其他拒絕
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -m iprange --src-range 192.168.15.1-192.168.15.10 -j ACCEPT 
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -j DROP

string模組

匹配指定字串

  • 引數
    • --string pattern :指定要匹配的字串
    • --algo {bm|kmp} :匹配的查詢演算法
# 案例:要求訪問資料包中包含HelloWorld的資料不允許通過
[root@m01 ~]# cd /usr/share/nginx/html/
[root@m01 html]# rm -rf ./*
[root@m01 html]# echo "Helloworld" > index.html
[root@m01 html]# echo "Hello" > demo.html

# 規則
[root@m01 html]# iptables -t filter -A INPUT -p TCP -m string --string "Helloworld" --algo kmp -j DROP

[root@m01 html]# curl http://192.168.15.81/demo.html
Hello
[root@m01 html]# curl http://192.168.15.81/index.html


# Helloworld被過濾掉了

time模組

根據時間段匹配資料包

  • 引數:
  • --timestart hh:mm[:ss] :開始時間
  • --timestop hh:mm[:ss] : 結束時間
  • --monthdays day[,day...] : 指定一個月的某一天
  • --weekdays day[,day...] : 指定周 還是 周天
# 案例: 要求每天的22到23之間,不允許訪問
[root@m01 ~]# iptables -t filter -A INPUT -p TCP -m time --timestart 14:00  --timestop 15:00 -j DROP

# 注意這裡使用的時間是UTC,記得-8

icmp模組

禁ping, 預設本機無法ping別人 、別人無法ping自己

  • 引數:--icmp-type {type[/code]|typename}
  • echo-request (8) 請求
  • echo-reply (0) 回應
# 要求別人不能ping本機,但是本機可以ping別人(優化上普通案例3)
[root@m01 ~]# iptables -t filter -A INPUT -p ICMP -m icmp --icmp-type "echo-request" -j DROP
# 本機ping百度
[root@m01 ~]# ping www.baidu.com
PING www.a.shifen.com (112.80.248.76) 56(84) bytes of data.
64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=1 ttl=128 time=15.1 ms
# 別人不能ping本機
[root@m01 ~]# ping 192.168.15.81
PING 192.168.15.81 (192.168.15.81) 56(84) bytes of data.

connlimit模組

限制連結數,併發連線數

  • 引數
    • --connlimit-upto n : 如果現有連線數小於或等於 n 則 匹配
    • --connlimit-above n : 如果現有連線數大於n 則匹配
# 要求主機連線最多有2個(最多開兩個視窗)
[root@m01 ~]# iptables -t filter -A INPUT -p TCP --dport 22 -m connlimit --connlimit-above 2 -j DROP

image


limit模組

針對 報文速率 進行限制; 秒、分鐘、小時、天。

  • 引數
    • --limit rate[/second|/minute|/hour|/day] :報文數量
    • --limit-burst number :報文數量(預設:5)
# 案例 :要求限制速率在500k/s左右,大約每秒為333個資料包
# 生成一個測試檔案
[root@m01 ~]# dd if=/dev/zero of=a.txt bs=100M count=10
10+0 records in
10+0 records out
1048576000 bytes (1.0 GB) copied, 7.64477 s, 137 MB/s
# 限速(控制是不準確的!)
[root@m01 ~]# iptables -t filter -A OUTPUT -p TCP -m limit --limit 333/s -j ACCEPT
[root@m01 ~]# iptables -t filter -A OUTPUT -p TCP -j DROP
	
# 傳輸
[root@m01 ~]# scp a.txt root@192.168.15.71:/root

image

傳輸是不準確的,慢慢在降低,直到穩定!


補充知識:

檢視centos版本

cat    /etc/redhat-release       

檢視本機埠占用的命令:

命令:netstat -nutlp

[root@m01 ~]# netstat -nutlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1591/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1304/sshd           
tcp6       0      0 :::80                   :::*                    LISTEN      1591/nginx: master  
tcp6       0      0 :::22                   :::*                    LISTEN      1304/sshd 

iptables指令碼設定

#!/bin/sh
iptables -P INPUT ACCEPT
iptables -F
iptables -X
iptables -Z
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
service iptables save
systemctl restart iptables.service

補充案例

企業案例

如果日誌檔案/var/logmessages出現:kernel:nf_conntrack:table full,droppint packet,解決辦法如下:

# 上述的結果會讓業務訪問的很慢
net.nf_conntack_max = 250000000
net.netfilter.nf_conntrack_max = 250000000
# 響應時間調短
net.netfilter.nf_conntrack_timeout_established = 170
net.netfilter.nf_conntrack_timeout_wait = 120
net.netfilter.nf_conntrack_timeout_close_wait= 60
net.netfilter.nf_conntrack_timeout_fin_wait = 100

易錯點

設定完iptables規則後儲存(service iptables save)有時候啟動會失敗

在第一步的時候安裝iptables時,請用 yum install -y iptables,加上,不然有些包裝不上,系統預設安裝的包不齊全

在過濾埠的時候,容易把自己幹掉,從虛擬機器上清除掉所有規則就好


【有錯請指正,感謝指正】


image

相關文章