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分析, 日志审计