ubunru14.04统计所有连接IP及所属国家的脚本
在 Ubuntu 14.04 这种较老的系统上,要实现“IP 地址后显示国家”,最轻量且无需联网查询(速度快、不依赖外部 API)的方法是使用 geoip-bin 和 geoip-database。
这将使用本地的 GeoIP 数据库进行匹配。
第一步:安装 GeoIP 工具库
请执行以下命令安装必要的包:
sudo apt-get update
sudo apt-get install -y geoip-bin geoip-database
注:geoip-bin 包含 geoiplookup 命令,geoip-database 包含免费的 GeoIP Country 数据库。
第二步:修改脚本 /home/shuncom/iplist.sh
我们需要修改脚本,在统计出 IP 和数量后,循环读取每一行,查询国家代码并追加到后面。
请使用 nano 编辑脚本:
nano /home/shuncom/iplist.sh
将脚本内容完全替换为以下内容:
#!/bin/bash
# 定义变量
LOG_DIR="/home/shuncom/iplist"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
LOG_FILE="${LOG_DIR}/iplist-${TIMESTAMP}.log"
GEOIP_CMD="geoiplookup"
# 确保日志目录存在
if [ ! -d "$LOG_DIR" ]; then
mkdir -p "$LOG_DIR"
fi
# 检查 geoiplookup 是否安装
if ! command -v $GEOIP_CMD &> /dev/null; then
echo "Error: geoip-bin not installed. Please run: sudo apt-get install geoip-bin"
# 即使没安装也生成日志,但标记错误
echo "=== IP Connection Statistics (GeoIP Missing) ===" > "$LOG_FILE"
echo "Generated at: $(date)" >> "$LOG_FILE"
echo "ERROR: geoiplookup command not found." >> "$LOG_FILE"
exit 1
fi
# 生成临时文件用于处理
TEMP_FILE=$(mktemp)
# 1. 获取网络连接统计
# 使用 netstat 或 ss
if command -v netstat &> /dev/null; then
netstat -ntu 2>/dev/null | awk '{print $5}' | cut -d: -f1 | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | sort | uniq -c | sort -nr > "$TEMP_FILE"
elif command -v ss &> /dev/null; then
ss -ntu 2>/dev/null | awk '{print $5}' | cut -d: -f1 | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | sort | uniq -c | sort -nr > "$TEMP_FILE"
else
echo "Error: Neither netstat nor ss found." > "$LOG_FILE"
exit 1
fi
# 2. 写入日志头部
echo "=== IP Connection Statistics with Country ===" > "$LOG_FILE"
echo "Generated at: $(date)" >> "$LOG_FILE"
echo "Format: Count IP_ADDRESS (COUNTRY_CODE)" >> "$LOG_FILE"
echo "-------------------------------" >> "$LOG_FILE"
# 3. 逐行读取统计结果,查询国家并写入日志
# 读取格式:空格+数量 空格+IP
while read -r count ip; do
# 跳过空行
if [ -z "$ip" ]; then continue; fi
# 查询国家 (geoiplookup 返回类似: GeoIP Country Edition: US, United States)
# 我们只提取国家代码 (US, CN, etc.)
country_info=$($GEOIP_CMD "$ip" 2>/dev/null)
# 解析国家代码 (提取冒号后的第一个单词,通常是代码)
# 示例输出: GeoIP Country Edition: US, United States
if ; then
country_code=$(echo "$country_info" | sed 's/.*GeoIP Country Edition: \([A-Z][A-Z]\).*/\1/')
country_name=$(echo "$country_info" | sed 's/.*GeoIP Country Edition: [A-Z][A-Z], \(.*\)/\1/')
output_line="$(printf '%6s' $count) $ip ($country_code - $country_name)"
else
# 如果查询失败或本地回环
output_line="$(printf '%6s' $count) $ip (Unknown - Local/Private)"
fi
echo "$output_line" >> "$LOG_FILE"
done < "$TEMP_FILE"
# 清理临时文件
rm -f "$TEMP_FILE"
echo "Log created: $LOG_FILE"
保存并退出 (Ctrl+O, Enter, Ctrl+X)。
第三步:赋予执行权限并测试
chmod +x /home/shuncom/iplist.sh
手动运行一次测试效果:
/home/shuncom/iplist.sh
然后查看生成的最新日志文件:
ls -lt /home/shuncom/iplist/ | head -n 2
# 假设最新文件是 iplist-2026-03-12_18-00-01.log (请替换为你实际的文件名)
cat /home/shuncom/iplist/iplist-*.log | tail -n 20
预期输出效果
修改后的日志文件内容将类似于:
=== IP Connection Statistics with Country ===
Generated at: Thu Mar 12 18:00:01 ICT 2026
Format: Count IP_ADDRESS (COUNTRY_CODE - Country Name)
-------------------------------
369 127.0.0.1 (Unknown - Local/Private)
108 119.59.98.80 (CN - China)
49 45.140.17.97 (NL - Netherlands)
30 45.140.17.26 (NL - Netherlands)
5 49.237.44.244 (TH - Thailand)
5 223.24.143.8 (CN - China)
...
常见问题与优化
-
关于速度:
geoiplookup是本地查询,速度非常快。但如果你的并发 IP 数量成千上万,while循环可能会让脚本运行时间从几秒增加到几十秒。对于一般的服务器监控(几百个 IP),这个方法是完全可行的。 -
关于 127.0.0.1:
本地回环地址通常查不到国家,脚本中做了特殊处理显示为Local/Private。 -
定时任务无需修改:
你之前设置的*/10 19-22 * * *依然有效,它会自动调用这个新版本的脚本。 -
数据库更新:
Ubuntu 14.04 自带的 GeoIP 数据库可能比较旧(截至 2014-2015 年)。如果需要非常精准的最新归属地,需要手动下载最新的.dat文件替换/usr/share/geoip/GeoIP.dat,但在老系统上,自带库通常足够用于区分主要国家。
No Comments