[TOC]
# 1. 基礎概念
1. iptables是Linux防火墻工具,用來定義數據包操作規則(用戶空間),用來操作netfilter規則
2. netfilter組件:稱為內核空間,是內核的一部分,由一些信息包過濾表組成,這些表是內核用來控制信息包過濾處理的規則集,
3. iptables和firewall是給用戶操作netfilter的工具,真正起到防火墻作用的是netfilter組件
# 2. table、chain和rule
## 2.1 三張表
1. 最常用的有三個表,分別是`filter`,`nat `和`mangle`.其中每個表又有各自包含不同的操作鏈(chains):
**filter**用于過濾數據包,進入本機(input)、從本機出去(output),轉發的數據
**nat**用于轉發數據包,轉入(prerouting)和轉出(postrouting)

2. iptables的表與鏈的工作流程,如圖想要修改input鏈,只能在filter(過濾)表和Mangle表上進行,同理其他鏈操作參考下圖

## 2.2 五種鏈
1. **input**:
匹配目標ip 是本機的數據包時,進入此鏈
2. **output**:
出口數據包,從本機發出的數據包,進入此鏈
3. **forward**:
匹配流經本機的數據包,nat轉發
4. **prerouting**:
可以**用來修改目的地址**用來做DNAT,如把內網的80端口映射到路由器外網端口上,然后內核的”路由模塊”-`route`根據”數據包目的IP”以及”內核中的路由表”判斷是否需要轉送出去(注意,這個時候數據包的DestIP有可能已經被修改過了)
5. **postrouting**:
用來修改源地址用來做SNAT,如內網通過路由器NAT轉換功能實現內網PC機通過一個公網ip地址上網
> 入站數據:prerouting -> input
> 轉發數據:prerouting -> forward -> postrouting
> 出站數據:putput -> postrouting
**包處理流程**
1. 首先進入preruteing,決定是進入本機還是轉發
2. 若果目的地址是本機的(數據包的目的ip是本機的網口ip),進入input鏈,到達input鏈后,任何的進程都有可能得到這個數據包
3. 如果數據包是要轉發出去的(即目的IP地址不再當前子網中),**且內核允許轉發**,數據包就會向右移動,經過FORWARD鏈,然后到達POSTROUTING鏈輸出(選擇對應子網的網口發送出去) -》源ip不變,目的ip變內網,記錄nat表,數據包返回是參照nat表,數據返回給外網,達到暴露服務的目的
4. 本機上運行的程序也可以發送數據包,這些數據包經過OUTPUT鏈,然后到達POSTROTING鏈輸出(注意,這個時候數據包的SrcIP有可能已經被我們修改過了) -》改變源ip,目的IP不變,記錄nat表,數據包回來參照nat表,又回到了內網,達到上網的目的
## 2.3 包處理規則target
**防火墻處理數據包的方式(規則):**
1. `ACCEPT`:允許數據包通過
2. `DROP`:直接丟棄數據包,不給任何回應信息
3. `REJECT`:拒絕數據包通過,必要時會給數據發送端一個響應的信息。
4. `SNAT`:源地址轉換。在進入路由層面的route之前,重新改寫源地址,目標地址不變,并在本機建立NAT表項,當數據返回時,根據NAT表將目的地址數據改寫為數據發送出去時候的源地址,并發送給主機。**解決內網用戶用同一個公網地址上網的問題**。
5. `MASQUERADE`,是SNAT的一種特殊形式,適用于像adsl這種臨時會變的ip上
6. `DNAT`:目標地址轉換。和SNAT相反,IP包經過route之后、出本地的網絡棧之前,重新修改目標地址,源地址不變,在本機建立NAT表項,當數據返回時,根據NAT表將源地址修改為數據發送過來時的目標地址,并發給遠程主機。可以隱藏后端服務器的真實地址。 (暴露內網地址和端口)
7. `REDIRECT`:是DNAT的一種特殊形式,將網絡包轉發到本地host上(不管IP頭部指定的目標地址是啥),方便在本機做端口轉發。
8. `LOG`:在/var/log/messages文件中記錄日志信息,然后將數據包傳遞給下一條規則
除去最后一個`LOG`,前3條規則匹配數據包后,該數據包不會再往下繼續匹配了,所以編寫的規則順序極其關鍵。
# 3. iptables命令使用
## 3.1 命令格式
> iptable是給用戶調用netfilter的工具,用來修改防火墻規則
```
iptables [-t 表名] 管理選項 [鏈名] [條件匹配] [-j 目標動作或跳轉]
```
1 ) 不指定表名時,默認表示filter表
2 ) 不指定鏈名時,默認表示該表內所有鏈
3 ) 除非設置規則鏈的缺省策略,否則需要制定匹配條件
**1. command 選項,操作鏈上的規則**
~~~
-A :增加
-D: 刪除
-I : 插入
-R
-L:列出表的規則,默認是filter表
-F: 清空規則
-Z
-N:用于新建一個自定義鏈
-X:清空引用為0的自定義鏈規則
-P : 設置某個鏈的默認規則,鏈的默認規則最后觸發
~~~
**2. parameter選項,數據包過濾,協議端口ip**
~~~
-P:協議類型
-s:來源地址
-d:目的地址
-i:流入
-o:流出
-sport:來源端口
-dport:目標端口
~~~
**3. target**
包處理方式
~~~
-j ACCEPT
-j DROP
-j REJECT
...
~~~
## 3.2 例子
> 查看默認策略
```
iptables -L
```

> 拒絕所有連接,沒有指定規則則,則匹配所有
```
iptables -t filter -A INPUT -j DROP
```
> 刪除規則 -D
按照序號展示 `iptables -L --line-numbers`
```
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */
2 KUBE-EXTERNAL-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes externally-visible service portals */
3 KUBE-FIREWALL all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 KUBE-FORWARD all -- anywhere anywhere /* kubernetes forwarding rules */
2 KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */
3 DOCKER-USER all -- anywhere anywhere
4 DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
5 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
6 DOCKER all -- anywhere anywhere
```
刪除filter表的input 鏈的第一條規則
```
iptables -t filter -D INPUT 1
```
方式2,按內容
> 刪除filter表的input鏈中內容為 "-s 192.168.0.1 -j DROP" 的規則
```
iptables -t filter -D INPUT -s 192.168.0.1 -j DROP
```
> 設置某個鏈的默認規則
`iptables -P INPUT DROP`
> 清空規則 -F
清空filter表INPUT鏈的所有規則
```
iptables -t filter -F INPUT
```
> 清空filter表的所有鏈的規則
```
iptables -t filter -F
```
注意事項
-F 不清除默認規則
-P 設置了DROP后,使用-F 一定要小心
如不寫鏈名,默認清空某表里所有鏈里的所有規則
### 3.2.2 nat 表
> PREROUTING 鏈的所有規則
```
iptables -t nat -vnL PREROUTING
```
**1. 按流入網絡接口匹配(-i)**
> -i 匹配數據進入網絡接口 #主要用于nat表
例子
-i eth0 匹配是否從網絡接口eth0進來
-i ppp0 匹配是否從網絡接口ppp0進來
2. 按流出網絡接口匹配(-o)
`iptables -t nat -o eth0 條件 動作`
3. 按來源地址匹配(-s)
-s 匹配來源地址,可以是ip,net,domain ,也可空(任何地址)
例如:
```
-s 192.168.0.1 匹配來自192.168.0.1的數據包
-s 192.168.1.0/24 匹配來自192.168.1.0/24 的數據包
-s 192.168.0.0/16 匹配來自192.168.0.0/16 的數據包
```
4. 按目的地址匹配(-d)
-d 匹配來源地址,可以是ip,net,domain ,也可空(任何地址)
例如:
```
-d 192.168.0.1 匹配去往192.168.0.1的數據包
-d 192.168.1.0/24 匹配去往192.168.1.0/24 的數據包
-d 192.168.0.0/16 匹配去往192.168.0.0/16 的數據包
```
5. 按協議匹配(-p)
-p 匹配來源地址,可以是TCP、UDP,ICMP,也可為空
例如:
```
-p tcp 匹配協議為 tcp的數據包
-p udp 匹配協議為 udp的數據包
-p icmp 匹配協議為 icmp的數據包
```
6. 按來源端口匹配(sport)
例如:
```
--sport 1000 匹配源端口是1000的數據包
--sport 1000:3000 匹配源端口是1000-3000的數據包
--sport :3000 匹配源端口是3000以下的數據包
--sport 1000: 匹配源端口是1000以上的數據包
```
7. 按目的端口匹配(dport)
```
--dport 1000 匹配目的端口是1000的數據包
--dport 1000:3000 匹配目的端口是1000-3000的數據包
--dport :3000 匹配目的端口是3000以下的數據包
--dport 1000: 匹配目的端口是1000以上的數據包
```
注意:
1. --sport 和 --dport 必須和 -p 配合使用
2. 條件越多,匹配越精確,范圍越小
數據包結構
目標端口 目標ip地址 內容址 源端口 源ip地址
80 192.168.1.64 xxx 3211 192.168.1.65
### 動作(處理方式)
#### ACCEPT(接受)
通過,允許數據包通過本鏈而不攔截
格式: -j ACCEPT
> 允許所有訪問本機ip的數據包通過
```
iptables -A INPUT -j ACCEPT
```
#### DROP (丟棄,不給對方任何回應)
丟棄,不允許數據包通過本鏈而丟棄它
格式: -j DROP
阻止來源地址為192.168.80.39的數據包通過本機
```
iptables -A FORWARD -s 192.168.80.39 -j DROP
```
#### REJECT (拒絕,給對方一個回應)
#### SNAT(上網)
原地址轉化,snat 支持轉化為單ip,也支持轉化到ip地址池
> 格式: -j SNAT --to IP[-IP][:端口-端口]
適用范圍: nat表的 postrouting
單個地址情況
1. 將內網 192.168.0.0/24的源地址修改為公網IP地址 1.1.1.1
```
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
```
2. 將內網 192.168.0.0/24的源地址修改為公網IP地址 1.1.1.1- 1.1.1.10
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10
#### DNAT(端口映射)
目標地址轉化,DNAT 支持轉化為單ip,也支持轉化到ip地址池
> 格式: -j DNAT --to IP[-IP][:端口-端口]
> 適用范圍: nat表的 prerouting
**1. 暴露端口**
> 把eth0進來的要訪問TCP/80的數據包目的地址改為192.168.0.1
```
iptables -t nat -A PREROUNTING -i eth0 -p tcp -dport 80 -j SNAT --to 192.168.0.1
```
多個地址情況
**2. 把eth0進來的要訪問TCP/80的數據包目的地址改為192.168.0.1-192.168.0.10**
```
iptables -t nat -A PREROUNTING -i eth0 -p tcp -dport 80 -j DNAT --to 192.168.0.1-192.168.0.10
```
#### MASQUERADE(偽裝ip地址)
> 動態源地址轉換(動態ip的情況下使用)
將源地址是192.168.0.0/24的數據包進行地址偽裝,轉換成eth0上的ip地址,eth0為路由器外網IP地址
```
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
```
## 附加模塊
### 按包狀態匹配
-m state --state 狀態
狀態:NEW、RELATED、ESTABLIShED、INVALID
```
NEW: 有別于tcp的syn
RELATED: 衍生態
ESTABLISHED: 連接狀態
INVALID: 不能被識別屬于哪個連接或沒有任何狀態
```
> 將連接狀態為RELATED 和ESTABLISHED 的訪問數據包通過
```
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
```
### 按來源MAC匹配
格式
-m mac --mac-source mac地址
> 阻斷來自某mac 地址數據包通過本機
```
iptables -A FORWARD -m mac --mac-source xxxx -j DROP
```
### 按包速率匹配
> 格式
-m limit --limit 匹配速率 [--burst 緩沖數量]
> 只允許192.168.0.1 一秒發送50個數據包
```
iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
iptables -A FORWARD -d 192.168.0.1 -j DROP
```
### 多端口匹配
格式
```
-m multport <--sports|--dports|--ports>
```
一次行匹配多個端口,可以區分源端口,目的端口或不制定端口
> 允許所有客戶端訪問本服務器的21、22、 25和 80端口的服務
```
iptables -A INPUT -p tcp -m multiport --dports 21,22,25,80 -j ACCEPT
```
注意: 必須與 -p 參數一起使用
三、網絡基本拓撲圖
graph LR
終端用戶--> 互聯網
互聯網--> 防火墻
防火墻--> 路由器
路由器--> 交換機
交換機--> 服務器
# 4. 案例
## 4.1 對web服務器保護
> 匹配規則,自上而下,只要匹配到一條就停止,無論是通過還是不通過
```
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m mutiport --dports 22,80 -j ACCEPT
iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT DROP
```
## 4.2 讓內網pc機上網
可連接外網主機|,有兩塊網卡
```
內網ip:192.168.56.10
外網ip: 10.0.2.15
```
內網主機
```
內網ip: 192.168.56.13
```
**1. 在可上外網主機配置路由規則,轉發數據包到外網網卡接口**
```
iptables -t filter -P FORWARD DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.56.10/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.56.1/24 -j SNAT --to 10.0.2.15
```
**2. 外網機器打開數據包轉發**
```
vim /etc/sysctl.conf
# 配置=1,開啟轉發
net.ipv4.ip_forward=1
```
**3.在內網機器上,設置其網關為外網主機ip,將外網請求發送到網關**

重啟網絡
`service network restart`
**4. 配置域名解析**
```
vi /etc/resolv.conf
nameserver?114.114.114.114
nameserver?8.8.8.8
```

## 4.3 暴露端口
- Linux
- 高級
- 殺毒
- 記一次中毒事件
- clamav查毒軟件
- 處理挖礦病毒
- 定時任務
- kill
- chattr文件保護
- 運行級別
- Linux啟動
- 文件加密
- ssh免密登錄
- .ssh
- 問題
- 腳本
- 阿里云域名解析
- yum源
- 時間同步
- keepalived實現高可用
- dos字符與unix字符
- 大文件上傳
- 基礎
- proc目錄
- 設置宋體
- 基礎命令_01
- 基礎命令_02
- SELinux
- 文件描述符
- 基礎命令_03
- awk
- 系統日志
- date命令
- bc命令
- lsof
- vim快捷鍵
- shell
- 循環控制
- expr
- 執行腳本的方式
- declare
- shell腳本
- 控制啟停腳本
- 數值計算
- centos
- 配置網絡
- 環境
- 灰度環境
- ansible
- 模塊
- 語法
- file模塊
- setup模塊
- ping模塊
- copy模塊
- command模塊
- shell模塊
- service模塊
- cron模塊
- yum模塊
- user 模塊
- group模塊
- 指定用戶
- playbook
- 實例
- ansible安裝
- Jenkins
- shell部署
- 導入已有項目的配置
- 執行shell
- tungsten數據同步
- 防火墻
- netfilter