friendly-bits/geoip-shell
GitHub: friendly-bits/geoip-shell
一款轻量级的 Linux 地理封锁工具,支持 nftables/iptables,可基于国家 IP 列表自动创建防火墙白名单或黑名单。
Stars: 411 | Forks: 16
# geoip-shell
适用于 Linux 的用户友好且功能丰富的地理封锁工具。支持 **nftables** 和 **iptables** 防火墙管理工具。
该项目的初衷是让地理封锁(即根据地理位置限制来自或发往互联网地址的访问)在(几乎)任何 Linux 系统上变得简单,无论硬件如何,包括桌面、服务器、容器、VPS 或路由器,同时保持可靠性并为高级用户提供灵活的配置选项。
[](https://github.com/friendly-bits/geoip-shell/assets/134004289/24010da9-a62a-428f-ae4d-cb1d4ae97f73)
[](https://github.com/friendly-bits/geoip-shell/assets/134004289/b35e199f-465d-487c-809b-9c5a8f0644be)
## 目录
- [主要功能](#main-features)
- [安装](#installation)
- [用法](#usage)
- [出站地理封锁](#outbound-geoblocking)
- [本地白名单和黑名单](#local-allowlists-and-blocklists)
- [前置条件](#pre-requisites)
- [注意事项](#notes)
- [详情](#in-detail)
- [OpenWrt](#openwrt)
- [隐私](#privacy)
- [附言](#ps)
## **主要功能**
* 核心功能是使用自动下载的用户指定国家的 IP 列表,在防火墙中创建白名单或黑名单。
* IP 列表获取自 **RIPE**(欧洲、中东和部分中亚地区的区域互联网注册机构)、**ipdeny** 或 **MaxMind**。这 3 个来源均提供所有区域的更新 IP 列表。
* 初始设置期间,会自动创建地理封锁所需的所有防火墙规则和 IP 集合。
* 支持自动化交互式设置,便于配置。
* 根据用户偏好自动创建辅助防火墙规则(例如,在主机上以白名单模式配置时,geoip-shell 会检测局域网 IP 范围并建议将其添加到白名单)。
* 实现了可选的(默认启用)跨系统重启的地理封锁持久化以及 IP 列表的自动更新。
* 安装后,提供一个工具用于检查地理封锁状态和防火墙规则,或更改国家代码和地理封锁相关配置。
* 支持入站和出站地理封锁。
* 支持 ipv4 和 ipv6。
* 支持在 OpenWrt 上运行。
### **可靠性**:
- 下载的 IP 列表会经过验证,以防止将损坏或不完整的列表应用到防火墙。
### **效率**:
- 利用原生的 nftables 集合(或者对于 iptables,使用 ipset 工具),这允许创建包含数千个 IP 范围的高效防火墙规则。
### **用户友好性**:
- 安装和初始设置简单,通常只需很短的时间。
- 良好的命令行界面和有用的控制台消息。
### **兼容性**:
- 由于该项目是用符合 POSIX 标准的 shell 代码编写的,因此它几乎兼容所有 Linux 系统(只要它具备[前置条件](#pre-requisites))。它甚至可以在仅有 8MB 闪存和 128MB 内存的简单嵌入式路由器上良好运行(对于 nftables,如果使用大型 IP 列表(如美国的列表),建议使用 256MB 内存,直到 nftables 团队发布减少内存消耗的修复程序)。
- 代码定期在 Debian、Linux Mint 和 OpenWrt 上测试,偶尔在 Alpine Linux 和 Gentoo 上测试。
- 虽然开发者没有专门进行测试,但有报告称在 LXC 容器中成功使用(如果在 LXC 容器中运行 geoip-shell 时遇到错误,请查看 [issue #24](/../../issues/24) 以获取可能的解决方案)。
## **安装**
_(请注意,某些命令需要 root 权限,因此您可能需要使用 `sudo` 运行它们)_
**1)** 如果您的系统没有 `curl`、`wget` 或(OpenWRT 工具)`uclient-fetch`,请使用您的发行版的包管理器安装其中之一(对于 Debian 及其衍生版:`apt-get install curl`)。仅拥有 `iptables` 的系统还需要 `ipset` 工具(`apt-get install ipset`)。
**2)** 下载最新版本:https://github.com/friendly-bits/geoip-shell/releases。除非您在 OpenWrt 上安装,否则请下载 **Source code (zip or tar.gz)**。要在 OpenWrt 上安装,请阅读 [OpenWrt README](/OpenWrt/README.md)。
_
**3)** 将版本中包含的所有文件解压到您主目录中的同一文件夹中,并在终端中 `cd` 进入该目录。
**4)** 对于安装后跟交互式设置,请运行 `sh geoip-shell-install.sh`。对于非交互式安装,请运行 `sh geoip-shell-install.sh -z`。
**注意:** 如果安装脚本提示您的 shell 不兼容,但您安装了另一个兼容的 shell,请使用它代替 `sh` 来调用 -install 脚本。例如:`dash geoip-shell-install.sh`。请查看 [前置条件](#pre-requisites) 以获取兼容 shell 的列表。如果您没有安装其中之一,请使用您的包管理器安装一个(您不需要将其设为默认 shell)。
**5)** 除非您以非交互模式安装,否则安装脚本会建议您配置 geoip-shell。如果您输入 `y`,geoip-shell 会询问您几个问题,然后启动 IP 列表的下载和应用。
## **初始设置**
安装完成后,安装程序会建议自动启动交互式设置。如果您以非交互方式运行安装脚本或在某个时候中断了设置,可以通过运行 `geoip-shell configure` 手动(重新)启动交互式设置。
交互式设置通过与用户的对话收集重要配置,不需要任何命令行参数。如果您不确定如何回答某些问题,请阅读 [SETUP.md](/Documentation/SETUP.md)。
或者,可以通过命令行参数提供部分或全部配置选项。
**注意:** 某些功能只能通过命令行参数访问。特别是,默认情况下,初始设置仅配置入站地理封锁,并将出站地理封锁保持禁用状态。如果要配置出站地理封锁,请阅读[出站地理封锁](#outbound-geoblocking)部分。
_要了解更多信息,请运行 `geoip-shell -h` 或阅读 [NOTES.md](/Documentation/NOTES.md) 和 [DETAILS.md](/Documentation/DETAILS.md)_
## **用法**
_(请注意,所有命令都需要 root 权限,因此您可能需要使用 `sudo` 运行它们)_
通常,一旦安装完成,您无需执行任何其他操作即可使**入站**地理封锁生效(如果您是通过 OpenWrt ipk 包安装的,请阅读 [OpenWrt README](/OpenWrt/README.md))。
默认情况下,IP 列表将在当地时间凌晨 4:15 左右每日更新(为了避免所有人同时加载服务器,默认分钟数在初始设置时随机化为 +-12 精度,秒数在自动更新时随机化)。
如果您想更改地理封锁配置或检查地理封锁状态,可以通过提供的工具进行。
此处列出了部分选项,如需更多选项,请运行 `geoip-shell -h` 或阅读 [NOTES.md](/Documentation/NOTES.md) 和 [DETAILS.md](/Documentation/DETAILS.md)。
**注意**,在使用 `geoip-shell configure` 命令时,如果未指定方向,则特定方向的选项适用于**入站**地理封锁。特定方向的选项包括 `-m `、`-c `、`-p `。要指定方向,请在指定该方向的选项之前添加 `-D `(有关更多详细信息,请阅读[出站地理封锁](#outbound-geoblocking)部分)。
**检查当前 geoip 封锁状态:** `geoip-shell status`。要列出主地理封锁链中的所有防火墙规则以及每个 IP 列表中 IP 范围的详细计数:`geoip-shell status -v`。
**配置地理封锁模式:**
`geoip-shell configure -m `
(`disable` 卸载所有 IP 列表并移除给定方向的防火墙地理封锁规则)
**更改地理封锁白名单/黑名单中的国家:**
`geoip-shell configure -c <"country_codes">`
`-c` 选项接受任何有效的 2 字母国家代码和/或区域代码(RIPE, ARIN, APNIC, AFRINIC, LACNIC)的组合。
_
**封锁或允许特定协议、端口或端口范围:**
`geoip-shell configure -p <[tcp|udp]:[allow|block]:[all|`
`geoip-shell configure -p `
_(有关此功能的详细说明,请阅读 [NOTES.md](/Documentation/NOTES.md),第 10-12 节)_
**启用或禁用地理封锁**(仅添加或移除地理封锁启用规则,保留所有其他防火墙地理封锁规则和 IP 集合):
`geoip-shell `
**更改 IP 列表来源:** `geoip-shell configure -u `
**让某些受信任的 IP 地址或 IP 范围(无论是在您的 LAN 中还是互联网上的任何位置)绕过地理封锁:**
`geoip-shell configure -t <["ip_addresses"]|none>`
`none` 移除先前设置的受信任 IP 地址。
**让某些 LAN IP 地址或 IP 范围绕过 geoip 封锁:**
`geoip-shell configure -l <["ip_addresses"]|auto|none>`
LAN 地址只能在至少一个方向的地理封锁模式设置为 `whitelist` 时配置。否则,无需将 LAN 地址列入白名单。此外,通常仅当机器没有专用 WAN 网络接口时,才需要将 LAN 地址列入白名单。否则,您应该仅对那些 WAN 接口应用地理封锁,这样来自 LAN 到机器的流量将绕过地理封锁过滤器,而无需为此设置特殊规则。
`auto` 将自动检测 LAN IP 范围(仅当机器没有专用 WAN 接口时使用此选项)。`none` 移除先前设置的 LAN IP 地址。
**检查某些 IP 地址是否属于 geoip-shell 加载的任何 IP 集合:**
`geoip-shell lookup [-I <"ip_addresses">] [-F ] [-v]`
有关此功能的详细说明,请运行 `geoip-shell -h` 或阅读 [DETAILS.md](/Documentation/DETAILS.md)。
**启用或更改自动更新计划:** `geoip-shell configure -s <"schedule_expression">`
_
**禁用 IP 列表的自动更新:** `geoip-shell configure -s disable`
**更新或重新安装 geoip-shell:** 从(更新的)分发目录运行 -install 脚本。
**暂时停止 geoip-shell:** `geoip-shell stop`。这将终止所有正在运行的 geoip-shell 进程,移除 geoip-shell 防火墙规则并卸载 IP 集合。要重新激活地理封锁,请运行 `geoip-shell configure`。
**卸载:** `geoip-shell-uninstall.sh`
在 OpenWrt 上,如果是通过 ipk 包安装的:`opkg remove `。对于 apk 包:`apk del geoip-shell`。
**设置成功或失败报告:**
`、`-c `、`-p `。要指定方向,请在指定该方向的选项之前添加 `-D `。
因此,要配置出站地理封锁,请使用上方[用法](#usage)部分中描述的相同命令,但在任何特定方向的选项之前添加 `-D outbound` 选项。
示例:
**启用并配置出站地理封锁:**
`geoip-shell configure -D outbound -m `.
**为入站和出站方向配置地理封锁模式:**
`geoip-shell configure -D inbound -m -D outbound -m `
配置**入站和出站**地理封锁,对于传入流量将德国和意大利列入白名单并阻止所有其他国家,对于传出流量将法国列入黑名单:
`geoip-shell configure -D inbound -m whitelist -c "DE IT" -D outbound -m blacklist -c FR`
**更改出站地理封锁适用的协议和端口:**
`geoip-shell configure -D outbound -p <[tcp|udp]:[allow|block]:[all|]>`
`geoip-shell configure -D outbound -p `
## **本地白名单和黑名单**
geoip-shell 支持将自定义的换行符分隔的 IP 列表导入到本地存储的文件中。然后使用这些文件创建额外的允许或阻止规则。无论地理封锁模式是白名单还是黑名单,也无论启用哪个地理封锁方向(入站或出站或两者),都会为本地 IP 列表创建规则。
要导入自定义 IP 列表,请使用以下命令:
`geoip-shell configure [-A|-B] <"[path_to_file]"|remove>`
使用 `-A` 将 IP 列表作为白名单导入。使用 `-B` 将 IP 列表作为黑名单导入。
`remove` 关键字告诉 geoip-shell 移除指定类型(白名单 or 黑名单)的任何现有本地 iplist。
每个 IP 列表文件只能包含一个家族(ipv4 或 ipv6)的 IP 地址和/或 IP 范围(CIDR 格式)。
_
_
您可以按顺序导入多个 IP 列表,geoip-shell 会将每个文件中的 IP 地址添加到本地存储的 IP 列表中。
**请注意**,黑名单规则优先于白名单规则。因此,如果同一个 IP 地址同时包含在本地白名单和本地黑名单中,它将被阻止。
**请注意**,导入自定义 IP 列表时,geoip-shell 会在 OpenWrt 上的 `/etc/geoip-shell/local_iplists/` 或所有其他系统上的 `/var/lib/geoip-shell/local_iplists/` 中创建本地允许和阻止列表文件。用于导入 IP 列表的原始文件在导入后可以删除以释放空间。要更改导入的本地 IP 列表的存储目录,请使用命令 `geoip-shell configure -L `。
## **前置条件**
(如果缺少前置条件,_-install.sh_ 脚本会告诉您)
- **Linux**。在类 Debian 系统和 OPENWRT 上测试过,应该适用于任何桌面/服务器发行版,也可能适用于其他一些嵌入式发行版。
- **符合 POSIX 标准的 shell**。适用于大多数相对现代的 shell,包括 **bash**、**dash**、**mksh**、**lksh**、**ksh93u+m**、**yash** 和 **ash**(包括 Busybox **ash**)。**不**适用于 **fish**、**tcsh** 和 **zsh**。
**注意:** 如果安装脚本提示您的 shell 不兼容,但您安装了另一个兼容的 shell,请使用它代替 `sh` 来调用 -install 脚本。例如:`dash geoip-shell-install.sh`。您用来安装 geoip-shell 的 shell 将是它安装后运行的 shell。通常,由于性能更好,首选更简单的 shell(如 dash 或 ash)而不是复杂的 shell(如 bash 和 mksh)。
- **nftables** - 防火墙管理工具。支持 nftables 1.0.2 及更高版本(可能适用于早期版本,但我不对其进行测试)。
- 或 **iptables** - 防火墙管理工具。应适用于任何相对现代的版本。
- 对于 **iptables**,需要 **ipset** 工具 - 使用您的发行版的包管理器安装它
- 标准 Unix 工具,包括 **tr**、**cut**、**sort**、**wc**、**awk**、**sed**、**grep**、**pgrep**、**pidof** 和 **logger**,这些工具包含在每个服务器/桌面 linux 发行版(以及 OpenWrt)中。支持 GNU 和非 GNU 版本,包括 BusyBox 实现。
- **wget** 或 **curl** 或 **uclient-fetch**(OpenWRT 特定工具)。
- 对于自动更新功能,需要启用 **cron** 服务。除 OpenWrt 外,持久化也需要 cron 服务。
- 对于 MaxMind 来源,需要工具:`unzip`、`gzip`、`gunzip`(`apt install unzip gzip`)
**可选**:_check-ip-in-source.sh_ 可选脚本需要 **grepcidr**。在 Debian 及其衍生版上使用 `apt install grepcidr` 安装它。对于其他发行版,请使用其内置的包管理器。
## **注意事项**
有关使用此套件的一些有用说明,请阅读 [NOTES.md](/Documentation/NOTES.md)。
## **详情**
有关每个脚本的具体信息,请阅读 [DETAILS.md](/Documentation/DETAILS.md)。
## OpenWrt
有关 OpenWrt 支持的信息,请阅读 [OpenWrt README](/OpenWrt/README.md)。
## **隐私**
geoip-shell 不会与任何人共享您的数据。
如果您使用 ipdeny 或 maxmind 来源,请注意它们是第三方,拥有自己的数据隐私政策。
## 附言
- 我希望能收到关于它在您的系统上是否有效的报告(请注明具体系统)。您可以为此使用 Github Discussions 标签。
- 如果您发现错误或想请求功能,请通过开启 issue 告诉我。
阅读更多:
- IP 列表的默认来源是 RIPE,这可以避免依赖非官方的第三方。 - 支持 'MaxMind' 商业来源,该来源提供更准确的 IP 列表,包括免费的 GeoLite2 数据库和付费的 GeoIP2 数据库。请注意,为了使用 MaxMind 来源,您需要拥有 MaxMind 账户。 - 对于 nftables,利用 nftables 原子规则替换功能,使与系统防火墙的交互具有容错能力,并完全消除自动更新期间 geoip 被禁用的时间。 - 所有脚本都执行广泛的错误检测和处理。 - 所有用户输入都经过验证,以减少意外错误的发生几率。 - 每次操作后验证防火墙规则的一致性。 - geoip-shell 状态的自动备份(可选,默认启用,OpenWrt 除外)。 - 重启后(即持久化)或在发生意外错误时,自动恢复 geoip-shell 防火墙规则。 - 支持在互联网任何位置指定受信任的 IP 地址,这些地址将绕过 geoip 封锁,以便在出现问题时更容易重新获得对机器的访问权限。阅读更多:
- 对于 nftables,根据机器的 RAM 容量和用户偏好,针对低内存消耗或性能进行地理封锁优化。对于 iptables,实现了自动优化。 - IP 列表解析和验证通过高效的正则表达式处理实现,即使在缓慢的嵌入式 CPU 上也非常快速。 - 通过数据时间戳检查实现 IP 列表的智能更新,避免了不必要的下载和防火墙重新配置。 - 对于入站地理封锁,使用内核 netfilter 组件中的 "prerouting" 钩子,这缩短了有害数据包在系统中的传输路径,如果后续有其他防火墙规则处理传入流量,可能会降低 CPU 负载。 - 支持 'ipdeny' 来源,该来源提供聚合的 IP 列表(适用于内存有限的嵌入式设备)。 - 脚本仅在由用户直接调用或由 init 脚本/重启 cron 作业/更新 cron 作业调用时短暂处于活动状态。阅读更多:
- 广泛且(通常)最新的文档。 - 附带卸载脚本,可完全删除套件和地理封锁防火墙规则。无需重启。 - 安装时默认应用合理的设置,但也为高级用户或特殊情况提供了大量命令行选项。 - 安装前,提供一个工具 _(check-ip-in-source.sh)_ 用于检查您可能想要列入黑名单或白名单的特定 IP 地址是否确实包含在从来源(RIPE 或 ipdeny 或 MaxMind)获取的 IP 列表中。 - 安装后,提供一个工具(符号链接到 _'geoip-shell'_)供用户更改地理封锁配置(打开或关闭地理封锁、配置出站地理封锁、更改国家代码、更改地理封锁模式、更改 IP 列表来源、更改 cron 计划等)。 - 安装后,提供命令 _('geoip-shell status')_ 以检查地理封锁状态,该命令还会报告是否存在任何问题。 - 如果出现错误或用户输入无效,会提供有用的错误消息以帮助排查故障。 - 所有主脚本在使用 '-h' 选项执行时会显示详细的 'usage'(用法)信息。 - 大部分代码应该相当容易阅读,并包含适量的注释。阅读更多:
- 支持在 OpenWrt 上运行。 - 该项目通过在自定义 shell 代码中实现非常用工具的功能,避免了使用它们,这使其速度更快且兼容更广泛的系统。**或使用命令行下载**:
_ - 运行 `git clone https://github.com/friendly-bits/geoip-shell` - 这将包含所有最新的更改,但可能并不总是稳定的 - 或者下载最新版本(需要 curl): `curl -L "$(curl -s https://api.github.com/repos/friendly-bits/geoip-shell/releases | grep -m1 -o 'https://api.github.com/repos/friendly-bits/geoip-shell/tarball/[^"]*')" > geoip-shell.tar.gz` - 要解压,请运行:`tar -zxvf geoip-shell.tar.gz`示例:
_ - 将国家设置为德国和荷兰:`geoip-shell configure -c "DE NL"`示例
_ `geoip-shell configure -s "1 4 * * *"`
geoip-shell 支持指定一个自定义 shell 脚本,该脚本定义 `gs_success` 或 `gs_failure` 任意一个或两个函数,以便在 geoip-shell 自动运行时(例如重启后或自动 IP 列表更新期间)在成功或失败时调用。此功能可用于例如发送电子邮件/短信/消息。
您可以根据需要实现 `gs_success` 和/或 `gs_failure` 函数。调用 `gs_failure` 时,geoip-shell 将提供运行期间收集的会话日志作为第一个参数。调用 `gs_success` 时,除非遇到错误或警告,否则 geoip-shell 不会提供会话日志。
以下是免费 Brevo(前身为 sendinblue)电子邮件服务的示例,但您可以使用自己喜欢的 smtp/email/短信等方法。
1. 安装 mailsend
2. 注册免费的 Brevo 账户(非关联!)
3. 创建文件 `/usr/libexec/geoip-shell_custom-script.sh`(您可以使用任何其他合适的路径)- 将下方大写的变量替换为您的具体详细信息:
```
#!/bin/sh
gs_success()
{
mailbody="${1}"
mailsend -port 587 -smtp smtp-relay.brevo.com -auth -f FROM@EMAIL.COM -t TO@EMAIL.COM -user BREVO@USERNAME.COM -pass PASSWORD -sub "geoip-shell automatic run successful" -M "${mailbody}"
}
gs_failure()
{
mailbody="${1}"
mailsend -port 587 -smtp smtp-relay.brevo.com -auth -f FROM@EMAIL.COM -t TO@EMAIL.COM -user BREVO@USERNAME.COM -pass PASSWORD -sub "geoip-shell automatic run failed" -M "${mailbody}"
}
```
- Brevo 密码在其网站内提供,而不是注册时创建的密码。
- 如果是从 Windows 复制粘贴,请避免复制粘贴 Windows 样式的换行符。为确保万无一失,在 Windows 中使用支持更改换行符样式的文本编辑器(例如 Notepad++),并确保将其设置为 Unix (LF),而不是 Windows (CR LF)。
4. 确保为自定义脚本设置权限,例如 `chmod 640 "" && chown root:root ""`
5. 在 geoip-shell 中配置自定义脚本:
```
geoip-shell configure -S ""
```
6. 测试调用自定义脚本:
```
geoip-shell-run.sh update -a
```
禁用调用自定义脚本:
```
geoip-shell configure -S none
```
**使用 `configure` 命令的示例:**
- 在位于德国、拥有 nftables 且位于防火墙之后(无直接 WAN 连接)的服务器上配置**入站**地理封锁,将德国和意大利列入白名单并阻止所有其他国家:
`geoip-shell configure -r DE -i all -l auto -m whitelist -c "DE IT"`
- 在位于美国、拥有 WAN 网络接口(名为 `pppoe-wan`)的路由器上配置**入站**地理封锁,将德国和荷兰列入黑名单并允许所有其他国家:
`geoip-shell configure -m blacklist -c "DE NL" -r US -i pppoe-wan`
## **出站地理封锁**
在使用 `geoip-shell configure` 命令时,如果未指定方向,则特定方向的选项适用于**入站**地理封锁方向。
特定方向的选项包括 `-m 示例源文件内容
_ ``` 8.8.8.8 1.1.1.1/24 ```示例命令
_ `geoip-shell configure -A /tmp/my-ip-list.txt` - 这会将指定的文件作为白名单导入。标签:CISA项目, Cutter, GeoIP, iptables, IP过滤, MaxMind, nftables, OpenWrt, Prompt Injection, Shell脚本, Streamlit, VPS安全, 入侵防御, 地理封锁, 开源, 白名单, 网络安全, 访问控制, 运维工具, 防火墙, 隐私保护, 黑名单