martin-ger/esp32_PPPoE_router
GitHub: martin-ger/esp32_PPPoE_router
基于 ESP32 和 WT32-ETH01 开发板的轻量级 PPPoE NAT 路由器固件,集成了防火墙、WireGuard VPN、动态 DNS 和 Web 管理界面。
Stars: 2 | Forks: 0
# ESP32 PPPoE 路由器
一个基于 ESP32 的 NAT WAN 路由器,专为带有有线上行链路的 **[WT32-ETH01](https://github.com/egnor/wt32-eth01)** 开发板设计。它可以直接与 WAN/DSL/有线调制解调器进行 PPPoE 通信,同时也支持用于纯以太网上行链路的 DHCP。客户端通过 WiFi(softAP)连接。包含完整的 Web 界面、防火墙、DHCP 预留、端口转发、WireGuard VPN 以及可选的 PCAP 抓包功能。
## 使用场景
- 无需独立调制解调器路由器即可实现 PPPoE DSL / 有线调制解调器接入
- 带有有线上行链路的 WiFi 接入点,提供可靠的吞吐量
- 具有每客户端流量监控和防火墙功能的轻量级旅行或实验室路由器
## 功能
- 基于 802.3 以太网的 PPPoE 上行链路(PAP / CHAP / auto,可选 VLAN tag)
- 具有四个 ACL 列表和命中计数器的无状态包防火墙
- 具有 IP 预留、客户端封锁和静态地址池的 DHCP 服务器
- 带有设备名称解析的端口转发(TCP / UDP)
- WireGuard VPN 客户端(全路由或分流隧道、断线开关、绑定 VPN 的端口映射)
- 具有自动 WAN IP 注册的动态 DNS (DDNS) —— 支持 NoIP、DuckDNS、Selfhost.de、Dynu 和 Namecheap
- 通过 TCP 流式传输到 Wireshark 的 PCAP 数据包捕获 —— 可选构建功能,默认禁用
- 基于 TCP 的远程 CLI 控制台(受密码保护)
- 远程 syslog 转发(UDP,RFC 3164)
- 通过 Web 界面进行 OTA 固件更新
- 通过 Web 界面进行配置备份/恢复(纯 JSON 或通过密码加密)
- 可选的每客户端流量统计
- TTL 覆盖和 TCP MSS 钳制
- WiFi 监管国家代码 —— 设置允许的信道范围(FCC/ETSI/TELEC)
## 硬件 — WT32-ETH01
WT32-ETH01 是一款紧凑型的 ESP32 模块,集成了 LAN8720A 以太网 PHY,使其成为无需外部 MAC 芯片的有线上行链路路由器的理想选择。
| 参数 | 值 |
|-----------|-------|
| MCU | ESP32 (240 MHz 双核) |
| Flash | 4 MB |
| 以太网 PHY | LAN8720A (RMII) |
| WiFi | 802.11 b/g/n 2.4 GHz |
| MDC GPIO | 23 |
| MDIO GPIO | 18 |
| PHY 地址 | 1 |
| PHY 电源 GPIO | 16 |
## Web 界面
在连接到路由器 WiFi 网络的任何设备上,通过 `http://192.168.4.1`(或配置的 AP IP)即可访问。端口可配置;默认为 80。
### 页面
**/ — 状态**
实时仪表板,显示上行链路状态、上行 IP、字节计数器、NAPT 表使用情况、已连接客户端列表(包含 MAC、IP、设备名称和可选的每客户端 TX/RX)、空闲堆栈和运行时间。还包含登录表单和密码管理。
**配置**
完整的路由器配置,分为多个部分:
- AP 设置(SSID、密码、信道、认证模式、隐藏 SSID、IP 范围、MAC)—— 信道的最大值根据配置的国家/地区代码进行强制限制
- STA / 上行链路模式和设置(静态 IP)
- 远程控制台设置(端口、超时)
- PCAP 监控设置(模式、snaplen)—— 仅在使用 `CONFIG_PCAP_CAPTURE` 构建时显示
- 系统设置(OTA 更新、配置备份 / 恢复)
**PPPoE**
PPPoE 设置(用户名、密码、服务名称、认证模式、VLAN、baby-jumbo)
**映射**
DHCP 租约和预留管理,以及端口转发规则:
- 带有活动租约的 DHCP 地址池概览
- 通过 MAC 和设备名称添加 / 删除 IP 预留
- 阻止某设备获取 IP
- 添加 / 删除 TCP 和 UDP 端口转发规则
**防火墙**
跨所有四个包流列表(`to_esp`、`from_esp`、`to_ap`、`from_ap`)的 ACL 规则管理。添加包含协议、源/目的地 CIDR、端口以及允许/拒绝/监控操作的规则。查看每个规则的命中计数器并清除统计信息。
**VPN**
WireGuard 配置:私钥、对端公钥、可选的预共享密钥、endpoint 主机和端口、隧道 IP、子网掩码、持久化 keepalive、全路由 / 分流隧道开关以及断线开关。还显示实时连接状态、隧道 IP 和 MSS/PMTU 值。
**DDNS**
动态 DNS 配置页面(仅在使用 `CONFIG_DDNS_ENABLED=y` 构建时显示)。提供提供商选择(NoIP、DuckDNS、Selfhost.de、Dynu、Namecheap)、主机名/子域名、凭证或 token 字段(根据提供商显示/隐藏)、keep-alive 间隔(小时),以及用于立即推送 DNS 的“触发更新”按钮。显示实时状态(启用/禁用、提供商、最后更新时间戳、最后报告的 WAN IP)。
### 密码保护
可选的密码用于保护除状态仪表板外的所有页面。可通过 Web 界面或 `set_router_password` 设置。身份验证使用带有 16 字节随机盐值的 SHA-256。会话基于 cookie,具有 30 分钟的空闲超时。清除密码将开放所有页面且无需身份验证。
### 配置备份 / 恢复
**配置** 页面可将整个 NVS 配置导出为 JSON 文件,并可将其重新导入。
**导出 —— 根据是否输入密码短语分为两种模式:**
| 导出类型 | WiFi 密码 | WireGuard 私钥 + PSK | PPPoE 密码 |
|-------------|----------------|-----------------------------|----------------|
| 明文(无密码短语) | 包含 | **省略** | **省略** |
| 加密(有密码短语) | 包含 | 包含 | 包含 |
加密导出使用 XChaCha20-Poly1305 AEAD,密钥通过 PBKDF2-HMAC-SHA256(10,000 次迭代,16 字节随机盐值)从密码短语中派生出 32 字节密钥。密文被封装在 JSON 信封 `{"enc":1,"s":"…","n":"…","c":"…"}` 中,因此加密和明文文件共享相同的 `.json` 扩展名,且导入处理程序会自动检测格式。
**导入:** 如果文件已加密,请在选择文件之前在 *Import* 密码短语字段中输入密码短语。如果密码短语错误,会在修改任何 NVS 密钥之前被认证标签拒绝。
这两个 endpoint(`/api/config-export`、`/api/config-import`)在启用密码保护时都需要处于活动会话中,并受 CSRF Origin 检查的保护。
## WiFi 和网络
### 上行链路 (Ethernet + PPPoE)
以太网接口连接到 DSL 或有线调制解调器。PPPoE 在以太网链路之上进行协商。通过 Web 界面或 CLI 配置凭证:
```
set_pppoe -u -p # ISP credentials
set_pppoe -a <0|1|2> # Auth: 0=auto, 1=PAP, 2=CHAP
set_pppoe -s # Service name (optional)
set_pppoe -v # 802.1Q VLAN tag (0=off)
set_pppoe -j <0|1> # Baby-jumbo frames (MSS 1460 vs 1452)
set_pppoe -e <0|1> # Enable / disable PPPoE
```
### AP (WiFi 客户端)
```
set_ap # Configure AP (empty password = open)
set_ap_ip # Change AP subnet (e.g. 192.168.4.1)
set_ap_dns # Custom DNS for clients (empty = upstream)
set_ap_auth # Auth mode (requires restart)
set_ap_hidden # Hide SSID (requires restart)
set_ap_channel <0-N> # 0 = auto; max N depends on country (requires restart)
set_ap_nat # Enable / disable NAT (requires restart)
set_wifi_country # WiFi country code (2-char ISO 3166, e.g. US, DE; 01 = world-safe)
ap # Enable or disable AP immediately
```
### DHCP 预留
通过 MAC 地址为设备预留固定 IP。预留的 IP 绝不会分配给其他设备。
```
dhcp_reserve add [-n ] # Reserve IP for device
dhcp_reserve del # Remove reservation
dhcp_reserve block [-n ] # Block device from getting any IP
```
### 端口转发
```
portmap add TCP # Add TCP mapping
portmap add UDP # Add UDP mapping
portmap del TCP # Delete TCP mapping
portmap del UDP # Delete UDP mapping
```
DHCP 预留中的设备名称可用于代替 IP 地址。
### WireGuard VPN
一个保护所有 AP 客户端流量的 WireGuard 客户端隧道。支持两种路由模式:
| 模式 | 行为 |
|------|-----------|
| **全路由** | 所有 AP 客户端流量均通过隧道发送。WireGuard netif 成为默认路由。 |
| **分流隧道** | 只有前往配置的 VPN 子网的流量通过隧道发送;其他所有流量直接发往 WAN。 |
可以启用 **断线开关**,以便在 VPN 已启用但尚未连接时阻止所有非本地 AP 流量,防止在重新连接期间发生互联网泄漏。端口转发规则可以标记为绑定 VPN,使得它们仅在隧道连通时激活。
MTU 和 MSS 会自动调整以补偿 WireGuard 开销(60 字节:20 IP + 8 UDP + 16 WireGuard header + 16 authentication tag)。
### 动态 DNS (DDNS)
当上行链路建立或 WAN IP 发生变化时,自动向动态 DNS 提供商注册您的 WAN(PPPoE)IP 地址。所有连接均使用 HTTPS。
支持的提供商:
| 提供商 | 设置 |
|------|------|
| **NoIP** | 用户名、密码、完整的 FQDN |
| **DuckDNS** | 子域名、认证 token |
| **Selfhost.de** | 用户名、密码(DynAccount 凭证 —— 无需主机名) |
| **Dynu** | 用户名、密码(DynAccount 凭证 —— 无需主机名) |
| **Namecheap** | API key 或密码、完整主机名 |
当启用 DDNS 时,路由器会自动更新 DNS 记录:
- 每次连接 PPPoE 时 **立即更新**
- 在配置的 keep-alive 间隔(默认为 24 小时)**定期更新** —— 无论 IP 是否更改都无条件重新注册,满足 NoIP 的 30 天 keepalive 要求
可通过 Web 界面(**DDNS** 页面)或 CLI 访问配置:
```
# 启用 DDNS
ddns enable 1
# 选择 provider (0=NoIP, 1=DuckDNS, 2=Selfhost.de, 3=Dynu, 4=Namecheap)
ddns provider 1
# NoIP:设置 hostname、username 和 password
ddns hostname myhost.no-ip.org
ddns token myusername
ddns password mypassword
# DuckDNS:设置 subdomain 和 token
ddns token 12345-abcde-token
# Selfhost.de:设置 username 和 password(DynAccount credentials)
ddns token myusername
ddns password mypassword
# Dynu:设置 username 和 password(DynAccount credentials)
ddns token myusername
ddns password mypassword
# Namecheap:设置 hostname 和 API key 或 password
ddns hostname example.com
ddns token my-api-key-or-password
ddns poll 24
# 触发立即更新
ddns update
# 显示当前 DDNS 状态
ddns status
```
Home Assistant 传感器会自动发布(状态、提供商、主机名、最后更新时间戳)。
### 其他网络设置
```
set_sta_static # Static Ethernet WAN IP (PPPoE disabled only)
set_sta_static dhcp # Revert WAN to DHCP (requires restart)
set_ap_mac # Override AP MAC
set_hostname # DHCP client hostname (max 32 chars)
set_ttl <0-255> # TTL override (0 = disabled)
set_tx_power <2-20|0> # WiFi TX power in dBm (0 = max/default)
set_wifi_country # WiFi country code (e.g. US, DE, JP; 01 = world-safe)
```
### 防火墙
无状态防火墙根据四个有序 ACL 列表之一来评估数据包。首条匹配规则生效;默认情况下允许未匹配的数据包。
**ACL 列表:**
| 列表 | 方向 |
|------|-----------|
| `to_esp` | 互联网 -> 路由器(上行链路入站) |
| `from_esp` | 路由器 -> 互联网(上行链路出站) |
| `to_ap` | WiFi 客户端 -> 路由器 |
| `from_ap` | 路由器 -> WiFi 客户端 |
#### 规则语法 (CLI)
```
acl
- del
- clear` | 清除列表中的所有规则 |
| `acl
- clear_stats` | 重置列表的命中计数器 |
列表:`to_esp`、`from_esp`、`to_ap`、`from_ap` —— 协议:`IP`、`TCP`、`UDP`、`ICMP` —— 操作:`allow`、`deny`;当启用 `CONFIG_PCAP_CAPTURE` 时还支持 `allow_monitor`、`deny_monitor`
### WireGuard VPN
| 命令 | 描述 |
|---------|-------------|
| `show vpn` | VPN 状态和完整配置 |
| `set_vpn
标签:ESP32, UML, WireGuard, 内核驱动, 客户端加密, 物联网, 网络协议, 网络通信, 软路由, 防火墙