在 Ubuntu 12.0.4.5 (LTS) 中,有没有其他方法可以让 IPTables 根据地理位置过滤 IP 地址

在 Ubuntu 12.0.4.5 (LTS) 中,有没有其他方法可以让 IPTables 根据地理位置过滤 IP 地址

因此,我管理的几台服务器正受到来自中国的流量冲击,而这些网站本身对中国人来说根本就没有任何吸引力。更糟糕的是,许多不必要的暴力黑客攻击和 DDoS 攻击也来自中国。因此,虽然我安装了 Fail2Ban 来阻止部分流量,但我真的很想暂时关闭来自中国的任何/所有流量,以保持这些服务器稳定、顺利地运行。

我已阅读有关如何为 IPTables 启用 GeoIP 支持的信息,并尝试遵循以下解决方案比如这里介绍的,但无论我遵循什么建议,它似乎都无法在我的 Ubuntu 12.04.5 (LTS) 服务器上运行。

我有一个选择,那就是硬着头皮将这些服务器升级到 Ubuntu 14.04,但这会带来一大堆麻烦。除了我在启动和运行 GeoIP 过滤时遇到的任何问题之外,这些服务器非常稳定,性能也相当不错。升级到 14.04 只会给它们带来潜在的不稳定因素,而我没有时间考虑这个;我决定继续使用 12.04,因为它在 2017 年之前都很稳定并且得到很好的支持,所以我会在遇到这个问题时再考虑。

那么,有没有什么方法可以让 Ubuntu 12.04 上的 IPTables 根据地理位置进行过滤,而不需要经历太多的系统包安装环节?

答案1

事实证明,我不必完全重新发明轮子来将某种 GeoIP 支持与 IPTables 混合使用。只需使用 IPSet 和 MaxMind 的 GeoIP Country 数据库副本(CSV 格式)以及一条简单的 IPTables 规则,即可在 Ubuntu 12.04.5 (LTS) 中启动并运行它。

附注:但一些解释此类过程的在线教程建议使用基于 Web 的国家区域文件,例如来自 IPDeny 网站的文件:

http://www.ipdeny.com/ipblocks/data/countries/cn.zone

虽然从技术上讲这可行,但我不喜欢如此依赖外部网站的数据。如果我想创建一个自动化脚本流程来管理这一点,而 IPDeny 网站出现故障或被黑客入侵,该怎么办?我会阻止谁的 IP。

这就是为什么我更喜欢在我的服务器上使用 CSV 格式的 MaxMind GeoIP 国家/地区数据库。如果需要更新,我可以随时获取该数据库的新副本,即使他们的网站瘫痪,我的服务器上也始终有该数据库的副本。由于该数据库包含世界上所有国家/地区,因此我始终可以使用国家/地区的两个字母轻松地将更多国家/地区添加到 IP 集中ISO 3166-1国家代码。

无论如何,以下是我使用 IPSet 和 MaxMind GeoIP 国家数据库完成此操作所采取的步骤。

1.安装IPSet。

首先,像这样安装IPSet。

sudo aptitude install ipset

安装完成后,创建一个BANNED_RANGES如下 IP 集:

sudo ipset create BANNED_RANGES hash:net

2. 获取 CSV 格式的 MaxMind GeoIP 国家数据库副本。

下一步的关键是获取一份 CSV 格式的 MaxMind GeoIP Country 数据库副本并安装在服务器上。我的步骤如下:

curl -O -L http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip

现在只需解压该档案:

unzip -o -q -d . GeoIPCountryCSV.zip

3. 像这样过滤并导入特定国家/地区的 IPSet 配置。

现在我们将使用 Awk 将中国特定的 IP 范围过滤到 IPSet 配置文件中:

awk -F "," -v COUNTRY_CODE=CN -v IPSET_TABLE=BANNED_RANGES} '$5 ~ COUNTRY_CODE { gsub(/"/, "", $1); gsub(/"/, "", $2); print "add "IPSET_TABLE" "$1"-"$2; }' /usr/local/share/GeoIP/GeoIPCountryWhois.csv >> ipset.BANNED_RANGES.conf

这将创建一个名为的 IPSet 配置文件ipset.BANNED_RANGES.conf,然后可以将其导入 IPSet,如下所示:

sudo ipset restore < ipset.BANNED_RANGES.conf

然后您可以使用以下命令检查该集合中的项目:

sudo ipset -l BANNED_RANGES | more

4. 使 IPTables 了解 IPSet。

现在,将所有内容整合在一起的最后一步是向 IPTables 中插入一条简单规则,如下所示:

sudo iptables -I INPUT -p tcp -m set --match-set BANNED_RANGES src -j REJECT

一旦完成后,IPTables 现在知道任何添加到集合的 IP 地址或范围都BANNED_RANGES将被拒绝REJECT

如果您以后想摆脱该规则,可以运行以下命令:

sudo iptables -D INPUT -p tcp -m set --match-set BANNED_RANGES src -j REJECT

但对我来说,这有点混乱。处理这种情况的一个更干净的方法是将所有 IP 数据从集合中清除,BANNED_RANGES如下所示:

sudo ipset flush BANNED_RANGES

通过这样做,您可以使 IPTables 规则到位,而不必执行任何其他操作,只需清除数据即可BANNED_RANGES。如果您想从该集合中添加或删除 IP 地址或范围,可以更方便/更轻松地更新地址或范围。

答案2

基于 Giacomo 在 2015 年的回答……

现在到了 2023 年,MaxMind 要求您完成登录过程并生成(免费)许可证密钥,以便自动下载 CSV 文件。目前,这些文件的永久链接如下

https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=YOUR_LICENSE_KEY&suffix=zip

您可以创建一个 cronjob 来每天或每周下载一次此文件。/etc/cron.weekly例如,添加以下脚本:

#!/bin/bash -e
CACHEDIR=/var/cache/geoip
read KEY << END_KEY
.... what you generate from MaxMind ...
END_KEY

install -d -m 0755 $CACHEDIR
cd $CACHEDIR
file=GeoLite2Country-CSV.zip
curl -s -S -L -o "$file" \
  "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=$KEY&suffix=zip"
unzip -j $file
rm $file

有两组文件:由国际化文件分隔的国家/地区名称和主 geo-ip DB。我假设您想通过英文拼写来识别国家/地区名称。

这些文档可在以下网址找到:https://dev.maxmind.com/geoip/docs/databases/city-and-country

要将 CSV 转换为 ipset,可以使用此脚本,该脚本可以附加到前一个脚本中。这里的优点是效率和原子性。该ipset restore操作(来自 Giacomo 的回答)将积累更改,而不是删除不再有效的更改。

此解决方案将用新的替换旧的,这样就不需要删除 iptables 规则,并且服务也不会中断。

# Setup....
country_name=REPLACE_WITH_YOUR_COUNTRY_NAME
ipset=geo-$country
ipset_temp=$( mktemp -u $ipset.XXXXX )
ipset create -exist $ipset hash:net
ipset create $ipset_temp hash:net
trap "ipset destroy $ipset_temp" EXIT

# Extrapolate the country-code from the Country-Locations DB
ccode=$( awk -F, -v cname=$country_name '$6 == cname { print $1 }'  GeoLite2-Country-Locations-en.csv )

# Extrapolate and restore the IPs found in the IPV4 set.
awk -F, -v ipset=$ipset_temp -v ccode=$ccode '$2 == ccode || $4 == ccode { print "add",ipset,$1 }' GeoLite2-Country-Blocks-IPv4.csv  | ipset restore

ipset swap $ipset_temp $ipset

请注意:如果您喜欢我的回答,也为 Giacomo 点赞,因为他做了大部分工作。

完整的工作脚本如下以片段形式发布

相关内容