防火牆必須位於封包實際經過的位置,才能依照來源、目的、協定與連線狀態執行安全規則。將 OPNsense 部署成虛擬機時,還要先處理一個更底層的問題:PVE 提供的虛擬網卡進入 OPNsense 後,如何對應成 WAN、LAN 與內部網路介面?
這段對應關係如果發生錯誤,WAN 可能被接進內部網路,管理介面也可能完全無法連線。本文會先介紹 OPNsense 的架構,再從 PVE 虛擬網卡一路說明到 FreeBSD 網路裝置與 OPNsense 介面。理解各層責任後,最後才進入實際安裝、管理連線與主控台救援。
vtnet?本文閱讀方式
- 完整理解技術與底層原理:依序閱讀全文。
- 掌握完成部署所需的基本概念:優先閱讀標有「⭐」的章節。
- 快速了解當天的部署內容:閱讀文末的 Lab/實作章節。
- 跟著系列建立完整系統:依照 GitHub 詳細部署文件 的天數順序操作。

圖(一)OPNsense 開源防火牆與路由平台
OPNsense 是由 Deciso 發起的開源防火牆與路由平台(Open-source Firewall and Routing Platform),採用 BSD 2-Clause License,底層作業系統為 FreeBSD。它將防火牆、路由、網路位址轉換、VPN、DHCP、DNS與入侵偵測/防禦系統(IDS/IPS)整合在同一套作業系統與管理介面中。
使用者主要透過網頁管理介面(Web GUI)設定 OPNsense,實際處理封包的工作則由 FreeBSD 核心、網路堆疊、pf 與各項服務共同完成。先從封包實際經過的資料平面(Data Plane)來看:

圖(二)OPNsense 入站、出站與本機服務的封包路徑
以入站與出站來看,從網路卡進入的封包會先經過 pf 的入站處理。目的地是 OPNsense 本機時,通過規則後才會送到服務的通訊端(Socket),目的地是其他網路時,則會在路由判斷後繼續接受出站處理。OPNsense 本機服務主動送出的封包,則從通訊端進入網路堆疊,再經過 pf 的出站處理。
pf 是封包過濾器(Packet Filter)的縮寫,也是 OPNsense 使用的核心封包過濾系統。封包進入介面後,pf 會依來源、目的、協定、連接埠與方向執行規則,並透過狀態表追蹤已建立的連線。第一個封包通過後,合法的回程封包便能沿用既有狀態。

圖(三)pf 以狀態表辨認符合既有連線的回程封包
執行 NAT 時,pf 也會在狀態資訊中保存轉換前後的連線對應,讓後續封包能沿著同一組關係往返。
前面的資料平面說明封包如何通過系統。那管理者修改設定時 OPNsense 又會如何運作。OPNsense 核心(OPNsense Core)提供設定資料模型、網頁管理介面、API、config.xml 與設定服務 configd。

圖(四)OPNsense 從保存設定到套用變更的流程
OPNsense 官方將管理架構分成前端(Frontend)與後端(Backend)。PHP/Phalcon 實作的前端處理 Web GUI 與 REST API 的操作,通過驗證的資料會寫入 /conf/config.xml 持久保存。Python 實作的後端核心服務 configd 再讀取設定並與系統互動。configd 可以產生服務設定、呼叫 pfctl 載入防火牆規則,或透過 rc 腳本管理服務。它負責協調設定變更,平常不在一般封包的資料路徑上。
FreeBSD 核心中的 pf 執行封包過濾、狀態追蹤與 NAT。Unbound、sshd、OpenVPN 等背景服務則各自處理送往本機通訊端的流量或主動建立對外連線。額外功能可以透過 FreeBSD 套件(Package)與 OPNsense 外掛(Plugin)擴充。
這種分層和 PVE 叢集設定的概念相似:管理介面接受操作、設定系統保存資料、底層服務負責執行。PVE 透過 pmxcfs 管理 /etc/pve,OPNsense 則以 config.xml 與 configd 協調各項服務。兩套系統的實作不同,但都把操作入口、設定資料與執行元件分開。
本次 Lab 使用社群版(Community Edition)。OPNsense 也提供商業版(Business Edition)、官方硬體與商業支援。
OPNsense 在整體架構中就是網路防火牆與路由器。它位於 WAN 與各個內部 VLAN 之間,集中處理以下工作:
前面提到,防火牆必須位於封包實際經過的路徑。跨 VLAN 流量由 OPNsense 路由,因此可以套用防火牆規則。同一 VLAN 內直接交換的流量則要由 PVE 防火牆或主機防火牆補足限制。
前面已經介紹過 VM 虛擬網卡、TAP 虛擬乙太網路裝置與 Linux 橋接器(Linux Bridge)的關係。將 OPNsense 安裝成 PVE 虛擬機後,這條路徑還會延伸到 FreeBSD 網路裝置與 OPNsense 介面:

圖(五)PVE 虛擬網卡進入 FreeBSD 與 OPNsense 的對應關係
Linux Bridge 負責 PVE 主機內的第二層轉送,TAP 是 VM 虛擬網卡在 PVE 端的出口。PVE VM 設定中的 net0、net1 等名稱,是虛擬化管理程式用來管理網卡的索引。
OPNsense 內的 FreeBSD 會透過 vtnet 驅動程式接管 VirtIO NIC,因此網卡會顯示為 vtnet0、vtnet1 等裝置名稱。這和 Linux 以 ens18 等名稱識別網路卡的概念相同,只是 FreeBSD 使用的驅動程式與命名方式不同。
net0、net1 是虛擬化管理端的網卡索引。vtnet0、vtnet1 識別 Guest OS 內的網路裝置。也就是這些名稱描述的是同一條虛擬連線在不同層次的觀察結果。
這組編號反映目前的硬體偵測結果,刪除、增加或調整虛擬網卡後,偵測順序可能改變。MAC 位址會同時出現在 PVE 與 FreeBSD,因此應使用 MAC 位址核對同一張網卡。
建立或調整防火牆 VM 時,至少要記錄:
vtnet 裝置名稱。這份對照表也能協助設定移轉。將 config.xml 還原到另一台虛擬或實體設備後,新的硬體可能使用不同裝置名稱,管理者必須重新確認介面指派。
FreeBSD 偵測到 vtnet0 後,只代表作業系統擁有一個可以收送乙太網路訊框的網路裝置。這個裝置尚未具備 WAN 或 LAN 的用途,也沒有對應的 IP、閘道、DHCP 與防火牆政策。
OPNsense 透過介面指派(Interface Assignment),將網路裝置綁定到 WAN、LAN 或 OPT 等邏輯介面:

圖(六)FreeBSD 網路裝置經過介面指派後對應成 WAN、LAN 與 OPT 介面
介面指派的來源不只實體網路卡。VLAN、鏈路聚合與容錯介面 LAGG(功能上類似 Linux Bonding)、橋接器與部分通道等虛擬網路裝置建立後,也可以被指派成 OPNsense 介面。換句話說,vtnet0 是網卡裝置,建立在父裝置上的 VLAN 裝置也是可供指派的裝置。
WAN、LAN 與 OPT 是 OPNsense 賦予網路裝置的管理角色,每個角色都可以綁定不同的實體或虛擬裝置:
介面完成指派後,才能在該介面上設定 IP、服務與防火牆規則。VLAN 負責切分第二層網路。OPNsense 介面則替每個網路提供閘道並套用安全政策。在我們這個系列,一個 VLAN 對應一個主要安全區域,使網路邊界與規則責任保持清楚。
虛擬網卡接到啟用 VLAN-aware 的 Linux Bridge 後,可以透過 Access Port 或 Trunk 交付流量。
Access Port 只承載單一 VLAN,VLAN 標籤終止於 PVE。PVE 會在訊框進入 VM 前移除標籤,OPNsense 收到未帶標籤的乙太網路訊框,可以直接把 vtnet 指派成 LAN 或其他介面。

圖(七)Access Port 由 PVE 處理 VLAN 標籤
上圖的標籤在 PVE 端加入或移除,進入 OPNsense 的 vtnet 後只剩未標籤訊框,因此一張虛擬網卡只對應一個 VLAN。
Trunk 同時承載多個 VLAN,VLAN 標籤一路保留到 OPNsense。OPNsense 收到帶有標籤的訊框後,以 vtnet 為父介面,依 VLAN ID 建立多個 VLAN 子介面。

圖(八)Trunk 將多個帶標籤 VLAN 交給 OPNsense 分流
上圖的標籤會穿過 PVE、TAP 與 VirtIO NIC,最後由 FreeBSD 的 VLAN 子裝置依 VLAN ID 分流,所以同一張虛擬網卡可以承載多個 VLAN。
判斷方式很直接:標籤由 PVE 處理,就把 OPNsense 的 vtnet 當成單一網路裝置。標籤保留到 OPNsense,就在 vtnet 上建立 VLAN 子裝置。兩端對標籤的處理方式必須互相配合,否則介面會收不到預期流量。
本系列同時使用這兩種方式:
net1 接到 vmbr2 並設定 VLAN Tag 10,因此 OPNsense 的 vtnet1 收到未標籤訊框,可以直接指派成 LAN。net2 接到 vmbr2 且 VLAN Tag 留白,讓 VLAN 20~50 的標籤保留到 OPNsense。後續會以 vtnet2 為父裝置建立 VLAN 子裝置,再分別指派成服務、資料庫、備份與跳板安全區域。OPNsense 的網頁管理介面需要逐層滿足以下條件:
建置初期先從與 OPNsense LAN 位於同一子網路的主機測試連線。這樣只需確認介面指派、IP 與 HTTPS 服務,還不用依賴尚未完成的跨 VLAN 路由與防火牆規則。
OPNsense 可以安裝在實體設備,也可以部署成虛擬機。無論採用哪一種形式,都應保留一條不經過 OPNsense 管理介面的主控台路徑。實體設備可以使用本機螢幕、鍵盤或序列主控台。虛擬機則使用虛擬化平台提供的主控台。
網頁管理介面因介面、IP 或服務設定錯誤而失聯時,管理者可以從主控台執行:
恢復出廠設定會清除目前配置,只適合確定要重新建立整套設定的情況。一般管理失聯應先修正介面或重新啟動網頁管理服務,再評估是否還原設定。
本次 Lab 的 OPNsense 是 PVE 虛擬機,因此使用 L0 PVE 主控台進行救援。OPNsense 本身也能獨立安裝在實體設備。正式環境若使用實體防火牆,則應保留設備本身的本機、序列或頻外管理入口。
正文已經說明 OPNsense 的封包處理、介面抽象、Access Port、Trunk 與救援路徑。本次 Lab 將 OPNsense 安裝成 fw01,建立 WAN、管理網路與內部 Trunk,並從 L0 一路驗證到網頁管理介面。VLAN 20~50 與跨區防火牆規則尚未在今天建立。
GitHub 詳細實作文件:Day 11|安裝 OPNsense 與主控台(Console)救援
本文使用 VMID 110。完整文件包含 ISO 選擇、PVE 每一頁欄位、介面指派、更新與故障排除,以下只保留能驗證正文的核心操作與結果。
fw01 使用 2 Cores、3072 MiB RAM、16 GB 系統磁碟與三張 VirtIO 虛擬網卡。三張網卡連到不同的橋接與 VLAN 處理位置:
| PVE 裝置 | L0 橋接器 | PVE VLAN 標籤 | OPNsense 裝置/角色 | 用途 |
|---|---|---|---|---|
net0 |
vmbr0 |
留白 | vtnet0/WAN |
向上游路由器取得 DHCP 位址 |
net1 |
vmbr2 |
10 |
vtnet1/LAN |
管理網路,10.77.10.1/24 |
net2 |
vmbr2 |
留白 | vtnet2/OPT1 |
VLAN 20~50 內部 Trunk |

圖(九)fw01 的 WAN、管理 Access Port 與內部 Trunk
net1 的 VLAN Tag 10 由 PVE 處理,所以 OPNsense 收到未標記的管理流量。net2 不填 VLAN Tag,後續才能讓多個帶標籤 VLAN 通過同一張 Trunk。建立 VM 後還要保存三張網卡的 MAC 位址,作為 OPNsense 介面指派的核對依據。
使用 dvd ISO 完成安裝後,退出安裝媒體並讓 fw01 從 scsi0 啟動。接著從 PVE 主控台選擇 1) Assign interfaces,依 MAC 位址完成以下指派:
WAN → vtnet0 → vmbr0
LAN → vtnet1 → vmbr2/VLAN Tag 10
OPT1 → vtnet2 → vmbr2/Trunk

圖(十)依 MAC 位址核對並完成 WAN、LAN 與 OPT1 指派
再從 2) Set interface(s) IP address 設定 LAN:
IPv4:10.77.10.1/24
閘道(Gateway):不設定
IPv6:暫不設定
DHCP 伺服器(DHCP Server):關閉
網頁管理介面:HTTPS
LAN 不設定閘道,因為預設路由由 WAN 負責。DHCP Server 保持關閉,避免在完整位址規劃完成前發送租約。WAN 暫時向上游路由器取得 DHCP 位址,提供系統更新所需的對外路徑。
L0 的 vmbr2.10 使用 10.77.10.10/24,與 fw01 LAN 的 10.77.10.1/24 位於同一個子網路。先在 L0 執行完整的連線檢查:
ping -c 3 10.77.10.1
curl -kI --connect-timeout 3 https://10.77.10.1/
Ping 成功只能證明 IP 可達。curl 收到 HTTPS 回應,才能證明網頁管理服務正在 TCP 443 接受連線。兩項都成功後,從管理電腦建立 SSH 本機通訊埠轉送:
ssh -L 8443:10.77.10.1:443 root@192.168.0.146
保持 SSH session 執行,再由瀏覽器開啟:
https://127.0.0.1:8443
第一次開啟會看到自簽憑證警告。繼續以前,先確認瀏覽器連線目標為本機 127.0.0.1:8443,而且 SSH Tunnel 確實轉送到 fw01 的 TCP 443。進入初始設定精靈後完成以下基線:
fw01
lab.home
Asia/Taipei
10.77.10.1/24

圖(十一)OPNsense 的主機名稱、內部網域與時區設定
這張畫面確認已進入 OPNsense Web UI 並完成基線設定。L0 到 HTTPS 的可達性,則由前面的 Ping、curl 與 SSH Tunnel 操作共同驗證。
更新前先到 System → Configuration → Backups 匯出 config.xml:

圖(十二)更新前先下載一份 OPNsense 設定備份
接著到 System → Firmware → Status 檢查更新。除非要測試開發版本,否則不要把 Release Type 切換成 Development。更新失敗時,依序檢查 WAN、DNS、預設閘道與 Firmware Mirror。

圖(十三)從 Firmware Status 檢查版本與可用更新
更新完成並重新開機後,記錄實際版本並再次匯出 config.xml。設定檔可能包含密碼雜湊、憑證、私鑰與其他敏感資料,必須存放在受控且加密的位置,不可提交到公開的版本庫。
新版 OPNsense 主控台的選項 11 為 Reload all services,可從不依賴 OPNsense 網路設定的 PVE 主控台重新載入各項服務。執行後回到 L0,再次確認 fw01 的 HTTPS 服務:

圖(十四)新版 OPNsense 主控台的選項 11 可重新載入所有服務
curl -kI --connect-timeout 3 https://10.77.10.1/

圖(十五)重新載入服務後,L0 再次收到 fw01 的 HTTPS 回應
畫面回傳 HTTP/2 403,代表 TLS 與 HTTP 服務已經回應這次 HEAD 請求。它可以證明 TCP 443 上的 HTTPS 服務可達,但不能單獨證明使用者已經成功登入 Web UI。
本日不執行 Factory Reset。它會清除既有設定,不適合作為一般連線問題的第一個排錯步驟。
管理介面無法開啟時,依序檢查 fw01 VM、PVE vNIC 與 VLAN Tag、FreeBSD 裝置指派、LAN IP、L0 vmbr2.10、ARP/Ping、TCP 443、SSH Tunnel,最後才是瀏覽器。先找出路徑在哪一段中斷,再修改對應設定,不要直接加入允許所有流量的規則掩蓋問題。
| 驗證 | 主要證據 | 可以得到的結論 |
|---|---|---|
| 驗證一:三條網路路徑 | fw01 Hardware 與三張 vNIC 設定 | WAN、管理 Access Port 與內部 Trunk 已接到預定橋接器 |
| 驗證二:介面指派 | MAC 位址與 OPNsense 主控台 | vtnet0、vtnet1、vtnet2 已分別指派為 WAN、LAN、OPT1 |
| 驗證三:管理入口 | Ping、HTTPS、SSH Tunnel 與 Web UI | 管理路徑已從 L0 延伸到 OPNsense Web UI |
| 驗證四:系統基線 | config.xml 與 Firmware Status | 更新前後都有可識別版本與設定備份 |
| 驗證五:主控台救援 | Reload all services 與重新取得的 HTTPS 回應 |
管理者可從 PVE 主控台重新載入服務,L0 隨後可連到 HTTPS |
單台 fw01 是網路與管理入口的單點。正式環境可使用兩台 OPNsense 搭配 CARP VIP、pfsync 與設定同步,但兩台設備的 WAN、LAN、Trunk 與同步介面必須一一對應。交換器、ISP/ONU、電力與實體線路也要另外處理。設定備份必須加密保存,更新與規則變更前則要準備主控台、序列埠或頻外管理等救援路徑。
原本規劃中是有包含雙 OPNsense 備援,但每篇文章的篇幅真的已經太多了,實在難以再安排完整章節,我也不希望為了這個部分而去壓縮其他章節的整體品質與內容。未來若有時間,我會再另外補充相關內容,這 30 天我們就以其他更核心的組件為主。
下一篇是 Day 12|WAN 如何連上網際網路:OPNsense 的 DHCP、PPPoE、NAT 與 DDNS。我們會從外部線路往內確認 WAN 如何取得位址、建立預設路由,以及出站(Outbound)與入站(Inbound)兩條驗證路徑。