NCNU-OpenSource
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    - 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`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully