saprayworld/pigate
GitHub: saprayworld/pigate
一款面向 Raspberry Pi 5 的防火墙/网关管理系统,通过 Web UI 提供防火墙、路由、DHCP、DNS、QoS 等网络管理功能的可视化配置。
Stars: 0 | Forks: 0
# PiGate
**PiGate**(Raspberry Pi 防火墙/网关控制器)是一个高性能的防火墙和网关管理系统,旨在 Raspberry Pi 5(或兼容的 Raspberry Pi OS 发行版)上运行。它被设计用作家庭网络或小型办公室的网关和防火墙, featuring an easy-to-use administration interface via a Web UI (React Single-Page Application) and a backend developed in Go (Golang) for high execution speed and stability.
该系统侧重于以下关键领域:
- **高性能与内核级安全:**通过 Netlink Sockets 直接与 Linux Kernel 通信以管理防火墙(`nftables`)、路由和网络接口。它利用 D-Bus 控制各种服务,而不是执行 shell 命令,从而彻底防止了 Command Injection 漏洞。
- **供应链安全:**通过利用 Go Standard Library 和纯 Go 编写的 SQLite 驱动(`modernc.org/sqlite`)来最小化外部依赖。这使得系统可以编译成一个安全且易于部署的单二进制文件。
- **SD 卡保护:**采用内存环形缓冲区以及 `/run/` 或 `/tmp/` 目录来存储大型日志文件,从而延长 Raspberry Pi MicroSD 卡的使用寿命。
- **权限分离:**在非特权用户账户(`pigate`)下运行服务,并使用 Linux Capabilities(`cap_net_admin, cap_net_raw`)提升网络管理权限,从而防止操作系统被接管(OS Takeover)。
## 免责声明警告
本项目主要利用 AI 辅助开发,并结合了项目所有者的基础编程知识和经验(主要在 Node.js 方面)。作者并不专精于网络安全或 Go 编程语言。
因此,无法保证网络安全的完整性。该软件应严格仅用于个人和非关键目的,例如在 homelabs、测试、研究、教育或位于 Network Address Translation (NAT) 路由器后方的本地系统中。
如果在生产环境中部署,项目所有者对产生的任何损害或损失不承担任何责任。用户可在自行判断并承担风险的前提下,自由使用、修改和分发本软件。
## 目录结构
项目根级别和后端目录的核心结构组织如下:
```
pigate/
├── backend/ # Go Backend API Server & Kernel Integration
│ ├── cmd/
│ │ └── pigate/
│ │ └── main.go # Main entrypoint for system boot and configuration
│ ├── internal/
│ │ ├── api/ # API Interface (Frontend Gateway) & Middleware
│ │ │ ├── handlers.go # HTTP API handlers for request processing
│ │ │ ├── router.go # Endpoint routing registration
│ │ │ ├── middleware.go # CORS, Authentication, and Rate limiting middlewares
│ │ │ └── embed.go # Embeds the React SPA (dist/) using go:embed
│ │ ├── db/ # SQLite Database Management Layer
│ │ │ ├── connection.go # SQLite connection configuration & database migrations
│ │ │ └── repository.go # CRUD operations for system configurations
│ │ ├── kernel/ # Linux Operating System Interaction Layer (Low-level OS)
│ │ │ ├── interfaces.go # Unified interface definitions for OS control
│ │ │ ├── real_network.go # IP and network interface management using Netlink
│ │ │ ├── real_routing.go # Routing table management using Netlink
│ │ │ ├── real_firewall.go # nftables management via google/nftables (Netlink)
│ │ │ ├── real_qos.go # Traffic Control (tc/HTB/IFB) queuing using Netlink
│ │ │ ├── real_hostname.go # System hostname control via systemd-hostnamed (D-Bus)
│ │ │ ├── real_timedate.go # Timezone/NTP configuration via systemd-timedated (D-Bus)
│ │ │ ├── dhcp_server.go # DHCP server: dnsmasq config generation, validation, and D-Bus lease watcher
│ │ │ ├── dns_server.go # Local DNS zones (FQDN) via dnsmasq config generation
│ │ │ ├── dhcpcd.go # DHCP client (dhcpcd@) lifecycle control via systemd D-Bus
│ │ │ ├── wpa.go # Wi-Fi management via unix control socket wpa_supplicant
│ │ │ ├── dns.go # DNS configuration and systemd-resolved control via D-Bus
│ │ │ └── mock.go # Memory-resident mock implementation for local testing
│ │ ├── service/ # System Coordination & Business Logic Layer
│ │ │ ├── interface.go # Network interface status update logic
│ │ │ ├── routing.go # Routing logic and metric coordination
│ │ │ ├── netlink_monitor.go # Background service monitoring Kernel events for state reconciliation
│ │ │ ├── firewall.go # Firewall security policy management logic
│ │ │ ├── dhcp_server.go # DHCP server coordination (configs, reservations, live leases)
│ │ │ ├── dns_server.go # Local DNS zone/record coordination
│ │ │ ├── dns.go # System DNS (systemd-resolved) coordination
│ │ │ ├── dhcpcd.go # DHCP client (WAN-side) coordination
│ │ │ ├── qos.go # QoS bandwidth rule coordination
│ │ │ ├── hostname.go # System hostname coordination
│ │ │ ├── timesync.go # Timezone / NTP / manual time coordination
│ │ │ ├── user.go # Multi-user account and role management
│ │ │ └── backup.go # Typed configuration export/import (backup & restore)
│ │ ├── model/
│ │ │ └── types.go # Data structure structs and validation tags
│ │ └── logs/
│ │ └── ringbuffer.go # In-memory ring buffer for temporary RAM-based log storage
│ ├── go.mod # Go backend module dependencies
│ └── go.sum # Cryptographic checksum hashes for Go dependencies
├── frontend/ # React 19 Frontend SPA (Vite + Tailwind CSS + shadcn/ui)
├── docs/ # Design documentation, system requirements, and development guides
├── build.sh # Compilation script to bundle Frontend and Backend into a Single Binary
├── install.sh # Installation script for automated Linux host deployment
├── note.md # Installation, build notes, and test commands
├── readme-ref.md # Reference template for README.md
└── LICENSE # Software license agreement
```
## 功能状态
下表总结了 PiGate 系统中各项功能的开发状态:
| 功能 | 前端 | 后端 | 状态 / 备注 |
|---|---|---|---|
| **仪表板** | 已完成 | 已完成 | 系统状态是真实的:CPU(使用率/型号/核心数/频率)、内存、温度、存储、正常运行时间/OS/kernel/主板,以及 WAN 带宽历史记录均从 `/proc`、`/sys`、`statfs` 和 netlink 计数器读取(无 shell exec)。在缺少 sysfs 节点的主机(例如 WSL/x86)上,温度/CPU 频率/主板型号会降级为 `available:false` 或被省略。流量历史记录是一个 RAM 环形缓冲区(24 小时,按 5 分钟划分,重启后重置)。最近的日志现在是真实的 forward-chain PASS/DROP 事件,通过 NFLOG 从内核馈送(参见 **转发流量日志**)。 |
| **接口** | 已完成 | 已完成 | IP 管理、Netlink 接口处理、`wpa_supplicant` Wi-Fi 扫描和状态管理、随机 MAC 地址、用于多 WAN 故障转移的按接口路由度量,以及通过 `dhcpcd@`(systemd D-Bus)实现的 WAN 端 DHCP 客户端。还支持直接通过 UI 利用 Netlink 创建/删除 **802.1Q VLAN** 子接口(`.`);VLAN 持久化存储在数据库中,并在每次启动时自动重新创建(并通过导入/导出进行恢复)。具有已保存配置但没有活动内核链接(父级消失的 VLAN、已拔出的 USB NIC)的接口将作为 **离线** 行显示在“显示离线”开关后,以便可以从 UI 中删除其配置(配置永远不会被自动删除)。 |
| **路由** | 已完成 | 已完成 | 静态路由的 CRUD 操作、Netlink 事件监控以及自动路由自愈。 |
| **DNS 系统** | 已完成 | 已完成 | 通过 D-Bus 进行 `systemd-resolved` 的按链接 DNS 配置。 |
| **防火墙系统** | 已完成 | 已完成 | 通过 Netlink 管理 `nftables`、配置 forward chain 策略、WAN Network Address Translation (Masquerade) 以及 Docker 兼容性。 |
| **端口转发 (DNAT)** | 已完成 | 已完成 | FortiGate-VIP 样式的端口转发:`pigate_nat` 中的 prerouting DNAT chain(由 `fib daddr type local` 保护)将外部 `interface:port` 重写为内部 LAN `IP:port`,并带有一条自动生成的 forward-accept 规则(放置在用户策略规则之前),因此被 DNAT 的数据包永远不会被 filter chain 丢弃。支持单端口转换和保留端口范围(1:1 范围转换不在范围内);conntrack 会对返回路径执行 un-DNAT。包含在备份/还原中。v1 不在范围内的功能:hairpin/NAT-loopback、IPv6、源限制 DNAT。 |
| **DHCP 服务器** | 已完成 | 已完成 | `dnsmasq` 配置生成(`/etc/dnsmasq.d/pigate-dhcp.conf`)带有语法验证(`dnsmasq --test`),通过 systemd D-Bus 重启服务,支持按接口的地址池和预留,以及通过 dnsmasq D-Bus 信号实现的实时租约监控器。 |
| **DNS 服务器** | 已完成 | 已完成 | 通过 `dnsmasq` 配置生成(`/etc/dnsmasq.d/pigate-dns.conf`)实现本地 DNS 区域/FQDN 记录,支持权威区域,以及独立于 DHCP 服务器的监听接口选择。 |
| **QoS 限制** | 已完成 | 已完成 | 通过 tc Netlink 进行 HTB 和 IFB 流量整形,支持源/目标 IP 地址范围(CIDR)。 |
| **系统主机名** | 已完成 | 已完成 | 通过 `systemd-hostnamed` D-Bus 进行主机名管理(静态 + 瞬态),在启动时应用,并带有依赖的 DHCP 客户端重启功能。 |
| **系统时间** | 已完成 | 已完成 | 通过 `systemd-timedated` D-Bus 进行时区、NTP 开关/服务器和手动时间设置;时区/NTP 配置在启动时重新应用。 |
| **设置(总体)** | 已完成 | 部分完成 | 密码更改、时间、主机名和导出/导入功能已完全可用。系统服务列表/重启面板目前仍是模拟数据。 |
| **导入/导出** | 已完成 | 已完成 | 类型化的 JSON 备份(schema v2),带有 SHA-256 完整性校验、可选的用户账户以及可选的密码短语加密(AES-256-GCM + Argon2id);导入使用 验证 → 导入前快照 → 单事务擦除与还原 → 内核重新应用(启动顺序)流程。跨机器安全(原始路由,按名称匹配接口),仅限 `super_admin` 使用,带有执行者锁定防护。接受旧版 v1 文件。 |
| **用户系统** | 已完成 | 已完成 | 多用户管理(创建/编辑/删除/启用-禁用),具有 `super_admin` / `admin_readonly` 角色,基于每个请求的数据库验证会话,基于角色的授权中间件,基于会话的身份验证,登录速率限制,以及首次登录强制更改密码。 |
| **电源控制(关机/重启)** | 已完成 | 已完成 | 通过 `systemd-logind`(`org.freedesktop.login1`)D-Bus 执行真实的系统重启/关机 — 无需 shell exec。仅限 `super_admin` 使用,由 Polkit 规则授权(参见 `install.sh`);命令会延迟约 1 秒,以便在 logind 停止 `pigate.service` 之前刷新 HTTP 200,并且关机是优雅的(SQLite 正常关闭)。在 `-mock=true` 下是安全的(无操作模拟管理器)。 |
| **事件日志** | 已完成 | 已完成 | 中央审计/事件日志(`EventLogService`):安全事件(登录成功/失败、密码更改、用户 CRUD)、网络/防火墙/路由/DHCP/DNS 更改、DHCP 租约添加/移除、配置导出/导入以及重启/关机/启动。通过一个对 SD 卡友好的异步批量写入器在重启后持久化存储于 SQLite 中(RAM 队列,每 10 个事件 / 10 秒刷新一次,表上限 10,000 行,在电源操作前进行同步刷新)。查看器 UI 位于日志和报告 › 系统事件,带有类别/严重性/文本过滤器和分页功能;清除日志仅限 `super_admin` 操作,并且始终会保留一行 `logs_cleared` 审计记录。 |
| **转发流量日志** | 已完成 | 已完成 | 针对通过防火墙转发的数据包(LAN↔WAN forward chain)的实时 PASS/DROP 事件。Forward-chain 日志语句将日志记录到 NFLOG 组(组 100),而不是 printk/dmesg;一个纯 Go 编写的 NFLOG 监听器(`github.com/florianl/go-nflog`,无 CGO)将每个事件的 IPv4/IPv6 + TCP/UDP 标头解析为 `FirewallLog` 并将其推送到 RAM 环形缓冲区(容量 500)。特意 **不** 进行持久化存储(考虑到数据包速率 + SD 卡磨损);监听器回调是非阻塞的,并在突发溢出时丢弃数据。查看器 UI 位于日志和报告 › 转发流量(判定过滤器,文本搜索,暂停/恢复 5 秒轮询,清除)。Mock 模式会合成事件(无 netlink socket)。根据设计,已建立的连接会被接受而没有每个数据包的日志,因此该视图是最近的样本,而不是完整的记录。 |
| **HTTPS / TLS** | 已完成 | 已完成 | 真实设备默认使用在首次启动时生成的一次性自签名证书(ECDSA P-256,stdlib `crypto/*`,无外部 CA/ACME)通过 **端口 443 上的 HTTPS** 提供管理 UI。密钥以 `0600` 权限存储在磁盘上的 `/tls/` 目录下(绝不存入数据库/备份中)。端口 2479/80 上的 HTTP 会发出 `308` 重定向至 HTTPS;如果 TLS 无法启动(证书不可写,端口 443 不可用),服务器将回退为提供完整的 HTTP 服务,以免管理员被锁定,并伴随明显的警告 + 事件日志。Session cookie 的 `Secure` 标志是根据连接协议按请求设置的。证书有效期使用固定的时间窗口(非派生自系统时钟),因此没有 RTC 电池的 Pi 在 NTP 同步之前仍能获得可用的证书。开发/mock 模式(无 `-https-port`)为仅限 HTTP 模式且保持不变。 |
## 如何构建
可以使用提供的 `build.sh` 脚本将项目构建为一个独立的单二进制文件,或者通过执行以下单独的编译步骤手动构建。
### 通过脚本快速构建(推荐)
```
bash build.sh
```
### 手动编译步骤
1. **构建前端界面:**
cd frontend
yarn install
yarn build
cd ..
2. **将生产构建复制到后端嵌入位置:**
rm -rf backend/internal/api/dist
mkdir -p backend/internal/api/dist
cp -r frontend/dist/* backend/internal/api/dist/
echo "# Placeholder" > backend/internal/api/dist/.gitkeep
3. **构建 Go 后端:**
cd backend
go build -o pigate-backend ./cmd/pigate
cd ..
mv ./backend/pigate-backend pigate
4. **授予可执行文件 Linux Capabilities(无需 Root 权限运行必需):**
sudo setcap cap_net_admin,cap_net_raw+ep ./pigate
## 安装说明
项目包含一个安装脚本,用于自动化设置用户、组、目录权限、Polkit 配置以及 Systemd 服务,以确保应用程序安全执行。
### 自动化安装
成功构建 `pigate` 可执行文件后,运行以下安装命令:
```
sudo bash install.sh
```
该脚本将执行以下操作:
1. 创建一个名为 `pigate` 的系统用户,并将其追加到 `netdev` 系统组中。
2. 为 `/etc/wpa_supplicant`、`/etc/dnsmasq.d`、`/etc/systemd/resolved.conf.d` 以及 `systemd-timesyncd` 插入目录配置 Access Control Lists (ACLs)(如果缺少 `dnsmasq` 则会进行安装)。
3. 创建一个 systemd 模板服务 `dhcpcd@.service`,以便 WAN 端 DHCP 客户端作为其自身 root 所有的单元运行,PiGate 通过 systemd D-Bus 按接口启动/停止该单元(无需 sudo)。
4. 创建 Pol 规则,授权 `pigate` 用户通过 D-Bus 控制 `wpa_supplicant`、`systemd-resolved`、`dnsmasq`、`systemd-timesyncd` 和 `dhcpcd@*` 服务。
5. 将二进制文件部署到 `/usr/local/bin/pigate` 并分配所需的 Linux capabilities。
6. 配置、注册并启动 Systemd 服务 `pigate.service`。
### 安装后的服务管理
- **启动服务:** `sudo systemctl start pigate`
- **停止服务:** `sudo systemctl stop pigate`
- **检查服务状态:** `sudo systemctl status pigate`
- **查看日志输出 (Journal):** `sudo journalctl -u pigate -f`
### 配置文件
无需编辑 systemd 单元即可更改运行时设置。`install.sh` 会在首次安装时创建 `/var/lib/pigate/pigate.conf`(一个简单的 `key=value` 文件,`#` 用于注释),并附带生产环境的默认值。键名是去掉前导 `-` 的 CLI flag 名称。
优先级顺序为 **内置默认值 → 配置文件 → CLI flag** — 在命令行显式传递的 flag 始终优先于文件配置。由于已安装的 `ExecStart` 仍会传递 `-mock=false -db=… -https-port=443` 作为安全保障,因此在该单元中移除这三个键之前,在文件中编辑它们不会生效;其他键(例如 `docker-compat`)将直接从文件中生效。可以使用 `-config=/path/to/file` 指定不同的文件(如果明确指定的文件不存在,则会导致硬错误)。
## 环境要求
为确保正常运作,宿主操作系统必须满足以下硬件、软件和依赖项要求:
### 硬件与操作系统
- **Raspberry Pi 5** 单板计算机(或运行基于 Debian 的 Linux 发行版的类似 x86/ARM 迷你 PC,例如 Raspberry Pi OS)。
- 拥有提升的管理员权限(`sudo` 访问权限)以进行初始安装过程。
### 软件依赖
### 安全配置
- 为了在个人工作站上进行开发和测试时的安全,强烈建议在 **Mock 模式** 下运行系统。这可以防止应用程序修改宿主计算机的实际路由表:
# 在端口 8081 上启动 mock 环境
./pigate -port=8081 -db=pigate.db -mock=true
# 以只读模式启动 mock 环境
./pigate -port=8081 -db=pigate.db -mock=true -disable-edit=true
*默认登录凭据:用户名 `pigate` | 密码 `首次运行时打印到控制台`*
标签:EVTX分析, 日志审计