根据IP所属的国家地区限制对Linux的访问


环境:Ubuntu 20.04 LTS

一、安装必备软件

sudo apt update
sudo apt upgrade -y
sudo apt install curl perl unzip xtables-addons-common libtext-csv-xs-perl libmoosex-types-netaddr-ip-perl

二、下载国家IP数据库

创建保存数据的目录:

sudo mkdir -p /usr/share/xt_geoip

创建一个位于 /usr/local/bin/update-geoip.sh 的脚本用于下载和更新数据库,并将下面的内容拷贝到脚本中:

#!/bin/bash

set -ex

# Create temporary directory
mkdir -p /usr/share/xt_geoip/tmp/
mkdir -p /usr/share/xt_geoip/tmp/ip2loc/

# Download latest from db-ip.com
cd /usr/share/xt_geoip/tmp/
/usr/lib/xtables-addons/xt_geoip_dl

# Download maxmind legacy csv and process
wget https://mailfud.org/geoip-legacy/GeoIP-legacy.csv.gz -O /usr/share/xt_geoip/tmp/GeoIP-legacy.csv.gz
gunzip /usr/share/xt_geoip/tmp/GeoIP-legacy.csv.gz
cat /usr/share/xt_geoip/tmp/GeoIP-legacy.csv | tr -d '"' | cut -d, -f1,2,5 > /usr/share/xt_geoip/tmp/GeoIP-legacy-processed.csv
rm /usr/share/xt_geoip/tmp/GeoIP-legacy.csv
rm /usr/share/xt_geoip/tmp/GeoIP-legacy.csv.gz

# Download latest from https://github.com/sapics/ip-location-db
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/geo-whois-asn-country/geo-whois-asn-country-ipv4.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/geo-whois-asn-country/geo-whois-asn-country-ipv6.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/iptoasn-country/iptoasn-country-ipv4.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/iptoasn-country/iptoasn-country-ipv6.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/dbip-country/dbip-country-ipv4.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/dbip-country/dbip-country-ipv6.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/geolite2-country/geolite2-country-ipv4.csv
wget -P /usr/share/xt_geoip/tmp/ https://cdn.jsdelivr.net/npm/@ip-location-db/geolite2-country/geolite2-country-ipv6.csv

# Combine all csv and remove duplicates
cd /usr/share/xt_geoip/tmp/
cat *.csv > geoip.csv
sort -u geoip.csv -o /usr/share/xt_geoip/dbip-country-lite.csv

# Remove temp directory and update geoip xtables
rm -r /usr/share/xt_geoip/tmp/
chmod +x /usr/lib/xtables-addons/xt_geoip_build
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip/ -S /usr/share/xt_geoip/
rm /usr/share/xt_geoip/dbip-country-lite.csv

# reload ufw
# ufw reload

给与脚本可执行权限,并执行:

sudo chmod +x /usr/local/bin/update-geoip.sh
/usr/local/bin/update-geoip.sh

三、配置并开启 UFW 防火墙

根据实际的需要在 /etc/ufw/before.rules/etc/ufw/before6.rules 这两个文件中添加 iptables 规则。

/etc/ufw/before.rules 用于控制 ipv4 。 /etc/ufw/before6.rules 用于控制 ipv6 。

下面以需求 禁止非中国的 IP 连接 SSH 为例,配置 UFW 。

  1. 允许 SSH 通过 UFW

    sudo ufw allow ssh

    如果 ssh 是其他的端口,比如 6666 ,可以使用命令 sudo ufw allow 6666/tcp

  2. 禁止非中国的 IP 连接 SSH

    1. 修改控制 ipv4 的文件 /etc/ufw/before.rules

      + # block all countries except china ssh connection
      + -A ufw-before-input -p tcp --dport 22 -m geoip ! --src-cc CN -j DROP
      
      # don't delete the 'COMMIT' line or these rules won't be processed
      COMMIT
    2. 修改控制 ipv6 的文件 /etc/ufw/before6.rules

      + # block all countries except china ssh connection
      + -A ufw6-before-input -p tcp --dport 22 -m geoip ! --src-cc CN -j DROP
      
      # don't delete the 'COMMIT' line or these rules won't be processed
      COMMIT

      修改中的 CN 表示 China,即中国地区。所有的国家地区的缩写可以在 https://www.iso.org/obp/ui/ 或者 https://shorewall.org/ISO-3661.html 中找到。

  3. 开机自启动并开启 UFW

    sudo systemctl enable ufw
    sudo systemctl start ufw

    注意:添加限制以后,UFW 会将阻止的 IP 访问记录到日志文件 /var/log/ufw.logdmesg 命令中。因为默认的 UFW 的日志记录配置是 low (可以通过命令 sudo ufw status verbose 查看当前的日志配置登记),可以通过命令 sudo ufw logging off 来关闭日志记录。

四、参考资料

  1. Geo Blocking With UFW / IPTables
  2. Block SSH access from specific countries
  3. The geoip match HOWTO
  4. ISO 3661 Country Codes recognized by Shorewall
  5. Is there a way to keep UFW logging out of dmesg?

文章作者: Kiba Amor
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 Kiba Amor !
  目录