Linux服务器禁止国外IP访问方案

Linux服务器禁止国外IP访问

使用iptables+ipset实现

IPSET介绍

ipset 是一个用于在 Linux 系统中管理 IP 地址集合的工具,可以用于高效地创建、管理和检查 IP 集合。

基本命令结构

ipset [options] command [arguments]

Commands:

options arguments 描述
create SETNAME TYPENAME [type-specific-options] Create a new set
add SETNAME ENTRY Add entry to the named set
del SETNAME ENTRY Delete entry from the named set
test SETNAME ENTRY Test entry in the named set
destroy [SETNAME] Destroy a named set or all sets
list [SETNAME] List the entries of a named set or all sets
save [SETNAME] Save the named set or all sets to stdout
restore Restore a saved state
flush [SETNAME] Flush a named set or all sets
rename FROM-SETNAME TO-SETNAME Rename two sets
swap FROM-SETNAME TO-SETNAME Swap the contect of two existing sets
help [TYPENAME] Print help, and settype specific help
version Print version information
quit Quit interactive mode

常用命令和参数

创建集合

ipset create setname typename options

  • setname: 集合的名称。
  • typename: 集合的类型,例如 hash:ip、hash:net、hash:ip,port 等。
  • [options]: 其他可选参数,例如 family、hashsize、maxelem。
  • 示例: 创建一个名为 myset 的集合;类型为 hash:net;地址族为 inet (IPv4);初始哈希表大小为 1024;最大元素数量为 65536。
ipset create myset hash:net family inet hashsize 1024 maxelem 65536

添加元素

ipset add setname element

  • setname: 集合的名称。
  • element: 要添加的元素,例如 IP 地址或子网。
  • 示例:
ipset add myset 192.168.1.0/24

删除元素

ipset del setname element

  • setname: 集合的名称。
  • element: 要添加的元素,例如 IP 地址或子网。
  • 示例:
ipset del myset 192.168.1.0/24

销毁集合

ipset destroy setname

  • setname: 集合的名称。

  • 示例: 销毁名为 myset 的集合。

ipset destroy myset

保存集合

ipset save [setname]

  • setname: 可选,集合的名称。如果不指定,将保存所有集合。

  • 示例:

ipset save > /etc/ipset.rules 

恢复集合

  • 示例: 从保存的文件恢复集合
ipset restore  < /etc/ipset.rules 

列出集合

ipset list [setname]

  • setname: 可选,集合的名称。如果不指定,将列出所有集合所有元素。

  • 示例: 列出名为 myset 的集合中的所有元素

ipset list myset

常用参数:

参数名 描述
family 指定地址族,inet 表示 IPv4,inet6 表示 IPv6。
hashsize 指定哈希表的初始大小。
maxelem 指定集合中允许的最大元素数量。
timeout 为集合中的元素指定超时时间(以秒为单位)。
counters 启用计数器,用于统计匹配次数。
comment 启用注释功能,为元素添加注释。
skbinfo 保存匹配的报文的元数据信息(例如接口索引、队列号)。

持久化ipset数据

systemd 方式实现规则数据持久化,避免重启后ipset数据丢失

  • 新增持久化保存集合脚本:/usr/local/bin/ipset-save.sh
#!/bin/bash
ipset save > /etc/ipset.rules
  • 新增恢复集合脚本:/usr/local/bin/ipset-restore.sh
#!/bin/bash
ipset restore < /etc/ipset.rules
  • 新增systemd 服务单元文件: /etc/systemd/system/ipset.service
[Unit]
Description=Restore ipset rules
Before=network-pre.target
Wants=network-pre.target
Requires=local-fs.target
After=local-fs.target


[Service]
Type=oneshot
ExecStart=/usr/local/bin/ipset-restore.sh
ExecReload=/usr/local/bin/ipset-restore.sh
ExecStop=/usr/local/bin/ipset-save.sh
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

保存并退出编辑器。然后,重新加载 systemd 配置并启动服务(修改systemd文件需重新执行下面命令):

sudo systemctl daemon-reload
sudo systemctl enable ipset.service
sudo systemctl start ipset.service

验证服务状态

sudo systemctl status ipset.service

重启(reboot)并验证:

sudo ipset list

iptables介绍:

iptables 是一个用于配置 Linux 内核中内置的 IP 包过滤规则的工具。
它是 Linux 系统中强大的防火墙工具,用于控制网络流量的传输。
iptables 提供了用户空间命令行接口,用于与内核空间中的 netfilter 子系统交互。

基本概念

表(Tables): iptables 规则被组织到不同的表中,每个表用于不同类型的操作。常见的表有:

    filter 表:这是默认表,包含用于过滤数据包的规则。它包含 INPUT、FORWARD 和 OUTPUT 链。
    nat 表:用于网络地址转换(Network Address Translation),包含 PREROUTING、POSTROUTING 和 OUTPUT 链。
    mangle 表:用于修改数据包的头部,包含 PREROUTING、POSTROUTING、INPUT、FORWARD 和 OUTPUT 链。
    raw 表:用于配置不进行连接跟踪的规则,包含 PREROUTING 和 OUTPUT 链。
------------------------------------------------------------------------------------------------------    
    
链(Chains): 每个表包含若干链,链是有序的规则列表。常见的链有:

    INPUT:处理进入本地系统的数据包。
    FORWARD:处理转发的数据包。
    OUTPUT:处理从本地系统发出的数据包。
    PREROUTING:在数据包路由决策之前处理数据包。
    POSTROUTING:在数据包路由决策之后处理数据包。
------------------------------------------------------------------------------------------------------

规则(Rules): 每个链包含若干规则,规则定义了匹配条件和相应的动作(目标)。当数据包匹配规则时,执行相应的动作。
      

------------------------------------------------------------------------------------------------------
目标(Targets): 目标定义了当规则匹配时应采取的动作。常见的目标有:

    ACCEPT:接受数据包。
    DROP:丢弃数据包。
    REJECT:拒绝数据包并发送错误响应。
    LOG:记录数据包信息到系统日志。
# 查询当前的 iptables 规则 
iptables -L -n -v   

# 允许 TCP 流量到端口 80(HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 拒绝所有 ICMP 数据包(例如 ping 请求)
iptables -A INPUT -p icmp -j DROP

# 允许从特定 IP 地址的 SSH 连接(例如允许来自 192.168.1.100 的 SSH 连接)
iptables -A INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 134.160.154.41 -p tcp --dport 6001 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 6001  -j ACCEPT

# 默认拒绝所有其他输入流量(通常放在规则列表的最后):
iptables -P INPUT DROP

#----------------------------------------------------------------------------------------------------------

# 使用-A(追加)和-I(插入):
# -A(追加)命令将规则添加到链的末尾。
# -I(插入)命令允许你将规则插入到链的指定位置,但位置是基于规则编号的,而不是基于你定义的某种顺序。默认情况下,如果你不提供编号,-I会将规则插入到链的开头。
# 例如,要将规则插入到INPUT链的第二条位置,你可以这样做:
iptables -I INPUT 2 -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT 13 -s 134.160.154.41  -p tcp --dport 6001 -m state --state NEW -j ACCEPT

# 按行号删除规则:
# 如果你知道要删除的规则的行号(使用 iptables -L -n --line-numbers 可以查看带行号的规则列表),你可以使用 -D 选项和行号来删除它。例如,要删除行号为 3 的规则,你可以执行:
iptables -D INPUT 3

# 按匹配条件删除规则:
# 例如,要删除所有允许来自 IP 地址 192.168.1.100 的流量的 INPUT 链规则,你可以执行:
iptables -D INPUT -s 192.168.1.100 -j ACCEPT


持久化iptables规则数据

systemd 方式实现规则数据持久化,避免重启后iptables规则数据丢失

  • 新增持久化保存规则脚本:/usr/local/bin/iptables-save-rules.sh
#!/bin/bash
iptables-save > /etc/iptables/rules.v4
  • 新增恢复规则脚本:/usr/local/bin/iptables-restore-rules.sh
#!/bin/bash
iptables-restore < /etc/iptables/rules.v4
  • 新增systemd服务单元规则持久化文件: /etc/systemd/system/iptables-save.service
[Unit]
Description=Save iptables rules
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/iptables-save-rules.sh
RemainAfterExit=true

[Install]
WantedBy=halt.target reboot.target shutdown.target

保存并退出编辑器。然后,重新加载 systemd 配置并启动服务(修改systemd文件需重新执行下面命令):

sudo systemctl daemon-reload
sudo systemctl enable iptables-save.service 
sudo systemctl start iptables-save.service 
  • 新增systemd服务单元规则恢复文件: /etc/systemd/system/iptables-restore.service
[Unit]
Description=Restore iptables rules
Before=network-pre.target
Wants=network-pre.target
Requires=local-fs.target
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/iptables-restore-rules.sh
ExecReload=/usr/local/bin/iptables-restore-rules.sh
#ExecStop=/usr/local/bin/iptables-save-rules.sh
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

保存并退出编辑器。然后,重新加载 systemd 配置并启动服务(修改systemd文件需重新执行下面命令):

sudo systemctl daemon-reload
sudo systemctl enable iptables-restore.service 
sudo systemctl start iptables-restore.service 

验证服务状态

sudo systemctl status iptables-save.service 
sudo systemctl status iptables-restore.service 

重启(reboot)并验证:

sudo iptables -L

iptables使用ipset:

特别须知: 使用集合控制时注意规则是否会阻止回环地址(127),ssh等管理,避免被拦截后无法正常远程管理

  • 添加匹配在ipset集合中的允许规则:
sudo iptables -I INPUT 3 -m set --match-set cnip src -j ACCEPT
  • 添加匹配不在ipset集合中的阻止规则:
sudo iptables -I INPUT 3 -m set ! --match-set cnip src -j DROP

获取中国IP子网分配


# 下载 APNIC 最新 IP 地址分配数据
curl https://ftp.apnic.net/stats/apnic/delegated-apnic-latest -O delegated-apnic-latest

# 提取所有中国的 IPv4 地址块并添加到 ipset 集合
grep '|CN|ipv4|' delegated-apnic-latest | while IFS='|' read -r registry cc type start_ip count date status
do
    ip_prefix="$start_ip/$(awk -v n=$count 'BEGIN {print 32-log(n)/log(2)}')"
    sudo echo $ip_prefix >> ./cnip_list
done


APNIC数据说明:

例: apnic|CN|ipv4|222.240.0.0|524288|20040326|allocated

注册机构(apnic):

表示该记录来自哪个互联网号码分配机构。apnic 代表亚太网络信息中心(Asia-Pacific Network Information Centre)。
国家代码(CN):

表示该 IP 地址块的分配国家。CN 代表中国。
地址类型(ipv4):

表示地址类型,这里是 ipv4。对于 IPv6 地址,值为 ipv6。
起始地址(222.240.0.0):

表示 IP 地址块的起始地址。
地址数(524288):

表示该记录中包含的地址数量。例如,524288 表示这个块包含 524,288 个连续的 IP 地址。
分配日期(20040326):

表示该地址块的分配日期,格式为 YYYYMMDD。这里是 2004 年 3 月 26 日。
状态(allocated):

表示该地址块的当前状态。allocated 表示地址块已经分配出去。其他可能的状态包括 assigned(分配给最终用户)和 available(可用的)。
解析地址块
对于起始 IP 地址 222.240.0.0 和地址数量 524288,我们需要计算子网掩码和地址块范围。524288 个地址相当于 2^19,所以掩码将是 /13(因为 32 - 19 = 13)。

地址块范围
起始地址:222.240.0.0
结束地址:222.247.255.255
  • 创建ipset集合cnip:
create cnip hash:net family inet hashsize 16384 maxelem 1000000
  • 创建添加数据到cnip集合脚本(赋予执行权限并执行):
#!/bin/bash
ipset create cnip hash:net family inet hashsize 16384 maxelem 1000000
for i in `cat cnip_list` 
do  ipset add cnip $i
done

建议把局域网IP端默认都加到cnip集合中,避免无法远程控制

ipset add cnip 10.0.0.0/8
ipset add cnip 192.0.0.0/8
ipset add cnip 172.0.0.0/8
  • 查看cnip集合数据:
ipset list cnip
  • 添加iptables规则(前置特定规则避免集合规则导致无法远程管理):
# 防火墙: 运行回环地址规则
sudo iptables -I INPUT 1 -s 127.0.0.1/32    -j ACCEPT
# 防火墙: 允许本地局域网访问规则
sudo iptables -I INPUT 2 -s 10.0.1.0/24    -j ACCEPT
# 防火墙: 允许特定ip访问规则
sudo iptables -I INPUT 3 -s 222.246.123.123 -j ACCEPT
# 防火墙: cnip 集合规则(阻止源IP不在cnip集合规则中的访问)
sudo iptables -I INPUT 4 -m set ! --match-set cnip src -j DROP
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容