https://github.com/narwhal-cloud/rfw
Rust Firewall
https://github.com/narwhal-cloud/rfw
aya ebpf firewall
Last synced: 26 days ago
JSON representation
Rust Firewall
- Host: GitHub
- URL: https://github.com/narwhal-cloud/rfw
- Owner: narwhal-cloud
- License: apache-2.0
- Created: 2025-10-30T17:00:20.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2026-05-24T12:01:35.000Z (29 days ago)
- Last Synced: 2026-05-24T14:05:29.632Z (29 days ago)
- Topics: aya, ebpf, firewall
- Language: Rust
- Homepage:
- Size: 188 KB
- Stars: 82
- Watchers: 0
- Forks: 21
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# rfw
Rust Firewall - 基于 eBPF/XDP 的高性能防火墙,支持 GeoIP 过滤和协议深度检测
[](https://github.com/narwhal-cloud/rfw/actions/workflows/build.yml)
## 目录
- [功能特性](#功能特性)
- [快速开始](#快速开始)
- [使用说明](#使用说明)
- [技术实现](#技术实现)
- [编译和安装](#编译和安装)
- [License](#license)
## 功能特性
### 灵活的 GeoIP 过滤
- **多国家支持** - 支持指定任意国家代码(CN、RU、KP、US 等)
- **灵活的过滤模式**:
- **黑名单模式** - 阻止指定国家的流量
- **白名单模式** - 只允许指定国家的流量
- **无 GeoIP 模式** - 直接基于协议规则过滤所有流量
- **自动下载 GeoIP 数据** - 运行时自动下载指定国家的最新 IP 段
### 支持的过滤规则
1. **屏蔽 Email** - 阻止邮件(SMTP: 25/587/465/2525)相关端口流量
2. **屏蔽 HTTP 入站** - 使用协议深度检测识别 HTTP 流量,配合 GeoIP 或全局过滤
3. **屏蔽 SOCKS5 入站** - 使用协议深度检测识别 SOCKS5 流量,配合 GeoIP 或全局过滤
4. **屏蔽全加密流量入站** - 使用 FET 算法识别 Shadowsocks、V2Ray 等加密代理
5. **屏蔽 WireGuard VPN 入站** - 精准识别 WireGuard VPN 协议
6. **屏蔽 QUIC 入站** - 精准识别 QUIC 协议(HTTP/3)
7. **屏蔽所有入站流量** - 阻止所有入站连接(配合 GeoIP 或全局)
8. **端口访问日志** - 记录所有端口被哪些 IP 访问,以及是否被阻断
### 协议深度检测 (DPI)
与传统的基于端口号的防火墙不同,rfw 使用**协议深度检测**(Deep Packet Inspection, DPI):
- **HTTP 检测**:识别 HTTP 请求方法(GET, POST 等)
- **SOCKS5 检测**:识别 SOCKS5 握手协议特征
- **全加密流量检测**:使用统计算法识别 Shadowsocks、V2Ray 等加密代理
- **WireGuard 检测**:精准识别 WireGuard VPN 协议
- **QUIC 检测**:识别 QUIC v1/v2 和 Google QUIC 协议(HTTP/3)
- **不依赖端口号**:即使服务运行在非标准端口也能识别
### 性能特性
- **XDP (eXpress Data Path)**:在网卡驱动层处理数据包,极低延迟
- **零拷贝**:直接在内核中处理,无需复制数据到用户空间
- **高吞吐**:可处理 10Gbps+ 的网络流量
### 协议支持
- **仅支持 IPv4**:目前不支持 IPv6 流量
- **GeoIP 自动更新**:每次运行时自动下载指定国家的最新 IP 数据
- **多数据源**:使用 [lyc8503/sing-box-rules](https://github.com/lyc8503/sing-box-rules) 提供的 GeoIP 数据
## 快速开始
### 编译
```bash
# Linux 环境
cargo build --release
# macOS 交叉编译到 Linux (x86_64)
CC=x86_64-linux-musl-gcc cargo build --package rfw --release \
--target=x86_64-unknown-linux-musl \
--config=target.x86_64-unknown-linux-musl.linker=\"x86_64-linux-musl-gcc\"
# macOS 交叉编译到 Linux (aarch64)
CC=aarch64-linux-musl-gcc cargo build --package rfw --release \
--target=aarch64-unknown-linux-musl \
--config=target.aarch64-unknown-linux-musl.linker=\"aarch64-linux-musl-gcc\"
```
### 基本使用
```bash
# 查看帮助
sudo ./target/release/rfw --help
# 阻止指定国家的 HTTP 和 SOCKS5 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU,KP \
--block-http --block-socks5
# 阻止来自中国的所有流量(快捷方式)
sudo ./target/release/rfw --iface eth0 \
--block-all-from CN
# 白名单模式:只允许来自美国、日本、韩国的流量
sudo ./target/release/rfw --iface eth0 \
--allow-only-countries US,JP,KR \
--block-http --block-socks5
# 不限国家,阻止所有 HTTP 流量
sudo ./target/release/rfw --iface eth0 \
--block-http
# 启用详细日志
sudo RUST_LOG=info ./target/release/rfw --iface eth0 --countries CN --block-wireguard --block-quic
```
## 使用说明
### GeoIP 配置
#### 1. 黑名单模式(阻止指定国家)
```bash
# 阻止来自中国、俄罗斯、朝鲜的 HTTP 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU,KP \
--block-http
# 阻止来自指定国家的所有流量
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU \
--block-all
```
#### 2. 白名单模式(只允许指定国家)
```bash
# 只允许来自美国、日本、韩国的访问
sudo ./target/release/rfw --iface eth0 \
--allow-only-countries US,JP,KR \
--block-http --block-socks5
```
#### 3. 快捷方式:阻止指定国家的所有流量
```bash
# 等价于 --countries CN --block-all
sudo ./target/release/rfw --iface eth0 \
--block-all-from CN,RU,KP
```
#### 4. 不使用 GeoIP(全局协议过滤)
```bash
# 阻止所有来源的 HTTP 和 SOCKS5 流量
sudo ./target/release/rfw --iface eth0 \
--block-http --block-socks5
```
### 协议规则详解
#### 1. 屏蔽发送 Email
```bash
sudo ./target/release/rfw --iface eth0 --block-email
```
此规则会**仅阻止发送邮件**的出站流量,**允许接收邮件**:
**阻止的 SMTP 端口(发送邮件):**
- 端口 25 - 标准 SMTP(未加密)
- 端口 587 - SMTP Submission(STARTTLS)
- 端口 465 - SMTPS(SSL/TLS 加密)
- 端口 2525 - 备用 SMTP 端口
**允许的端口(接收邮件):**
- ✅ 端口 110 - POP3(未加密)
- ✅ 端口 995 - POP3S(SSL/TLS 加密)
- ✅ 端口 143 - IMAP(未加密)
- ✅ 端口 993 - IMAPS(SSL/TLS 加密)
**效果说明:**
- ❌ 阻止使用邮件客户端(Outlook, Thunderbird, Apple Mail 等)**发送**邮件
- ❌ 阻止命令行邮件工具(sendmail, mutt 等)发送邮件
- ✅ **允许**使用邮件客户端**接收**邮件(POP3/IMAP)
- ✅ 不影响基于浏览器的网页邮箱(如 Gmail 网页版,使用 HTTP/HTTPS)
**使用场景:**
- 防止服务器被用作垃圾邮件发送源
- 防止恶意软件发送钓鱼邮件
- 允许用户正常接收邮件,但禁止发送
#### 2. 屏蔽 HTTP 入站
```bash
# 阻止指定国家的 HTTP 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU \
--block-http
# 阻止所有来源的 HTTP 流量
sudo ./target/release/rfw --iface eth0 \
--block-http
```
阻止 HTTP 入站连接(仅明文 HTTP,不包括 HTTPS)
#### 3. 屏蔽 SOCKS5 入站
```bash
# 阻止指定国家的 SOCKS5 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN \
--block-socks5
# 阻止所有来源的 SOCKS5 流量
sudo ./target/release/rfw --iface eth0 \
--block-socks5
```
阻止 SOCKS5 代理入站连接
#### 4. 屏蔽全加密流量入站
```bash
# 严格模式:阻止指定国家的全加密流量
sudo ./target/release/rfw --iface eth0 \
--countries CN \
--block-fet-strict
# 宽松模式
sudo ./target/release/rfw --iface eth0 \
--countries CN \
--block-fet-loose
```
阻止全加密代理流量(Shadowsocks、V2Ray 等)
**特点:**
- 使用统计算法识别加密代理特征
- 自动豁免合法的 TLS/HTTPS 流量
- 基于 GFW 研究论文实现
**注意:**
- 检测基于统计特征,可能有极少的误报
#### 5. 屏蔽 WireGuard VPN 入站
```bash
# 阻止指定国家的 WireGuard 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN \
--block-wireguard
# 阻止所有来源的 WireGuard 流量
sudo ./target/release/rfw --iface eth0 \
--block-wireguard
```
阻止 WireGuard VPN 流量
**特点:**
- 基于 WireGuard 协议特征精准识别
- 误报率极低,性能开销小
- 不会影响其他 UDP 应用
#### 6. 屏蔽 QUIC 入站
```bash
# 阻止指定国家的 QUIC 流量
sudo ./target/release/rfw --iface eth0 \
--countries CN \
--block-quic
# 阻止所有来源的 QUIC 流量
sudo ./target/release/rfw --iface eth0 \
--block-quic
```
阻止 QUIC 协议流量(HTTP/3)
**特点:**
- 精准识别 QUIC v1(RFC 9000)和 QUIC v2(RFC 9369)
- 支持检测 Google QUIC 协议
- 识别长头部和短头部数据包
- 误报率极低,不影响其他 UDP 应用
**支持的 QUIC 版本:**
- QUIC v1(RFC 9000,版本号 0x00000001)
- QUIC v2(RFC 9369,版本号 0x6b3343cf)
- Google QUIC(Q0xx 系列)
- 版本协商包
**使用场景:**
- 阻止基于 HTTP/3 的服务被滥用
- 防止 QUIC 代理服务器被滥用
- 限制新一代加密传输协议的入站连接
#### 7. 屏蔽所有入站流量
```bash
# 阻止指定国家的所有流量
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU \
--block-all
# 快捷方式
sudo ./target/release/rfw --iface eth0 \
--block-all-from CN,RU
# 白名单模式:只允许指定国家
sudo ./target/release/rfw --iface eth0 \
--allow-only-countries US,JP,KR \
--block-all
# 阻止所有来源的流量(不使用 GeoIP)
sudo ./target/release/rfw --iface eth0 \
--block-all
```
阻止**所有**入站流量(不限协议、不限端口)
**特点:**
- 配合 GeoIP 时,仅基于 GeoIP 检测,性能开销最小
- 最彻底的屏蔽方式
- 优先级最高,在协议检测之前执行
**使用场景:**
- 服务器只面向特定地区用户(使用白名单模式)
- 需要彻底阻止来自特定国家的访问
**注意:**
- 如果启用此规则,无需启用其他协议检测规则
- 只影响入站流量,不影响出站流量
#### 8. 端口访问日志
端口访问日志功能可以记录所有端口被哪些 IP 访问,以及这些访问是被允许还是被阻断。
##### 启用日志记录
在启动防火墙时添加 `--log-port-access` 参数即可启用端口访问日志:
```bash
# 启动防火墙并启用端口访问日志
sudo ./target/release/rfw --iface eth0 \
--block-http --block-socks5 \
--log-port-access
# 配合 GeoIP 使用
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU \
--block-http --block-wireguard \
--log-port-access
```
##### 查看统计信息
在防火墙运行时,使用 `stats` 子命令查看访问统计:
```bash
# 查看所有端口访问记录
sudo ./target/release/rfw stats
# 按端口过滤
sudo ./target/release/rfw stats --port 80
# 按源 IP 过滤
sudo ./target/release/rfw stats --ip 1.2.3.4
# 只显示被阻断的访问
sudo ./target/release/rfw stats --blocked-only
# 只显示允许通过的访问
sudo ./target/release/rfw stats --allowed-only
# 按端口分组显示(汇总统计)
sudo ./target/release/rfw stats --group-by-port
# 组合使用过滤条件
sudo ./target/release/rfw stats --port 80 --blocked-only
```
##### 输出示例
**列表模式(默认):**
```
Source IP Proto Port Allowed Blocked Total
------------------------------------------------------------------------
1.2.3.4 TCP 80 0 156 156
5.6.7.8 TCP 8080 45 0 45
9.10.11.12 UDP 443 12 8 20
```
**分组模式(--group-by-port):**
```
Port 80/TCP
Source IP Allowed Blocked Total
--------------------------------------------------------
1.2.3.4 0 156 156
5.6.7.8 120 0 120
Port 8080/TCP
Source IP Allowed Blocked Total
--------------------------------------------------------
9.10.11.12 45 0 45
```
##### 技术实现
- **BPF 文件系统共享**: 使用 `/sys/fs/bpf` pinning 机制实现跨进程 eBPF map 共享
- **LRU 缓存**: 自动淘汰旧记录,最多存储 65536 条记录
- **实时更新**: 统计数据在内核中实时记录,无需重启防火墙
- **低开销**: 仅当启用 `--log-port-access` 时才记录,不影响未启用时的性能
- **高性能**: 所有统计在 eBPF 内核中完成,几乎无性能损耗
##### 注意事项
1. **需要 root 权限**: 访问 `/sys/fs/bpf` 需要 root 权限
2. **防火墙必须运行**: `stats` 命令依赖正在运行的防火墙进程(需启用 `--log-port-access`)
3. **BPF 文件系统**: 需要 `/sys/fs/bpf` 已挂载(大多数 Linux 系统默认已挂载)
4. **容量限制**: 最多存储 65536 条不同的访问记录(源IP + 目标端口 + 协议组合)
5. **自动清理**: 使用 LRU 策略,旧记录会被自动淘汰以腾出空间
6. **协议支持**: 记录 TCP 和 UDP 协议的访问
##### 使用场景
- **安全审计**: 了解服务器上哪些端口被访问,来源 IP 是哪些
- **攻击分析**: 查看哪些 IP 的访问被阻断,分析攻击模式
- **服务监控**: 监控特定端口的访问频率和来源分布
- **规则优化**: 根据访问统计优化防火墙规则
### 组合使用多个规则
```bash
# 同时启用所有规则(针对指定国家)
sudo ./target/release/rfw --iface eth0 \
--countries CN,RU,KP \
--block-email \
--block-http \
--block-socks5 \
--block-fet-strict \
--block-wireguard \
--block-quic
# 多国家分别配置(使用白名单)
sudo ./target/release/rfw --iface eth0 \
--allow-only-countries US,JP,KR,SG \
--block-http \
--block-socks5
# 不使用 GeoIP,全局协议检测
sudo ./target/release/rfw --iface eth0 \
--block-http \
--block-socks5 \
--block-wireguard \
--block-quic
# 组合使用:邮件 + 特定国家的代理协议
sudo ./target/release/rfw --iface eth0 \
--block-email \
--countries CN \
--block-http \
--block-socks5
# 最激进模式:阻止指定国家的所有流量
sudo ./target/release/rfw --iface eth0 \
--block-all-from CN,RU,KP
```
### 运行要求
1. **Linux 内核版本**: 需要支持 XDP 的内核(通常是 4.8+,推荐 5.x+)
2. **Root 权限**: 加载 eBPF 程序需要 root 权限
3. **网络接口**: 确保指定的网卡名称正确(使用 `ip link` 查看)
4. **协议支持**: 目前仅支持 IPv4,不支持 IPv6
### 日志
程序使用 `env_logger` 记录日志。可以通过设置 `RUST_LOG` 环境变量来控制日志级别:
```bash
# 显示详细日志
sudo RUST_LOG=info ./target/release/rfw --iface eth0 --block-email
# 显示调试日志
sudo RUST_LOG=debug ./target/release/rfw --iface eth0 --block-email
```
当数据包被阻止时,eBPF 程序会记录相关信息到内核日志中。
### 停止防火墙
按 `Ctrl+C` 即可停止防火墙程序。程序会自动卸载 eBPF 程序并清理资源。
## 技术实现
rfw 基于 **eBPF/XDP** 技术,使用 **Rust** 语言开发。
### 架构
- **rfw-ebpf**: 运行在内核的 eBPF 程序,负责数据包过滤
- **rfw**: 用户空间程序,负责加载配置和管理 eBPF 程序
- **rfw-common**: 共享的数据结构定义
### 工作原理
1. 在网卡驱动层拦截数据包(XDP)
2. 检查是否为 IPv4 数据包(**目前仅支持 IPv4**)
3. 根据启用的规则进行检测:
- **GeoIP 检测**:使用 LpmTrie 高效匹配源 IP 是否在指定国家列表中
- **白名单/黑名单模式**:支持阻止指定国家或只允许指定国家
- **协议检测**:识别 HTTP、SOCKS5、WireGuard、QUIC 等协议特征
- **端口检测**:识别 Email 发送端口
4. 返回判决:允许通过或丢弃
### GeoIP 数据管理
- **数据源**: [lyc8503/sing-box-rules](https://github.com/lyc8503/sing-box-rules)
- **存储方式**: 使用 LpmTrie (Longest Prefix Match Trie) 进行高效前缀匹配
- **容量**: 最多支持 65536 个 CIDR 前缀
- **性能**: O(1) 时间复杂度的 IP 查询
- **更新策略**: 每次程序启动时自动下载最新数据
### 性能优势
- 在内核驱动层处理,延迟极低
- 零拷贝,无需将数据传到用户空间
- 可处理 10Gbps+ 高速流量
## 编译和安装
### Prerequisites
1. stable rust toolchains: `rustup toolchain install stable`
2. nightly rust toolchains: `rustup toolchain install nightly --component rust-src`
3. (if cross-compiling) rustup target: `rustup target add ${ARCH}-unknown-linux-musl`
4. (if cross-compiling) LLVM: (e.g.) `brew install llvm` (on macOS)
5. (if cross-compiling) C toolchain: (e.g.) [`brew install filosottile/musl-cross/musl-cross`](https://github.com/FiloSottile/homebrew-musl-cross) (on macOS)
6. bpf-linker: `cargo install bpf-linker` (`--no-default-features` on macOS)
### 编译
#### Linux 环境
```bash
cargo build --release
```
#### macOS 交叉编译
交叉编译适用于 Intel 和 Apple Silicon Mac:
```bash
# x86_64
CC=x86_64-linux-musl-gcc cargo build --package rfw --release \
--target=x86_64-unknown-linux-musl \
--config=target.x86_64-unknown-linux-musl.linker=\"x86_64-linux-musl-gcc\"
# aarch64
CC=aarch64-linux-musl-gcc cargo build --package rfw --release \
--target=aarch64-unknown-linux-musl \
--config=target.aarch64-unknown-linux-musl.linker=\"aarch64-linux-musl-gcc\"
```
交叉编译后的程序位于 `target/${ARCH}-unknown-linux-musl/release/rfw`,可以复制到 Linux 服务器或虚拟机上运行。
### 运行
```bash
# 基本运行
sudo ./target/release/rfw --iface eth0
# 启用规则
sudo ./target/release/rfw --iface eth0 --block-email --block-cn-http
# 查看日志
sudo RUST_LOG=info ./target/release/rfw --iface eth0 --block-cn-fet-strict
```
## 参考资料
- [eBPF 文档](https://ebpf.io/)
- [XDP 教程](https://github.com/xdp-project/xdp-tutorial)
- [Aya 框架](https://aya-rs.dev/)
- [OpenGFW 项目](https://github.com/apernet/OpenGFW)
- [FET 论文](https://gfw.report/publications/usenixsecurity23/data/paper/paper.pdf)
## License
With the exception of eBPF code, rfw is distributed under the terms
of either the [MIT license] or the [Apache License] (version 2.0), at your
option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
### eBPF
All eBPF code is distributed under either the terms of the
[GNU General Public License, Version 2] or the [MIT license], at your
option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the GPL-2 license, shall be
dual licensed as above, without any additional terms or conditions.
[Apache license]: LICENSE-APACHE
[MIT license]: LICENSE-MIT
[GNU General Public License, Version 2]: LICENSE-GPL2