阻止来自某些国家/地区的流量的任务似乎很简单,但第一印象就是欺骗。今天,我们将告诉您如何实施。
背景
Google在该主题上的搜索结果令人沮丧:大多数解决方案长期以来一直“烂透了”,有时似乎这个主题已被搁置一旁,并永远被遗忘了。我们已经浏览了许多旧记录,并准备好共享现代版本的说明。
我们建议您在执行指示的命令之前先阅读全文。
准备操作系统
过滤将使用iptables实用程序进行配置,该实用程序需要扩展才能使用GeoIP数据。这样的扩展可以在xtables-addons中找到。xtables-addons将iptables扩展安装为独立的内核模块,因此无需重新编译OS内核。
在撰写本文时,xtables-addons的当前版本是3.9。但是,在标准Ubuntu 20.04 LTS存储库中只能找到3.8,而在Ubuntu 18.04存储库中只能找到3.0。您可以使用以下命令从程序包管理器安装扩展:
apt install xtables-addons-common libtext-csv-xs-perl
请注意,版本3.9与项目的当前状态之间存在细微但重要的差异,我们将在后面讨论。要从源代码进行构建,请安装所有必需的软件包:
apt install git build-essential autoconf make libtool iptables-dev libxtables-dev pkg-config libnet-cidr-lite-perl libtext-csv-xs-perl
克隆存储库:
git clone https://git.code.sf.net/p/xtables-addons/xtables-addons xtables-addons-xtables-addons
cd xtables-addons-xtables-addons
xtables-addons包含许多扩展,但是我们只对xt_geoip感兴趣。如果您不想将不必要的扩展名拖到系统中,则可以将其从程序集中排除。为此,您需要编辑mconfig文件。对于所有需要的模块,输入y,所有不必要的模块,设置n。我们收集:
./autogen.sh
./configure
make
并以超级用户权限安装:
make install
在安装内核模块的过程中,可能会出现类似内容的错误:
INSTALL /root/xtables-addons-xtables-addons/extensions/xt_geoip.ko
At main.c:160:
- SSL error:02001002:system library:fopen:No such file or directory: ../crypto/bio/bss_file.c:72
- SSL error:2006D080:BIO routines:BIO_new_file:no such file: ../crypto/bio/bss_file.c:79
sign-file: certs/signing_key.pem: No such file or directory
发生这种情况是由于无法签名内核模块,因为 没有要签名的东西。您可以使用几个命令来解决此问题:
cd /lib/modules/(uname -r)/build/certs
cat <<EOF > x509.genkey
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
CN = Modules
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
EOF
openssl req -new -nodes -utf8 -sha512 -days 36500 -batch -x509 -config x509.genkey -outform DER -out signing_key.x509 -keyout signing_key.pem
已安装编译的内核模块,但系统未检测到它。让我们让系统基于新模块创建一个依赖关系图,然后加载它:
depmod -a
modprobe xt_geoip
确保xt_geoip已加载到系统中:
# lsmod | grep xt_geoip
xt_geoip 16384 0
x_tables 40960 2 xt_geoip,ip_tables
此外,确保扩展已加载到iptables中:
# cat /proc/net/ip_tables_matches
geoip
icmp
一切适合我们,剩下的就是将模块的名称添加到/ etc / modules中,以便模块在重启操作系统后可以正常工作。在这一点上,iptables可以理解geoip命令,但是缺少要使用的数据。让我们开始加载geoip数据库。
获取GeoIP数据库
创建一个目录,该目录将存储有关iptables扩展的信息:
mkdir /usr/share/xt_geoip
在本文开头,我们提到源版本和程序包管理器版本之间存在差异。最明显的区别是数据库提供程序和xt_geoip_dl脚本的更改,该脚本下载了实际数据。
包管理器中的版本
该脚本位于/ usr / lib / xtables-addons路径中,但是,当您尝试启动时,可能会看到一个不太有用的错误:
# ./xt_geoip_dl
unzip: cannot find or open GeoLite2-Country-CSV.zip, GeoLite2-Country-CSV.zip.zip or GeoLite2-Country-CSV.zip.ZIP.
以前,数据库使用的是GeoLite产品,现在称为GeoLite Legacy,由MaxMind根据Creative Commons ASA 4.0许可分发。使用该产品,同时发生了两个事件,这“破坏”了与iptables扩展的兼容性。
首先,在2018年1月,他们宣布终止对该产品的支持,并在2019年1月2日,从官方网站上删除了所有下载旧版本数据库的链接。建议新用户使用GeoLite2产品或其付费版本GeoIP2。
其次,自2019年12月起,MaxMind宣布关于他们数据库访问权限的重大变化。为了遵守加利福尼亚州的消费者保护法,MaxMind决定通过注册“掩盖” GeoLite2的发行。
由于我们要使用他们的产品,因此我们将在此页面上注册。
此后,将向邮件中显示一条消息,要求您设置密码。现在我们已经创建了一个帐户,我们需要创建一个许可证密钥。在您的个人帐户中,找到“我的许可证密钥”项目,然后单击“生成新的许可证密钥”按钮。
创建密钥时,将仅询问我们一个问题:我们将在GeoIP更新程序中使用此密钥吗?我们回答否定,然后单击“确认”按钮。该键将显示在弹出窗口中。将此密钥保存在安全的地方,因为关闭弹出窗口后,您将不再能够看到完整的密钥。
我们可以手动下载GeoLite2数据库,但是它们的格式与xt_geoip_build脚本期望的格式不兼容。这就是GeoLite2xtables脚本的来源。为了使脚本起作用,请安装NetAddr :: IP perl模块:
wget https://cpan.metacpan.org/authors/id/M/MI/MIKER/NetAddr-IP-4.079.tar.gz
tar xvf NetAddr-IP-4.079.tar.gz
cd NetAddr-IP-4.079
perl Makefile.PL
make
make install
接下来,我们使用脚本克隆存储库,并将先前获得的许可证密钥写入文件:
git clone https://github.com/mschmitt/GeoLite2xtables.git
cd GeoLite2xtables
echo YOUR_LICENSE_KEY=\’123ertyui123\' > geolite2.license
我们启动脚本:
# GeoLite2
./00_download_geolite2
# ( )
./10_download_countryinfo
# GeoLite2 GeoLite Legacy
cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv |
./20_convert_geolite2 /tmp/CountryInfo.txt > /usr/share/xt_geoip/dbip-country-lite.csv
MaxMind每天限制下载2000次,并且由于服务器数量众多,可以在代理服务器上缓存更新。请注意,输出文件必须命名为dbip-country-lite.csv。不幸的是,20_convert_geolite2无法生成完美的文件。xt_geoip_build脚本需要三列:
- 地址范围的开始;
- 地址范围的结尾;
- iso-3166-alpha2中的国家/地区代码。
输出文件包含六列:
- 地址范围的开始(字符串表示形式);
- 地址范围的结尾(字符串表示形式);
- 地址范围的开始(数字);
- 地址范围的结尾(数字);
- 国家代码;
- 国家的名字。
这种差异非常关键,可以通过以下两种方式之一进行纠正:
- 编辑20_convert_geolite2 ;
- 编辑xt_geoip_build。
在第一种情况,我们缩写的printf为所需格式,并且在第二,我们改变了的分配$ CC变量到$行- > [4] 。之后,您可以构建:
/usr/lib/xtables-addons/xt_geoip_build -S /usr/share/xt_geoip/ -D /usr/share/xt_geoip
. . .
2239 IPv4 ranges for ZA
348 IPv6 ranges for ZA
56 IPv4 ranges for ZM
12 IPv6 ranges for ZM
56 IPv4 ranges for ZW
15 IPv6 ranges for ZW
请注意,GeoLite2xtables的作者不认为他的脚本可以投入生产,建议您遵循原始xt_geoip_ *脚本的开发。因此,让我们从源代码开始进行构建,其中这些脚本已经更新。
原始版本
从源代码安装时,xt_geoip_ *脚本位于/ usr / local / libexec / xtables-addons目录中。此版本的脚本使用IP至Country Lite数据库。许可证-知识共享署名许可证,根据可用数据,这是最必要的三列。下载并收集数据库:
cd /usr/share/xt_geoip/
/usr/local/libexec/xtables-addons/xt_geoip_dl
/usr/local/libexec/xtables-addons/xt_geoip_build
完成这些步骤后,iptables就可以使用了。
在iptables中使用geoip
xt_geoip 模块仅添加两个键:
geoip match options:
[!] --src-cc, --source-country country[,country...]
Match packet coming from (one of) the specified country(ies)
[!] --dst-cc, --destination-country country[,country...]
Match packet going to (one of) the specified country(ies)
NOTE: The country is inputed by its ISO3166 code.
iptables规则的形成方式通常保持不变。要使用来自其他模块的开关,必须使用-m开关明确指定模块名称。例如,一条规则阻止来自所有端口上非美国的端口443上的传入TCP连接:
iptables -I INPUT ! -i lo -p tcp --dport 443 -m geoip ! --src-cc US -j DROP
xt_geoip_build生成的文件仅在创建规则时使用,但不考虑进行过滤。因此,要正确更新geoip数据库,必须首先更新iv * -files,然后重新创建在iptables中使用geoip的所有规则。
结论
按国家/地区过滤数据包是一种被遗忘的策略。尽管如此,用于此类过滤的软件工具仍在开发中,也许不久之后,带有新geoip数据提供程序的xt_geoip的新版本将出现在程序包管理器中,这将大大简化系统管理员的工作。