---
# System prepended metadata

title: Firewall

---

# Firewall

防火牆 firewall 是一種網路安全系統，其基本功能是監控和控制進入或離開網路的資料流量

## 主要功能

### 流量過濾 Traffic Filtering

根據一組預先定義的規則來監控和過濾進出網路的封包。例如，它可以允許或拒絕特定來源或目的地的流量，或者基於特定的協議和端口號

### 狀態檢查 Stateful Inspection

進階的 firewall 能夠追蹤連線的狀態，並根據這些資訊來允許或阻止流量。這意味著不僅僅基於單獨的封包來做決定，而是考慮整個連線過程

### 應用層過濾 Application Layer Filtering

一些更進階的 firewall 能夠檢查封包的應用層資料。能夠讓其對特定應用程式的流量施加更精細的控制，例如阻止或允許特定的網頁或服務

## 實際案例

## 背景

- 公司網路: 有多台電腦和伺服器，包括一個內部郵件伺服器和一個檔案共享伺服器
- 外網連接: 公司通過一個 router 連接到外網，所有的外部連結都經過這個 router
- firewall: firewall 安裝在 router 上，作為內部網路和外網之間的閘道


### 規則設定

#### 允許內部到外部的網絡流量

規則: 允許所有來自公司內部網路的流量訪問外網
目的: 員工可以瀏覽網頁，發送郵件，使用外部服務

#### 阻擋外部到內部的未經請求的流量

規則: 除非是作為內部到外部流量的回應，否則阻擋所有從外網進入公司網路的流量
目的: 防止未經授權的連線和潛在的攻擊

#### 限制對特定服務的訪問

規則: 只允許從特定的 IP 訪問內部郵件伺服器
目的: 增強郵件伺服器的安全性，防止外部攻擊

#### 監控和記錄

規則: 記錄所有進出的流量，特別是被阻擋的嘗試
目的: 分析流量模式，識別潛在的安全問題

### 情境

當一名員工試圖從公司內部電腦訪問一個外部網站時，firewall 會檢查其規則，並允許這個合法的請求通過
假如一個人試圖從外網遠端對公司的文件伺服器發出請求，firewall 會識別出這個請求並不是對任何內部請求的回應，並阻擋它
如果有一個合法的外部合作夥伴需要訪問郵件服務器，他們的 IP 地址會被添加到白名單中，firewall 隨後會根據規則允許這個特定的流量

## iptables

`iptables `是一個執行在 user space 的應用程式，透過操作 Linux Kernel 的 Netfilter module，來管理網路封包的處理或是轉發，進而實現 firewall 的功能，日後會由更新的 nftables 取代

## Netfilter

Netfilter module，是一個用於管理網路封包的軟體框架，具備一連串的檢查流程，來對進入系統、由系統發送的封包，進行客製化的操作
![image](https://hackmd.io/_uploads/Bkg_FQxPa.png)



## 架構

由三個主要元件構成:

- table
- chain
- rule
> iptables 內部包會多張 tables，而 table 則包含多個 chains，chain 內部則包含多個 rules


![image](https://hackmd.io/_uploads/SyL5K7ewa.png)



## tables

iptables 中的 table 是 ruleset 的分類，每個 table 包含一些特定的 chains，用於不同的網路流量處理方式

#### Filter table

- 最常用的 table
- 用於決定封包的基本處理，如 ACCEPT、REJECT 或 DROP
- 包含的 chains
    - `INPUT`: 處理進入本機的封包
    - `OUTPUT`: 處理本機產生的封包
    - `FORWARD`: 處理經由本機轉發的封包

### NAT table

- 用於 NAT，主要用於修改封包的來源 (**s**ource) 或目的 (**d**estination) 地址
- 包含的 chains
    - `PREROUTING`: 在 routing decision 之前處理進入的封包
    - `POSTROUTING`: 在 routing decision 之後處理出去的封包
    - `OUTPUT`: 更改本機送出的封包的目的地

### Mangle table

- 用於修改封包的特定選項，如修改 TTL (time to live)，設置流量控制 (QoS) 標記等
- 包含的 chains (在這些 chains 上都可以對封包進行修改)
    * `PREROUTING`
    * `INPUT`
    * `FORWARD`
    * `OUTPUT`
    * `POSTROUTING`

### Raw table

- 用於設置不應被 conntrack 處理的封包
- 包含的 chains
    * `PREROUTING`: 用於標記排除狀態跟蹤的封包
    * `OUTPUT`: 用於本機產生的封包

### Security table

- 用於實施 SELinux 網路存取控制
- 包含的 chains (用於標記封包的安全級別)
    * INPUT
    * OUTPUT
    * FORWARD

## Netfilter 運作流程

![image](https://hackmd.io/_uploads/Byp5qXgvp.png)


先從封包進入主機來看:

### NAT PREROUTING

可以在此改變封包的目的地 (DNAT) 像是 IP, Domain Name, Port，藉此達到轉送封包的能力

e.g. 連到本機 8080 port 的封包，轉送去 192.168.1.101 的 80 port

`sudo iptables -t nat -I PREROUTING -p tcp --dport 8080 -j DNAT --to 192.168.1.101:80`

### routing decision (路由判斷)

根據 routing table (路由表) 決定封包要進入主機，還是轉送出去
:::info
查看路由表的方式
- `route -n`
```
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         198.19.249.1    0.0.0.0         UG    100    0        0 eth0
198.19.248.200  198.19.249.1    255.255.255.255 UGH   100    0        0 eth0
198.19.249.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0
198.19.249.1    0.0.0.0         255.255.255.255 UH    100    0        0 eth0
```
* `ip route`
```
default via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.147 metric 100
198.19.248.200 via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.147 metric 100
198.19.249.0/24 dev eth0 proto kernel scope link src 198.19.249.147 metric 100
198.19.249.1 dev eth0 proto dhcp scope link src 198.19.249.147 metric 100
```
:::

### FILTER INPUT (路線 A)

routing decision 後，若**封包要進入本機**就會進到這個階段，來判斷封包能否進入本機

e.g. 拒絕所有進入本機的封包

`sudo iptables -I INPUT -j DROP`

### FILTER FORWARD (路線 B)

routing decision 後，若**封包不需進入本機**就會進到這個階段，來判斷封包能否轉送

e.g. 拒絕轉送目標是 192.168.56.135 的封包

```
sudo iptables -I FORWARD -d 192.168.56.135 -j DROP

```

### NAT OUTPUT (路線 C)

本機送出封包時，會進到此階段，routing decision 後可以更改封包的目的地 (很少用到)

e.g. 更改封包目的地，從 1.2.3.4 改成 8.8.8.8

`sudo iptables -t nat -I OUTPUT -d 1.2.3.4 -j DNAT --to 8.8.8.8`

### FILTER OUTPUT (路線 C)

決定封包能否送出去

e.g. 允許發送到 192.168.1.101 的封包

`sudo iptables -I OUTPUT -d 192.168.1.101 -j ACCEPT`

### NAT POSTROUTING

更改封包的 source IP (來源 IP)，主要目的是讓外網回傳封包時，能夠使用正確的地址 (防火牆的地址)。

假設在內網連到外網，要將內網使用的 IP 位置換成防火牆的 IP 位置，因為對外的出口跟入口都是防火牆，要讓 response 能夠成功到防火牆，然後再讓防火牆用 NAT 再換成內網 IP

e.g. 從防火牆對外的網卡 (eth0) 送出的封包，都把來源 IP 換成防火牆的對外 IP (178.87.12.34)

`sudo iptables -t nat -I POSTROUTING -o eth0 -j SNAT --to 178.87.12.34`

Rules

- 實際設定 iptables 規則的地方，只要符合規則就會執行對應的操作
- rule 處理的過程是 short circuit (短路) 的，意即只要一碰到可以匹配的 rule 就會執行對應動作，即使後面也有匹配的 rule 也不會再執行，所以 rule 的順序很重要

### policy

封包的預設處理方式，如果沒有符合的 rule 時就會執行

### target

符合規則時要進行的動作

* ACCEPT: 允許
* REJECT: 拒絕，會透過 RST 封包通知發送者，表示連線被拒絕
* DROP: 拒絕，但不會告知發送者，會讓發送者直接等到 timeout，DROP 會相對安全
* SNAT: 修改封包的 source IP
* DNAT: 修改封包的 destination IP 和 port

:::info
* MASQUERADE: 動態 SNAT
* REDIRECT: 更改封包的目的 port
* LOG: 記錄到系統的 log，預設路徑: `/var/log/kern.log` 和 `/var/log/syslog`
:::

:::info
## conntrack module
conntrack 模組是 Linux network stack 的一部分，它負責追蹤所有通過網路接口的 IP 連線狀態，包括 TCP、UDP 和其他協議的連線。主要作用是為了支持高級的網路功能，NAT 和防火牆功能，`iptables` 中紀錄連線狀態以及相關功能都是依此實現的
### 連線狀態追蹤
conntrack 能夠追蹤每個連線的狀態，如 TCP 連線的建立、維持和終止過程。它記錄了連線的 source address、destination address、port 和協議狀態等資訊
### 實現狀態檢查
不只根據靜態規則 (IP 地址和 port) 過濾封包，也根據封包所屬連線的狀態來做出決策
### 支持 NAT 功能
conntrack 對於實現 source NAT (SNAT) 和 destination NAT (DNAT) 至關重要。它保持了 NAT 轉換前後的連線狀態資訊，確保封包能夠正確地被轉發和回應
:::
