asciimoth/killswitch

GitHub: asciimoth/killswitch

基于 Linux eBPF 的故障封闭式网络出口过滤守护进程,用于 VPN 断线时阻断未授权流量以防止 IP 泄露。

Stars: 1 | Forks: 0

# killswitch `killswitch` 是一个 Linux eBPF 网络终结开关。系统守护进程会附加一个 egress 程序到选定的网络接口,维护基于接口的策略, 并且除非当前策略明确允许,否则将丢弃路由到这些接口的流量 (顺便说一下,它与 [pmark](https://github.com/asciimoth/p-mark) 配合得很好)。 该项目包括: - `killswitch`:系统守护进程,负责接口监控、eBPF 挂载、 策略评估、管理 API 以及可选的本地 SOCKS 代理。 - `killswitch-user`:桌面会话辅助工具,用于通知、托盘控制、 网络检查和强制门户处理。 - `killswitch-cli`:控制 killswitch 守护进程的命令行客户端。 ## 功能 - 故障封闭式 IPv4 和 IPv6 egress 过滤。 - 按类型、确切名称和正则表达式选择接口。 - 每个接口的有效策略。 - 针对 fwmark、端口、目标主机和主机+端口对的全局允许规则。 - 由接口、地址、Wi-Fi 和网关触发器激活的命名规则集。 - 用于应用程序集成的临时连接独占规则集。 - 用于交互式或受监督工作流的强制规则集激活。 - 可选的本地 SOCKS 代理,其 fwmark 会自动被允许。 - 基于 Unix socket 的管理 API,具有基于对端凭证的授权。 - 桌面通知、托盘集成以及网络登录页面处理。 ## 安装说明 ### Nix 从 flake 直接构建或运行: ``` nix build github:asciimoth/killswitch#killswitch nix profile add github:asciimoth/killswitch#killswitch ``` 你也可以使用系统服务: ``` imports = [ inputs.killswitch.nixosModules.killswitch ]; environment.systemPackages = [ inputs.killswitch.packages.${pkgs.system}.killswitch ]; services.killswitch = { enable = true; settings = { interface_types = [ "device" ]; interface_regexps = [ "^(en|wl|ww)" ]; allow_all = false; enable_v4 = true; enable_v6 = true; # allowed_ports = [ "udp/53" "tcp/53" ]; socks_proxy = { enabled = true; port = 1080; fwmark = "0xeb9f0001"; dns_server = "8.8.8.8"; protected = { usernames = [ "root" "myuser" ]; }; }; }; }; ``` ### 基于 Deb 和 rpm 的系统 软件包已发布到[我的 deb/rpm 仓库](https://repo.moth.contact): 通过脚本(或手动)为你的系统进行设置: ``` curl https://repo.moth.contact/setup.sh | bash ``` 然后使用你的系统软件包管理器进行安装: ``` sudo apt install killswitch # 或 sudo dnf install killswitch # 或 sudo yum install killswitch ``` ### GitHub Releases 发布归档和软件包工件发布在 [GitHub 发布页面](https://github.com/asciimoth/killswitch/releases)上。 ### Arch 已提供 [AUR](https://aur.archlinux.org/packages/killswitch-bin) ## 守护进程设置 默认情况下,守护进程会读取 `/etc/killswitch/killswitch.json`。配置是一个 单一的 JSON 对象;未知字段会被拒绝。 示例: ``` { "interface_types": ["device"], "interface_names": ["eth0", "wlan0"], "interface_regexps": ["^(en|wl|ww)"], "ignored_interface_types": ["bridge"], "ignored_interface_names": ["docker0"], "ignored_interface_regexps": ["^(veth|br-)"], "admin_api": { "socket_path": "/run/killswitch/admin.sock", "auth": { "groupnames": ["killswitch"] } }, "socks_proxy": { "enabled": true, "port": 1080, "fwmark": "0xeb9f0001", "dns_server": "8.8.8.8", "protected": { "usernames": ["root", "alice"] } }, "rulesets": { "wireguard-up": { "disabled": false, "match": "or", "trigger": { "interface_names": ["wg0"], "ip_addrs": ["10.64.0.2"] }, "enable_v4": true, "enable_v6": true, "allowed_v4_hostports": ["udp/198.51.100.10:51820"] } }, "allow_all": false, "enable_v4": true, "enable_v6": true, "allowed_marks": ["0x42"], "allowed_ports": [], "allowed_v4_hosts": [], "allowed_v6_hosts": [], "allowed_v4_hostports": ["udp/198.51.100.10:51820"], "allowed_v6_hostports": [] } ``` ### 接口过滤 至少需要以下包含选择器之一: - `interface_types` - `interface_names` - `interface_regexps` 匹配的忽略选择器将在包含之后应用: - `ignored_interface_types` - `ignored_interface_names` - `ignored_interface_regexps` 被忽略的接口不由守护进程管理。环回接口 `lo` 始终被忽略。 ### 全局策略 顶层策略是每个选定接口的基础策略: - `allow_all`:在正常数据包解析之前放行所有数据包。这应该作为 临时的恢复或调试设置。 - `enable_v4`:启用 IPv4 流量评估。当为 false 时,除内置引导流量外, 可路由的 IPv4 流量将被丢弃。 - `enable_v6`:启用 IPv6 流量评估。当为 false 时,除内置引导流量外, 可路由的 IPv6 流量将被丢弃。 - `allowed_marks`:允许带有匹配 fwmark 的数据包,例如 `"0x42"` 或 `"100"`。 - `allowed_ports`:允许任何主机上的 TCP 或 UDP 目标端口,例如 `"tcp/443"` 或 `"udp/53"`。 - `allowed_v4_hosts`、`allowed_v6_hosts`:无论端口如何,均允许目标主机。 - `allowed_v4_hostports`、`allowed_v6_hostports`:允许协议、目标 主机和目标端口组成的元组,例如 `"udp/198.51.100.10:51820"` 或 `"tcp/[2001:db8::10]:443"`。 对于固定端点,建议使用主机+端口规则。`allowed_ports` 通常过于 宽泛,因为它允许在每台主机上使用该目标端口。 eBPF 程序会将 ARP、DHCPv4、DHCPv6 和 ICMPv6 邻居发现 引导流量与这些允许规则分开处理。 ### 规则集 `rulesets` 是一个以规则集名称为键的对象。一个规则集包含: - `disabled`:在不删除规则集的情况下忽略它。 - `match`:`"or"` 或 `"and"`。如果任何触发谓词匹配,`"or"` 就会激活。 `"and"` 要求每个配置的触发器组都匹配。API 也将其公开为 `match_all`。 - `trigger`:激活谓词。 - 使用与全局策略相同名称的策略字段。 支持的触发器字段: - `interface_types` - `interface_names` - `interface_regexps` - `ip_addrs` - `ssids` - `bssids` - `gateway_macs` 规则集在每个接口上独立激活。对于每个选定的接口, 守护进程会从全局策略开始,并合并触发器匹配该接口的每个已启用的命名规则集。 被禁用的规则集将被忽略。 ### SOCKS 代理 守护进程可以在 `127.0.0.1` 上运行本地 SOCKS 代理。它由 `socks_proxy` 配置块控制,也可以通过 `killswitch-cli` 启动或停止。 - `enabled`:随守护进程启动代理。 - `port`:本地监听端口。默认为 `1080`。 - `fwmark`:应用于出站代理流量的标记。在代理运行时,配置的标记会 自动合并到 `allowed_marks` 中。 - `dns_server`:代理 DNS 处理所使用的可选 DNS 服务器。 - `protected.uids`、`protected.gids`、`protected.usernames`:限制哪些本地 用户可以连接到代理。 基于用户的代理访问是一个便利的边界,而不是绝对安全的保护。监听器会 尽最大努力检查传入本地连接的所有者,并且该检查可能会受到竞争条件的影响。 ### 管理 API 管理 API 默认启用。它监听 Unix socket,默认路径为 `/run/killswitch/admin.sock`。 配置字段: - `admin_api.socket_path`:Unix socket 的绝对路径。 - `admin_api.debug`:启用调试通知注入以测试客户端。 - `admin_api.auth.uids` - `admin_api.auth.gids` - `admin_api.auth.usernames` - `admin_api.auth.groupnames` 如果未配置任何身份验证规则,守护进程将允许 `killswitch` 组的成员。该 API 使用来自 Unix socket 连接的对端凭证。 ## 桌面集成 `killswitch-user` 应在用户的图形会话中运行。它连接到 守护进程管理 API,并处理面向用户的通知、托盘状态和 网络检查。 默认情况下,它使用: ``` $XDG_CONFIG_HOME/killswitch/killswitch-user.json ``` 或: ``` ~/.config/killswitch/killswitch-user.json ``` 如果你的会话在桌面栏或 D-Bus 服务就绪之前启动了 `killswitch-user`, 请添加一个启动延迟: ``` killswitch-user --delay 10s ``` 示例: ``` { "socket_path": "/run/killswitch/admin.sock", "notify_interface_changes": true, "notify_global_allow_all": true, "tray_enabled": true, "network_check": { "period": "300s", "url": "http://connectivity-check.ubuntu.com/", "status": 204, "header": "online", "notify": true, "captive_portal": { "cmd": [ "chromium", "--proxy-server={{.ProxyAddr}}", "--user-data-dir={{.Tmp}}", "--no-first-run", "--password-store=basic", "{{.Portal}}" ] } } } ``` 配置字段: - `socket_path`:管理 API 的 socket 路径。 - `notify_interface_changes`:在受管理的接口发生更改时显示通知。 - `notify_global_allow_all`:在全局 `allow_all` 状态发生更改时显示通知。 - `tray_enabled`:启用系统托盘 UI。 - `network_check`:在设置了 `url` 时启用定期连接检查。 网络检查字段: - `period`:间隔,例如 `"300s"`。 - `url`:要检查的 HTTP 端点。 - `status`:预期的 HTTP 状态码。 - `text`:可选的预期响应文本。 - `header`:可选的预期响应头。 - `timeout`:可选的请求超时。 - `notify`:为网络检查状态更改显示通知。 - `captive_portal`:在网络似乎需要登录时启动的命令。 强制门户命令支持模板值,例如 `{{.Portal}}`、 `{{.ProxyAddr}}` 和 `{{.Tmp}}`。建议在强制门户流程中使用 Chromium, 因为它可以通过命令行参数接受 SOCKS 代理 URL。 ## CLI 使用 `killswitch-cli` 与守护进程管理 API 通信。当守护进程 socket 不是默认值时, 每个子命令都接受 `-socket PATH` 或 `-s PATH`。 检查当前守护进程状态: ``` killswitch-cli get-cfg killswitch-cli get-cfg --watch killswitch-cli get-cfg --json-out ``` 监听通知: ``` killswitch-cli notifications killswitch-cli notifications --json-out ``` 启动或停止守护进程 SOCKS 代理: ``` killswitch-cli socks-proxy start killswitch-cli socks-proxy stop ``` 修改全局策略: ``` killswitch-cli set -target base_policy.enable_v4 true killswitch-cli set -target base_policy.allow_all false killswitch-cli add -target base_policy.allowed_v4_hostports udp/198.51.100.10:51820 killswitch-cli remove -target base_policy.allowed_marks 0x42 ``` 添加、更改或移除命名规则集: ``` killswitch-cli add -target ruleset -ruleset wireguard-up -json '{"trigger":{"interface_names":["wg0"]},"policy":{"enable_v4":true,"allowed_v4_hostports":["udp/198.51.100.10:51820"]}}' killswitch-cli set -target ruleset.disabled -ruleset wireguard-up true killswitch-cli remove -target ruleset -ruleset wireguard-up ``` 安装临时规则集并使其保持活动状态,直到按下 Ctrl+C、Ctrl+D、Esc 或 服务器断开连接: ``` killswitch-cli tmp-ruleset -interfaces wg0 -json '{"enable_v4":true,"allowed_v4_hostports":["udp/198.51.100.10:51820"]}' ``` 在 CLI 连接的生命周期内,强制为选定接口激活命名规则集: ``` killswitch-cli force-ruleset -interfaces wg0 -ruleset wireguard-up ``` 临时和强制规则集的作用域仅限于连接。当拥有它们的客户端断开连接时, 它们会自动被移除。 ## 应用程序集成 应用程序应将绕过 killswitch 视为用户的明确选择。默认情况下将其 保持禁用状态,只有在用户有意选择加入后才启用。 推荐策略: - 对于短暂的访问使用拥有的临时规则集。临时规则集与 管理 API 客户端连接绑定,并在应用程序退出、崩溃或断开连接时自动移除。 - 当应用程序与已知地址通信时,首选端点白名单。仅针对所需的 协议、地址和端口添加主机+端口规则。 - 当应用程序能够标记其所有流量时,使用 fwmark 策略。 使用带有 `allowed_marks` 的临时客户端拥有的规则。 ## 待办事项 - [ ] killswitch 守护进程启动后是否应进行权限降级? - [ ] 安全审计 - [ ] killswitch-cli 的 shell 自动补全 - [ ] 流行 VPN 客户端的设置示例 - [ ] Tailscale? - [ ] Amnesia - [ ] 允许检查多个 URL 以测试网络连通性 ## 许可协议 本仓库采用 GPL 或 MIT 双重许可;请参阅 [LICENSE-GPL](./LICENSE-GPL) 和 [LICENSE-MIT](./LICENSE-MIT)。 注意:Go 绑定嵌入了由 `bpf2go` 生成的预编译 eBPF 对象二进制大对象 (`cmd/killswitch/killswitch_bpf*.o`)。 这些二进制大对象由开源的 [killswitch.c](./cmd/killswitch/killswitch.c) 构建, 该文件为内核验证器声明了 `Dual MIT/GPL`。 你可以使用以下命令重新生成它们: ``` go generate ./... ```
标签:EVTX分析, VPN, 日志审计, 流量过滤, 网络防火墙