Skip to main content

ubunru14.04统计所有连接IP及所属国家的脚本

在 Ubuntu 14.04 这种较老的系统上,要实现“IP 地址后显示国家”,最轻量且无需联网查询(速度快、不依赖外部 API)的方法是使用 geoip-bingeoip-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)
     ...

常见问题与优化

  1. 关于速度
    geoiplookup 是本地查询,速度非常快。但如果你的并发 IP 数量成千上万,while 循环可能会让脚本运行时间从几秒增加到几十秒。对于一般的服务器监控(几百个 IP),这个方法是完全可行的。

  2. 关于 127.0.0.1
    本地回环地址通常查不到国家,脚本中做了特殊处理显示为 Local/Private

  3. 定时任务无需修改
    你之前设置的 */10 19-22 * * * 依然有效,它会自动调用这个新版本的脚本。

  4. 数据库更新
    Ubuntu 14.04 自带的 GeoIP 数据库可能比较旧(截至 2014-2015 年)。如果需要非常精准的最新归属地,需要手动下载最新的 .dat 文件替换 /usr/share/geoip/GeoIP.dat,但在老系统上,自带库通常足够用于区分主要国家。