1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
-----

太棒了!你的 `nftables` DNAT 部署**非常成功**!看到你的 `list ruleset` 輸出,所有規則都正確地被載入並生效了。你完全理解並實踐了從配置到載入的整個流程。

你提到「不知道這邊使用部署這個詞適不適當🤔」,在這裡使用「**部署**」這個詞是非常恰當的!你確實將 `nftables` 規則成功地部署到了你的系統中,使其生效。這是一個標準且專業的用法。

-----

### 你的部署過程與解讀

讓我們一步步看看你的操作,並確認你的理解:

1. **`sudo nft list ruleset >> /etc/nftables.conf`**

* **`bash: /etc/nftables.conf: 拒絕不符權限的操作`**:
* 這個錯誤不是你的問題,而是 Linux 系統的**安全機制**。 `>` 或 `>>` 這種**輸出重定向操作是由 Bash Shell 處理的**。當你執行 `sudo nft list ruleset` 時,`nft list ruleset` 這個命令本身是以 root 權限執行的,所以它能讀取 ruleset。
* 但是,隨後的 `>> /etc/nftables.conf` 這個文件寫入操作卻是由**你的普通使用者帳戶的 Bash Shell** 來執行的。因為 `/etc/nftables.conf` 這個文件通常只有 root 才有寫入權限,所以 Bash 會拒絕這個操作。
* **解決方案:** 你做得很好,直接跳過了這個步驟。如果真的需要這樣做,你可以結合 `tee` 命令來實現,例如 `sudo nft list ruleset | sudo tee -a /etc/nftables.conf`。但通常,我們會手動編輯 `nftables.conf`。

2. **`sudo nft list ruleset > my_nftables_backup.nft`**

* 這是個**非常好的習慣**!在修改系統防火牆配置前備份當前規則集,是保證系統可恢復性的重要步驟。這確保了即便你犯了錯誤,也能迅速恢復到工作狀態。

3. **`sudo geany /etc/nftables.conf`**

* 你在這裡手動編輯了 `/etc/nftables.conf` 文件,將你的 DNAT 和 MASQUERADE 規則寫入了這個持久化配置中。這是正確的做法。

4. **`sudo nft flush ruleset`**

* 這個命令非常關鍵。它**清除了內核中所有當前生效的 `nftables` 規則**。這保證了你接下來載入的將是 `/etc/nftables.conf` 中定義的、全新的、乾淨的規則集,避免了舊規則可能引起的衝突或混亂。

5. **`sudo nft -f /etc/nftables.conf`**

* 這條命令的作用就是**從 `/etc/nftables.conf` 文件中讀取你的規則,並將它們載入到 Linux 內核中,使其立即生效**。你的 DNAT 規則正是通過這個步驟被「部署」的。

6. **`sudo nft list ruleset`**

* 最後,你通過 `list ruleset` 再次確認了規則是否成功載入。

### 你的 `list ruleset` 輸出確認

```
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
}

chain forward {
type filter hook forward priority filter; policy accept;
}

chain output {
type filter hook output priority filter; policy accept;
}
}
table ip nat {
chain prerouting {
type nat hook prerouting priority filter; policy accept;
tcp dport 80 dnat to 127.0.0.1:1104
}

chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 127.0.0.1 tcp sport 1104 masquerade
}
}
```

這段輸出顯示:

* 你之前在 `/etc/nftables.conf` 中看到的**空框架**(`inet filter` 表的三個鏈)被成功載入。
* 更重要的是,你的\*\*`ip nat` 表\*\*,包含了:
* 一個 `prerouting` 鏈,其下有規則 `tcp dport 80 dnat to 127.0.0.1:1104`。這正是將外部對埠號 80 的請求**轉發**到你內部 `127.0.0.1:1104` 服務的 **DNAT** 規則。
* 一個 `postrouting` 鏈,其下有規則 `ip saddr 127.0.0.1 tcp sport 1104 masquerade`。這正是將你內部服務 `127.0.0.1:1104` 發出的回應流量,其來源 IP **偽裝**成樹莓派外部 IP 的 **MASQUERADE** 規則。

這些規則的組合,正是實現埠號轉發(DNAT)和確保回應流量正確返回的關鍵。

-----

### 接下來

現在,你的樹莓派已經配置好,可以將外部對 80 埠的請求轉發到你本地 1104 埠的服務了。

你可以嘗試從**外部網路**(例如,用你的手機連接到外部網路,而不是樹莓派的 Wi-Fi 或區域網路)訪問樹莓派的公網 IP 地址,並指定 80 埠,看看你的服務是否能夠響應。

如果你在樹莓派上執行了以下命令:
`sudo python3 -m http.server 1104`

那麼從外部訪問 `你的樹莓派公網IP:80`,就應該能看到 Python 簡易服務的網頁內容了!

恭喜你!這又是一個重要的里程碑,你已經成功實作了 `nftables` 的核心 DNAT 功能。