CentOS7 ipset + iptables限制国外IP访问
CentOS7 ipset + iptables限制国外IP访问
ipset -version
yum install -y ipset wget
优化核心参数
vi /etc/sysctl.conf
vm.swappiness=0
net.ipv4.tcp_max_tw_buckets=5000
# 文件句柄上限
fs.file-max = 1048576
# TCP基础优化
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# 后端出站临时端口范围
net.ipv4.ip_local_port_range = 1024 65535
# nftables conntrack 10W并发预留2倍以上容量
net.netfilter.nf_conntrack_max = 1310720
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 15
# 连接队列扩容
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TCP缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
echo "nf_conntrack" >> /etc/modules-load.d/netfilter.conf
echo "nf_conntrack_ipv4" >> /etc/modules-load.d/netfilter.conf
modprobe nf_conntrack
modprobe nf_conntrack_ipv4
sysctl -p
# 修改系统文件句柄限制
vi /etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
root soft nofile 1048576
root hard nofile 1048576
mkdir -p /opt/ipset/
touch /opt/ipset/manual_white.txt
加载iptables规则
[root@nftables-test ~]# cat install_ipset.sh
#!/bin/bash
BASE_DIR=/opt/ipset
CACHE_CIDR=${BASE_DIR}/china_ip.txt
WHITE_FILE=${BASE_DIR}/manual_white.txt
FIXED_WHITE=(
"192.168.0.0/16"
"172.30.0.0/16"
"10.0.0.0/8"
)
# 缓存时间,7天更新一次
CACHE_TTL=$((7*24*3600))
log()
{
echo "$(date '+%F %T') $1"
}
mkdir -p $BASE_DIR
#################################################
# 下载中国IP段
#################################################
NEED_DOWNLOAD=true
if [ -s "$CACHE_CIDR" ]; then
FILE_TIME=$(stat -c %Y "$CACHE_CIDR")
NOW=$(date +%s)
AGE=$((NOW - FILE_TIME))
if [ "$AGE" -lt "$CACHE_TTL" ]; then
log "本地CIDR缓存有效,已经 $((AGE/3600)) 小时,跳过下载"
NEED_DOWNLOAD=false
fi
fi
if [ "$NEED_DOWNLOAD" = true ]; then
log "开始从APNIC下载中国IPv4网段"
TMP_FILE=${CACHE_CIDR}.tmp
if wget --timeout=60 -q -O- \
'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' \
| awk -F\| '/CN\|ipv4/ {
printf("%s/%d\n",$4,32-log($5)/log(2))
}' > $TMP_FILE
then
# 防止空文件覆盖
if [ -s "$TMP_FILE" ]; then
mv $TMP_FILE $CACHE_CIDR
log "中国CIDR更新成功"
else
rm -f $TMP_FILE
log "下载结果为空,继续使用旧缓存"
fi
else
rm -f $TMP_FILE
log "APNIC下载失败,继续使用旧缓存"
fi
fi
if [ ! -s "$CACHE_CIDR" ]; then
log "错误:中国CIDR文件不存在"
exit 1
fi
#################################################
# 创建ipset
#################################################
create_set()
{
SET_NAME=$1
ipset list -n | grep -w "$SET_NAME" >/dev/null
if [ $? -ne 0 ]; then
ipset create \
$SET_NAME \
hash:net \
family inet \
hashsize 65536 \
maxelem 200000
else
ipset flush $SET_NAME
fi
}
create_set china_net
create_set fixed_white
create_set manual_white
#################################################
# 导入固定白名单
#################################################
log "加载固定白名单"
for ip in ${FIXED_WHITE[@]}
do
ipset add fixed_white $ip -exist
done
#################################################
# 导入中国CIDR
#################################################
log "加载中国IP网段"
while read ip
do
[[ -z "$ip" ]] && continue
[[ "$ip" =~ ^# ]] && continue
ipset add china_net $ip -exist
done < $CACHE_CIDR
#################################################
# 导入手工白名单
#################################################
if [ -f "$WHITE_FILE" ]; then
log "加载手工白名单"
while read ip
do
[[ -z "$ip" ]] && continue
[[ "$ip" =~ ^# ]] && continue
ipset add manual_white $ip -exist
done < $WHITE_FILE
fi
#################################################
# 保存ipset
#################################################
ipset save > /etc/sysconfig/ipset
#################################################
# iptables规则
#################################################
iptables -N CHINA_FILTER 2>/dev/null
iptables -F CHINA_FILTER
# 放行必要端口
iptables -A CHINA_FILTER \
-m conntrack --ctstate ESTABLISHED,RELATED \
-j ACCEPT
# 本机回环
iptables -A CHINA_FILTER \
-i lo \
-j ACCEPT
# ICMP
iptables -A CHINA_FILTER \
-p icmp \
-j ACCEPT
# 固定白名单
iptables -A CHINA_FILTER \
-m set --match-set fixed_white src \
-j ACCEPT
# 手工白名单
iptables -A CHINA_FILTER \
-m set --match-set manual_white src \
-j ACCEPT
# 中国IP
iptables -A CHINA_FILTER \
-m set --match-set china_net src \
-j ACCEPT
# 默认拒绝
iptables -A CHINA_FILTER \
-j DROP
# INPUT挂载
iptables -C INPUT -j CHINA_FILTER 2>/dev/null
if [ $? -ne 0 ];then
iptables -I INPUT 1 -j CHINA_FILTER
fi
#service iptables save
#################################################
# 输出统计
#################################################
log "更新完成"
echo "放行中国IP网段数量:"
ipset list china_net | grep "Number of entries"
echo "手动白名单IP网段数量:"
ipset list manual_white | grep "Number of entries"
echo "固定白名单网段数量:"
ipset list fixed_white | grep "Number of entries"
手动加载部分
配置手动白名单
vi /opt/ipset/manual_white.txt
[root@nftables-test ~]# cat reload_manual_white.sh
#!/bin/bash
WHITE_FILE=/opt/ipset/manual_white.txt
if [ ! -f "$WHITE_FILE" ];then
echo "文件不存在:$WHITE_FILE"
exit 1
fi
echo "刷新手工白名单"
ipset flush manual_white
while read ip
do
[[ -z "$ip" ]] && continue
[[ "$ip" =~ ^# ]] && continue
ipset add manual_white $ip -exist
done < $WHITE_FILE
ipset save > /etc/sysconfig/ipset
echo "完成"
ipset list manual_white | grep "Number"
# 执行
chmod +x reload_manual_white.sh
./reload_manual_white.sh
运维操作
查看所有规则和命中数量
[root@nftables-test ~]# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2346 198K CHINA_FILTER all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 258 packets, 35392 bytes)
pkts bytes target prot opt in out source destination
Chain CHINA_FILTER (1 references)
pkts bytes target prot opt in out source destination
449 29868 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
142 14659 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 match-set fixed_white src
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 match-set manual_white src
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 match-set china_net src
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
查看全部的ipset列表
# 查看所有的ipset列表
ipset list -n
ipset list china_net
全部放行兜底
清理全部规则
iptables -F

浙公网安备 33010602011771号