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

在 Ubuntu 14.04 这种较老的系统上，要实现“IP 地址后显示国家”，最轻量且无需联网查询（速度快、不依赖外部 API）的方法是使用 **`geoip-bin`** 和 **`geoip-database`**。

这将使用本地的 GeoIP 数据库进行匹配。

### 第一步：安装 GeoIP 工具库

请执行以下命令安装必要的包：

```bash
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` 编辑脚本：

```bash
nano /home/shuncom/iplist.sh

```

**将脚本内容完全替换为以下内容：**

```bash
#!/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`)。

### 第三步：赋予执行权限并测试

```bash
chmod +x /home/shuncom/iplist.sh

```

**手动运行一次测试效果：**

```bash
/home/shuncom/iplist.sh

```

然后查看生成的最新日志文件：

```bash
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

```

### 预期输出效果

修改后的日志文件内容将类似于：

```text
=== 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`，但在老系统上，自带库通常足够用于区分主要国家。