[TOC]
# Netfilter網絡框架
防火墻(iptables)基于Netfilter(http://www.netfilter.org/ )實現,它在Linux內核中的一個軟件框架,用于管理網絡數據包。不僅具有網絡地址轉換(NAT)的功能,也具備數據包內容修改、以及數據包過濾等防火墻功能。
# 防火墻的備份與恢復
我們來看一下防火墻的備份與恢復,在使用它前建議提前備份這是一個不錯的習慣。
1.查看當前規則。
```
iptables -L -nv --line
```
2.通過iptables-save + “>” 將當前iptables規則備份在文件中。
```
iptables-save > iptables.2020.10.1
```
3. 通過iptables-restore命令來恢復之前備份好的防火墻規則。
```
iptables-restore < iptables.2020.10.1
```
# 防火墻編程基礎
學習防火墻編程的順序(Tables(表) -> Chains (鏈)-> Rules(規則))
## 表與鏈
火墻(iptables) 分為常用的表和鏈,先介紹三張表分別為:
* filter 過濾數據
* nat 轉發數據
* mangle 數據包打標記
根據每張表的不同常用的鏈如下:
* INPUT 用于匹配進入的數據包
* OUTPUT 用于匹配出的數據包
* FORWARD 用于匹配轉發的數據包
* PREROUTING 用于匹配NAT之前的數據包
* POSTROUTING 用于匹配NAT之后的數據包
## 防火墻數據生命周期流程

## Filter 表
Filter表主要用戶數據包的過濾。
### 操作命令
\-A {-C | -D} , -A (append) 追加一條規則到防火墻中; -C (check) 檢測一條規則是否存在 ;-D 刪除一條規則。
```
# 追加一條規則到防火墻中
iptables -t filter -A INPUT -j DROP
# 刪除一條已經存在的防火墻規則
iptables -t filter -D INPUT 1 (規則id,可以通過iptalbes -L -nv --line 查到)
# 確認當前規則是否存在
iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
echo $?
1
iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT
iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
echo $?
0
```
\-I 插入規則。
```
iptables -t filter -I INPUT 1 (插入序號)
```
-R 替換規則
-P 設置鏈的目標規則
-F 清空規則
```
# 清空INPUT鏈規則
iptables -t filter -F INPUT
# 清空OUTPUT鏈的規則
iptables -t filter -F OUIPUT
```
-E 修改鏈名
```
iptables -E 源表名 新表名
```
-Z 清空計數器
```
iptables -Z INPUT
```
-N 創建一個自定義鏈
```
iptables -N test
```
-X 刪除自定義鏈
```
iptables -X test
```
### 參數
* \-p 接協議 udp、tcp、icmp
* \-s 接源地址IP或IP段
* \-d 接目的地址IP或IP段
* \-i 進數據的網卡,如eth0
* \-o 出數據的網卡,如eht0
### 擴展匹配
* \--dport 通常與-p連用,-p后可以接--dport ,但沒有-p 參數無法使用--dpport參數
* \--sport 通dport相同
* \--tcp-flag 如 SYN, ACK, FIN, RST
* \--mac-source 匹配硬件地址
* \--limit 可賦的值有'/second', '/minute', '/hour', or '/day'這樣的單位,默認是3/hour
* \--limit-burst number?匹配最大值
* \--multiport 可以將多個規則轉為一個規則
### owner
* \--uid-owner uid 通常用于OUPUT表出數據的uid控制
* \--gid-owner gid 通常用于OUTPUT表出數據的gid控制
* \--sid-owner seessionid? 通常用于OUTPUT表數出數據的會話控制
### 狀態防火墻
\--state state 可能的狀態是:INVALID表示包是未知連接,ESTABLISHED表示是雙向傳送的連接,NEW 表示包為新的連接,否則是非雙向傳送的,而RELATED表示包由新連接開始,但是和一個已存在的連接在一起,如FTP數據傳送,或者一個ICMP錯誤。
### IP數據包打標簽
\--tos tos 這個參數可以是一個標準名稱,(用iptables -m tos -h 察看該列表),或者數值
### 日志記錄
* \--log-level level?
* \--log-prefix prefix?
* \--log-tcp-sequence?
* \--log-tcp-options
### Filter表綜合案例
**案例1**
允許本服務器的80、443和22對外提供訪問,同時支持icmp協議。
```
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A INPUT -j DROP
```
升級一下規則:
* 22端口只準許202.106.184.183這個服務器訪問
* 支持本地回環訪問
* 將80和443規則合并為1條提高效率
* 支持狀態防火墻
```
iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A INPUT -p tcp -m multiport --dport 80,443 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -t filter -A INPUT -p -s 202.106.184.183 tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A INPUT -j DROP
```
**案例2**
1.準許某個網段訪問。
```
iptables -A OUTPUT -p tcp -d 192.168.100.0/24 --dport 22 -j ACCEPT
```
2.禁止icmp協議。
```
iptables -A INPUT -p icmp -j DROP
```
3.如果你的網絡中有兩塊網卡分別為eth0和eht1,可以限制指定網卡訪問的IP。
```
如果你的網絡中有兩塊網卡分別為eth0和eht1 ,可以限制指定網卡訪問的IP
```
4. 很多網絡攻擊都會嘗試用黑客自定義的非法數據包進行嘗試,我們可以使用如下命令來丟棄無效數據包。
```
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
```
5. 清理INPUT鏈規則。
```
iptables -A INPUT -F
```
6. 端口轉發,將80端口數據包轉發到8989端口上。
```
iptables -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8989
```
7.對ping本服務器的icmp報進行限制。
```
ping 106.53.60.21 -l 100 -c 100
iptables -A INPUT -p icmp -m limit --limit 5/sec --limit-burst 5 -j ACCEPT
iptables -A INPUT -p icmp -j DROP
```
每秒鐘5個包,最高5個包以下為測試數據結果。
8.防止syn flood攻擊。
```
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
```
## NAT 表
NAT為轉發數據表,以下為相關鏈的數據流向:
* 入站順序:PREROUTING→INPUT
* 出站順序:OUTPUT→POSTROUTING
* 轉發順序:PREROUTING→FORWARD→POSTROUTING
### NAT數據轉發案例
我們來配置一個NAT轉發的案例。
```
# 臨時
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久
vi /etc/sysctl.conf
net.ipv4.ip_forward=1
# 清空轉發表規則
iptables -t filter -A FORWARD -F
# 172.16.16.18 為主機公網對應的內網IP, 172.16.32.10 為內網MySQL的IP
iptables -t nat -A PREROUTING -d 172.16.16.18 -p tcp --dport 7788 \
-j DNAT --to-destination 172.16.32.10:3306
# 反過來寫
iptables -t nat -A POSTROUTING -d 172.16.32.10 -p tcp --dport 3306 \
-j SNAT --to-source 172.16.16.18
```
## Mangle 表
Mnangle表主要用于數據包的打標簽,我們來看兩個案例:
### 端口打標簽案例
對不通的端口進行數據包打標簽,并按照端口的特性對網絡使用有優先權限。
```
iptables -A PREROUTING -t mangle -p tcp --dport telnet -j TOS --set-tos Minimize-Delay
iptables -A PREROUTING -t mangle -p tcp --dport ftp -j TOS --set-tos Minimize-Delay
iptables -A PREROUTING -t mangle -p tcp --dport ftp-data -j TOS --set-tos Maximize-Throughput
```
### 數據包打標簽案例
通過TTL值來偽裝服務器。當黑客在攻擊你的服務器前首先要判斷服務器的操作系統,判斷操作系統最簡單方式就是通過TTL值,以下通過iptables來偽裝的TTL值,以實現隱藏操作系統的目的。
```
iptables -t mangle -A POSTROUTING -j TTL --ttl-set 128
```
Linux系統返回TTL值為64 , Windows的TTL值返回為128 。