- Book mode https://hackmd.io/@ncnu-opensource/book [TOC] # 什麼是防火牆? :::info - 在學校內就相當於警衛的角色 - 確認只有學生或是教職人員可以進入學校 ::: ![image](https://hackmd.io/_uploads/rkH9FChWJl.png) ![image](https://hackmd.io/_uploads/rJC2K0nb1x.png) - 讓使用者設定規則/策略,保護自己的網路環境 主要的功能有: - **阻擋**不要的封包 - **放行**需要的封包 - **轉發**封包 :::danger ## 如果沒有防火牆 ![LSA Firewall.drawio](https://hackmd.io/_uploads/rkqhj1abyg.svg) - 任何使用者都能直接連線到我的主機 ::: :::success ## 如果有防火牆 ![LSA Firewall.drawio](https://hackmd.io/_uploads/H1UxYkp-Jl.svg) - 確定只有合法的使用者能夠連線進來 ::: # Netfilter ## 介紹 - Linux 內建的封包過濾框架 - 由 Rusty Russell 在 1998 年開始主導開發 - Linux 2.4 版本時,正式取代舊的 ipchains - 目前 Linux 上主流的防火牆軟體,都是基於此框架去實作 - 主要提供以下功能 - 封包選擇跟過濾 - 網路位址轉譯 (NAT, Network Address Translation) - Packet mangling - Connection tracking ## Hooks :::info 在系統設計中,Hook 是一種機制,用來在特定的事件發生時啟動額外的自訂的行為。防火牆的規則,就是透過在以下這些 Hooks 上註冊一些檢查以及相對應的行為去達成的 ::: ```mermaid flowchart TB A((封包進入)) --> B[NF_INET_PRE_ROUTING] B --> C{路由判斷} C -->|封包送往本機| D[NF_INET_LOCAL_IN] C -->|轉發封包| E[NF_INET_FORWARD] D --> |交給需要的本機資源| F[[本機 process]] E --> |發送封包| I[NF_INET_POST_ROUTING] G[[本機 process]] --> |產生封包| H[NF_INET_LOCAL_OUT] H -->|發送封包| I I --> J((封包傳出)) ``` 當封包進到 Linux 的網路系統中時,會按照一定的順序去觸發這些 Hooks,Netfilter 主要提供以下 5 種 Hook 點: ### `NF_INET_PRE_ROUTING` 接收到的封包第一個會碰到的 Hook,會在進行路由判斷 (routing decision) 之前觸發 ### `NF_INET_LOCAL_IN` 經過路由判斷後,若目的地是本機,就會觸發這個 Hook ### `NF_INET_FORWARD` 經過路由判斷後,若是需要轉發出去的封包(目的地不是本機),就會觸發這個 Hook ### `NF_INET_LOCAL_OUT` 本機產生並要送往外部的封包,會觸發這個 Hook ### `NF_INET_POST_ROUTING` 任何送往外部的封包 (包含轉發) 最終都會觸發的 Hook # iptables ## 介紹 - iptables 是 Linux 的一種防火牆軟體 - 透過使用 iptables 提供的指令可以操作 Netfilter,進而實現防火牆的功能 - 都需要超級使用者權限 (`sudo`) 才能使用 ## 架構 ![LSA Firewall Page 3](https://hackmd.io/_uploads/H1VMPl0byg.svg) - 由 **table**、**chain**、**rule** 組成 - iptable"s"/nftable"s",可知有多個 table - 一個 table 內會有多個 chain - 一個 chain 內會有多個 rule ## Tables 根據**用途** iptables 有**預先定義**幾個 Table: ![image](https://hackmd.io/_uploads/HkZUiEbzke.png) ### `raw` - **不常用**的 table - 主要用於控制哪些封包需要進行連線追蹤 (connection tracking) ### `filter` - **常用**的 table - 專門用於封包過濾,根據定義的規則來允許、阻擋封包,是防火牆功能的核心 ### `nat` - **常用**的 table - 專門用於網路位址轉譯 (NAT) 的 table。主要是修改封包的來源或目的地 IP 地址和通訊埠號 (port),以便在內外網之間進行網路通訊 ### `mangle` - **不常用**的 table - 主要用來修改封包的標頭或屬性 ### `security` - **不常用**的 table - 專門與 SELinux (Security-Enhanced Linux) 或 AppArmor 等 Linux 安全模組 (Linux Security Modules, LSM) 配合使用,進行更細粒度的封包控制 > 接下來的內容會聚焦在 `filter` 跟 `nat` 這兩個**常用**的 table 上 ## Chains ![image](https://hackmd.io/_uploads/SkIbBu0ZJx.png) iptables 中有五個預先定義好的 chain: - `PREROUTING` - `INPUT` - `FORWARD` - `OUTPUT` - `POSTROUTING` :::warning Q&A 聰明的你有發現可以直接對應到之前講的什麼東西嗎? ::: ### `filter` table 的 chains ![image](https://hackmd.io/_uploads/HyDqoN-Gkl.png) | chain | 用途 | |:--------- |:------------------ | | `INPUT` | 過濾**進入**的封包 | | `OUTPUT` | 過濾**送出**的封包 | | `FORWARD` | 過濾要轉送的封包 | ### `nat` table 的 chains ![image](https://hackmd.io/_uploads/S1C6AN-f1l.png) | chain | 用途 | |:------------- |:------------------------------------------------------------------------------------- | | `PREROUTING` | 在封包進入 routing decision 之前,對其進行目的地位址轉譯 (DNAT) | | `INPUT` | 因為已經過了 routing decision,所以僅能對封包進行本機的 port 轉發,僅在特殊情況使用 | | `OUTPUT` | 特殊情況下,修改本機生成封包的目的地位址 (DNAT),可用來做透明代理 (transparent proxy) | | `POSTROUTING` | 在封包離開系統後、發送到網路之前,對其進行來源地位址轉譯 (SNAT) | ## Rules - 使用者使用 iptables 設定的規則,若符合規則就會對封包執行對應的行為 - rule 是以**有序的**方式進行判斷 - rule 在判斷的時候是短路 (short circuit) 的,意即只要有一條規則被匹配到就不會繼續往接下來的規則進行判斷 ### Policy 封包預設的處理方式,若沒有 rule 被匹配到的時候,就會執行 policy 設定的行為 ### Target 符合規則的時候,要對封包執行的操作,以下是常見的 target: | Target | 用途 | |:------------ |:---------------------------------------------------------------------------------------------------------- | | `ACCEPT` | 允許封包 | | `REJECT` | 拒絕封包,且會透過回傳 RST 封包通知發送封包的人連線被拒絕,也因為會有回應所以發送者會知道主機存在 | | `DROP` | 丟棄封包,不會對發送封包的人有任何回應,會讓連線自己 timeout,因為沒有回應所以發送者也無法判定主機是否存在 | | `DNAT` | 修改封包的目的地位址 | | `SNAT` | 修改封包的來源地位址 | | `REDIRECT` | 修改封包目的地的 port | | `MASQUERADE` | 動態的 SNAT | | `LOG` | 記錄到 `syslog` | :::warning Q&A 覺得哪些 target 跟 `filter` table 相關? 哪些跟 `nat` table 相關? ::: :::success 好文分享 - [DROP vs. REJECT](https://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject) ([中文翻譯](https://www.jyh.im/2024/11/01/Drop-versus-Reject/)) - [iptables REDIRECT vs. DNAT vs. TPROXY](https://gsoc-blog.ecklm.com/iptables-redirect-vs.-dnat-vs.-tproxy/) ::: ## 運作流程 ```mermaid flowchart TB subgraph NF_INET_PRE_ROUTING nat_PREROUTING[nat: PREROUTING] end subgraph NF_INET_LOCAL_IN direction TB nat_INPUT[nat: INPUT] --> filter_INPUT[filter: INPUT] end subgraph NF_INET_FORWARD filter_FORWARD[filter: FORWARD] end subgraph NF_INET_LOCAL_OUT direction TB nat_OUTPUT[nat: OUTPUT] --> filter_OUTPUT[filter: OUTPUT] end subgraph NF_INET_POST_ROUTING nat_POSTROUTING[nat: POSTROUTING] end routing_decision_1{路由判斷} routing_decision_2{路由判斷} routing_decision_3{路由判斷} packet_in((封包進入)) local_process_1[[本機 process]] local_process_2[[本機 process]] packet_out((封包傳出)) packet_in --> NF_INET_PRE_ROUTING NF_INET_PRE_ROUTING --> routing_decision_1 routing_decision_1 -->|封包送往本機| NF_INET_LOCAL_IN routing_decision_1 -->|轉發封包| NF_INET_FORWARD NF_INET_LOCAL_IN --> |交給需要的本機資源| local_process_1 NF_INET_FORWARD --> |發送封包| NF_INET_POST_ROUTING local_process_2 --> |產生封包| routing_decision_2 routing_decision_2 --> NF_INET_LOCAL_OUT NF_INET_LOCAL_OUT --> routing_decision_3 routing_decision_3 --> |發送封包| NF_INET_POST_ROUTING NF_INET_POST_ROUTING --> packet_out ``` :::info 這邊主要在基於 Netfilter hooks 再加上 `filter` 跟 `nat` table 的流程,涉及到更多 table 可以看[這邊](https://www.frozentux.net/iptables-tutorial/chunkyhtml/images/tables_traverse.jpg) ::: ### `NF_INET_PRE_ROUTING` 1. `nat` table `PREROUTING` chain 修改封包的目的位址 (e.g. IP, port),來達到**轉送封包**的功能 (DNAT) ### 路由判斷 (routing decisions) 根據 routing table 設定的規則,決定封包要**進入系統**還是要**轉發出去** :::warning Q&A 可以使用什麼命令查看 routing table ::: ### `NF_INET_LOCAL_IN` > 路由判斷後,若封包要**進入本機**就會進到這個 hook 1. `nat` table 的 `INPUT` chain 是否針對進入本機的流量進行 port 轉發 2. `filter` table 的 `INPUT` chain 判斷是否要允許封包進入本機 ### `NF_INET_FORWARD` > 路由判斷後,若封包要**轉發出去**就會進到這個 hook 1. `filter` table 的 `FORWARD` chain 判斷封包是否要允許封包轉發出去 ### `NF_INET_LOCAL_OUT` > 本機產生的封包要從本機送出時會到這個 hook 1. `nat` table 的 `OUTPUT` chain 修改封包的目的地,但不常用 2. `filter` table 的 `OUTPUT` chain 判斷封包是否可以送出 ### `NF_INET_POST_ROUTING` > 只要是要從本機送出的封包,最終都會碰到這個 hook 1. `nat` table 的 `POSTROUTING` chain 修改封包的來源地位址 (SNAT),來讓外部網路回傳的封包能夠正確找到系統的對外位址 ## 指令操作 `iptables [-t table] {-A|-C|-D...} chain rule [options...]` ### 查看 `filter` table 內有哪些 chains 跟 rules `sudo iptables -t filter -L` :::info 補充一些好用的選項 - `-n` 不嘗試把 IP 位址解析成域名,執行速度會較快 - `-v` 列出更多資訊 - `--line-numbers` 顯示 rule 的編號,在新增或是刪除時可能需要 ::: ![image](https://hackmd.io/_uploads/S1IzmUkzkx.png) ![image](https://hackmd.io/_uploads/SksXmUJf1l.png) :::warning Q&A 查看 `mangle` table 的 `PREROUTING` chain 內的規則的指令 ::: ### 修改 `filter` table `INPUT` chain 的 policy `sudo iptables -t filter -P INPUT DROP` ![image](https://hackmd.io/_uploads/ryYRVDJzke.png) :::danger 某些情況為了系統安全,會將 policy 設為 DROP,設定的 rule 就會變成哪些封包是能夠被允許的,變成像是**白名單**,但會建議說在 rule 都確定沒問題之後,在規則的最下方再加上一 DROP 的規則,可以有效的避免一些操作失誤 像是在 ssh 到遠端主機進行 iptables 設定時,要是手殘 flush 了所有規則,此時若 policy 為 DROP,ssh 的 connection 也會直接被切斷 ::: :::warning Q&A 把 policy 改回 `ACCEPT` 的指令 ::: ### 設定 rule `sudo iptables [-t table] {-A|-I} chain -j target` - `-A, --append`: 會將規則加在舊有規則的**後面** - `-I, --insert`: 會將規則加在舊有規則的**前面** - `-D, --delete`: 刪除指定的 rule - `-R, --replace`: 取代指定的 rule - `-F, --flush`: 刪除指定的 chain 或是 table 內的所有 rules - `-j, --jump`: 指定符合規則時會執行哪個 target #### 針對網路介面卡設定規則 :::warning Q&A 用什麼指令可以列出電腦網卡跟 IP 的資訊 ::: - `-i, --in-interface`: 封包進入系統時經過的網卡名稱 `sudo iptables -t filter -I INPUT -i eth0 -j ACCEPT` - `-o, --out-interface`: 封包傳出系統時經過的網卡名稱 `sudo iptables -t filter -I OUTPUT -o eth0 -j ACCEPT` #### 針對 IP 位址設定規則 - `-s, --source`: 封包的來源 IP 位址 `sudo iptables -t filter -I INPUT -s 192.168.56.11 -j DROP` :::warning Q&A 想想為什麼我這邊擋了 INPUT 但我嘗試去 `ping 192.168.56.11` 的時候也是會沒有反應 ::: - `-d, --destination`: 封包的目的 IP 位址 `sudo iptables -t filter -I OUTPUT -d 192.168.56.11 -j DROP` - `!`: 用在 `-s` 跟 `-d` 之前,指不是這個 IP 的時候 `sudo iptables -t filter -I INPUT ! -d 192.168.56.11 -j DROP` #### 針對協定設定規則 - `-p, --protocol`: 封包使用的協定 `sudo iptables -t filter -I INPUT -p ICMP -j DROP` #### 針對 port 設定規則 > 在 `-p` 指定是 `tcp` 或是 `udp` 時可以使用 - `--sport`: 封包來源的 port `sudo iptables -I OUTPUT -p tcp --sport 80 -j ACCEPT` - `--dport`: 封包目的的 port `sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT` #### 刪除 rule - 刪除 `filter` table `OUTPUT` chain 的第 1 個 rule `sudo iptables -t filter -D OUTPUT 1` - 清空 `filter` table `INPUT` chain 所有的 rule `sudo iptables -t filter -F INPUT` > 若後面不加 chain 會清空整張 table 內的所有規則 :::info **conntrack** 內建在 netfilter subsystem 用於**記錄連線狀態**的模組,有以下幾種狀態 | 名稱 | 記錄的狀態 | | ------------- |:----------------------------------- | | `NEW` | 新建立的連線 | | `ESTABLISHED` | 已建立的連線、NEW 封包的回應封包 | | `RELATED` | 新的連線,但與已建立的連線相關 | | `INVALID` | 無效,無法識別狀態的封包 | | `UNTRACKED` | 在 `raw` table 被標示關閉追蹤的封包 | ![image](https://hackmd.io/_uploads/ByGiiOyz1l.png) 但因為需要載入額外的模組,以及儲存這些連線的狀態,所以會有額外的記憶體開銷 **demo** 情境: 我們想阻止來自特定 IP(192.168.56.11) 的所有請求,但希望主機還是能夠對它發送請求,並成功接收到它的回應 ![LSA Firewall Page 4](https://hackmd.io/_uploads/BJBzD0ZMyg.svg) 如之前所述,可以先使用這個 iptables 規則擋住來自 192.168.56.11 的所有流量 `sudo iptables -t filter -I INPUT -s 192.168.56.11 -j DROP` 但這樣也會同時阻擋掉 192.168.56.11 的回應,這個情況就可以利用 conntrack 的狀態追蹤功能,單獨允許回應的封包 `sudo iptables -t filter -I INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT` 封包的流程如下: 1. 當我們向 192.168.56.11 發送 ping 時,conntrack 會記錄這條連線的狀態。 2. 當 192.168.56.11 回應我們的 ping 時,回應流量會被標記為 `ESTABLISHED` 狀態 3. 防火牆會檢查這個狀態,發現回應是我們允許的 `ESTABLISHED` 狀態,因此允許其通過 :::warning Q&A 若是不想用 conntrack,我們可以使用 `sudo iptables -t filter -I INPUT -s 192.168.56.11 -p icmp --icmp-type 0 -j ACCEPT` 這條規則去允許 192.168.56.11 對於 ping 的回覆,但這樣會有什麼樣的問題? ::: :::info Stateful Firewall vs. Stateless Firewall Stateless Firewall 無狀態防火牆,**不會記錄封包的狀態**,就會造成前面 QA 關於 ping 的狀況 而 Stateful Firewall 有狀態防火牆,就是**會記錄封包狀態**的防火牆,可以根據連線的狀態設定更靈活的防火牆規則 ::: ### 儲存 iptables 的設定 直接使用 `iptables` 的指令不會自動儲存在系統中,關機後就會消失,`iptables` 有提供幾個工具可以使用 #### `iptables-save` 儲存目前的 `iptables` 的設定 `iptables-save > 檔案路徑` #### `iptables-restore` 使用設定檔恢復 `iptables` 的設定 `iptables-restore < 檔案路徑` #### `iptables-apply` 用來測試新的 iptables 規則,套用新規則時若太長時間 (預設是 10 秒) 沒有回應就會自動恢復成舊的設定 `iptables-apply 檔案路徑` > 預設的路徑是: `/etc/network/iptables.up.rules` # Lab ## NAT ![image](https://hackmd.io/_uploads/SJPxvEfGke.png) - 網路位址轉譯 (Network Address Translation) - 改變網路封包中的 IP 位址資訊,使不同網路之間能夠進行通訊 - 可以節省 IP 位置 - 主要有 **SNAT (Source Network Address Translation)** 跟 **DNAT (Destination Network Address Translation)** ### SNAT #### 情境: 內網主機 (192.168.1.100) 要連線到 yahoo.com.tw ![image](https://hackmd.io/_uploads/S1bsCBzMJx.png) 1. 內網主機 192.168.1.100 發送封包給 Firewall (NAT 主機) 2. Firewall 尋找路由表,發現目的地不在直接連接的網路,也沒有紀錄指定該往哪裡送,所以透過路由表找到「default gateway」並使用對應的網路介面卡 3. 因目前封包的 source IP 是內網 IP,直接送出去的話會造成對方的錯亂,誤會來源位置,所以,會在 `POSTROUTING` chain 把來源 IP 修改成 Firewall 對外的 IP,這時 **NAT translation table** 把這兩個來源 IP、port 的對應關係記錄起來,之後回應封包傳回來時就能知道要傳給內網的哪台主機 ![image](https://hackmd.io/_uploads/ByOQ-Lfz1l.png) ![image](https://hackmd.io/_uploads/HJRNbLGGye.png) 4. 封包從外部網路傳回來,目的地是 Firewall 的外網 IP 5. 在 `PREROUTING` chain 根據 **NAT translation table** 的紀錄更改封包目的地 `sudo iptables -t nat -I PREROUTING -o {外網網卡} -j SNAT --to {NAT 主機的外網網卡 IP}` 6. 封包轉發給內網主機 (192.168.1.100) :::info `MASQUERADE` 有時候 Firewall 取得的外網 IP 不會是固定的 IP,可能會隨時間變動,而若是這種情況有可能會需要頻繁地去更動 SNAT 的規則,`MASQUERADE` 就是為了因應這樣的情況,他會自動找尋能連接上外網的網路介面卡,然後使用那張網卡的 IP 位置當作 SNAT 的來源 IP ::: ### DNAT #### 情境: 在內網主機架了 Web Server,要讓外網能夠連進來 ![image](https://hackmd.io/_uploads/SylASUzz1x.png) 1. 外網主機先向 Firewall 發送請求 2. Firewall 收到封包後,在 `PREROUTING` chain 將目的 IP 從 Firewall 的外網 IP 改成內網 Web Server 的 IP,然後也會在 **NAT translation table** 把這兩個目的 IP、port 的對應關係記錄起來 `sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 192.168.1.210:80` 3. 封包會路由到內網網卡 (192.168.1.2),然後再傳送到目的地 (192.168.1.210) ![image](https://hackmd.io/_uploads/S1BTDUMMkg.png) ### 統整 | | SNAT | DNAT | |:-------- |:---------------------- |:------------------------ | | 功用 | 更改封包的來源 IP | 更改封包的目的 IP | | 使用場景 | 讓內網主機可以連線外網 | 讓外網能主動連到內網主機 | ### Demo ![LSA Firewall Page 5](https://hackmd.io/_uploads/r1azr4Mzyl.svg) #### 準備環境 **Firewall (NAT 主機)** 要先開啟 Linux 轉發封包的功能 1. `sudo vim /etc/sysctl.conf` 2. 把這行的註解取消 ``` # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 ``` 3. `sudo sysctl -p` **Server (內網的 Web Server)** 1. `sudo ip route del default` 2. `sudo ip route add default via 10.0.0.10 dev eth1` #### iptables 規則設定 **功能要求** 1. 將內網主機要送往外網的封包,透過 Firewall 轉送到外網,且回應的封包,能夠回傳給內網主機 `sudo iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.56.21` 或使用 `MASQUERADE` `sudo iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE` 2. 將外網連線到 Firewall 80 port 的封包,轉發到內網主機 8080 port 上的 Web Server `sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.11:8080` ![image](https://hackmd.io/_uploads/ryxYrvMf1e.png) ## DMZ ![image](https://hackmd.io/_uploads/BkHWdOfGyx.png) **功能要求** - 外網可以直接連線 DMZ,但不能直接連線 LAN - DMZ 可以直接連線外網,但不能直接連線 LAN - LAN 可以直接連線外網,也可以直接連線 DMZ **環境** - Firewall 主機上設定防火牆 - DMZ 中有一台**對外開放**的 Web Server 主機,80 port 上有 web service - LAN 中有一台**不對外開放**的 Student 主機 - 外網透過連線到 Firewall 主機的 8080 port,可以連線到 Web Server 主機的 80 port - `INPUT`、`FORWARD`、`OUPUT` 的 policy 都是 `ACCEPT` ### 準備環境 **Firewall (NAT 主機)** 要先開啟 Linux 轉發封包的功能 1. `sudo vim /etc/sysctl.conf` 2. 把這行的註解取消 ``` # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 ``` 3. `sudo sysctl -p` **DMZ 和 LAN 的 default gateway (設成 Firewall 主機 IP)** 1. `sudo route del default` 2. `sudo route add default gw {Firewall IP}` ### 設定規則 - 外網能透過 Firewall 連到 DMZ 的 web server ```shell sudo iptables -t nat -A PREROUTING -i {外網網卡} -p tcp --dport 8080 -j DNAT --to {Web Server IP}:80 ``` - 同意該封包轉送 ```shell sudo iptables -A FORWARD -i {外網網卡} -d {Web Server IP} -p tcp --dport 80 -j ACCEPT ``` - DMZ 能夠連到外網 ```shell sudo iptables -I FORWARD -i {DMZ 網卡} -o {外網網卡} -j ACCEPT sudo iptables -t nat -I POSTROUTING -o {外網網卡} -j MASQUERADE ``` - LAN 能夠連到外網 ```shell sudo iptables -I FORWARD -i {LAN 網卡} -o {外網網卡} -j ACCEPT # 出去的封包做 MASQUERADE 上面已經設過,這裡就不再設定 ``` - LAN 能夠連到 DMZ ```shell sudo iptables -I FORWARD -i {LAN 網卡} -o {DMZ 網卡} -j ACCEPT ``` - 允許轉送已建立或相關的連線 ```shell sudo iptables -I FORWARD -m conntrack --ctstate "ESTABLISHED,RELATED" -j ACCEPT ``` - 拒絕其他所有進入 Firewall 主機的連線 ```shell sudo iptables -A INPUT -j DROP ``` - 拒絕轉送其他所有連線 ```shell sudo iptables -A FORWARD -j DROP ``` :::warning Q&A 這裡為什麼要用 `-A` ::: <!-- # nftables :::info nftables 是作為 iptables 的替代,較新的 Linux 發行版都逐漸向 nftables 靠攏,但這學期上課使用的 Ubuntu 22.04 (Jammy Jellyfish) 還是預設使用 iptables (但到 24.04 就預設使用 nftables),所以這次課程內容以 iptables 為準 ::: :::info nftables 補充 nftables 維持了 tables、chains、rules 的架構,但已捨棄預先定義的上述的 iptables 的資源,只依照自訂的 chain 要註冊在哪個 netfilter hook 上,還有設定的優先級來決定規則順序 ::: --> # UFW (Uncomplicated Firewall) 使用 iptables 或是 nftables 作為後端,提供比較簡單的介面 ### 安裝 (通常 Ubuntu 已經預設安裝) `sudo apt install ufw` ### 開/關 `sudo ufw enable` `sudo ufw disable` ### 查看防火牆狀態 `sudo ufw status` `sudo ufw status verbose` `sudo ufw status numbered` ### 設定預設規則 `sudo ufw default allow` `sudo ufw default deny` ### 針對服務或是 port 設定規則 `sudo ufw allow ssh` `sudo ufw deny 80` > 針對一個範圍的 port & protocol `sudo ufw allow 6000:6007/tcp` ### 針對 IP `sudo ufw allow from 192.168.11.10` > 針對網段 `sudo ufw deny from 192.168.11.0/24` > 拒絕某 IP 連到某 port `sudo ufw deny from 192.168.11.7 to any port 22` ### 刪除規則 `sudo ufw delete 3` > 重設 `sudo ufw reset`