#!/bin/bash
##############################################################################
# 脚本名称: mtr_with_ip_location.sh
# 脚本功能: 执行MTR路由测试,并自动查询每个节点IP的属地信息
# 使用说明: ./脚本名 <目标IP>
# 依赖工具: mtr、curl、jq、iconv、awk、sed、grep
# 示例: ./mtr_with_ip_location.sh 23.95.215.199
# 注意事项:
# 1. 需确保能访问http://whois.pconline.com.cn(IP属地查询接口)
# 2. 执行时间取决于MTR节点数(每个节点curl超时60秒,默认重试3次)
##############################################################################
# ======================== 配置项 ========================
TARGET_IP="$1" # 目标IP(从参数传入)
CURL_TIMEOUT=10 # curl超时时间(缩短为10秒,原60秒过长)
CURL_RETRY=2 # curl重试次数
USER_AGENT="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"
LOG_FILE="/var/log/mtr_location.log" # 运行日志
# ======================== 日志函数 ========================
log() {
local level=$1
local msg=$2
echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$level] $msg" >> ${LOG_FILE}
}
# ======================== 随机生成合法IP(X-Forwarded-For) ========================
generate_random_ip() {
# 生成1-254之间的随机数(IP段合法范围)
local a=$((RANDOM % 254 + 1))
local b=$((RANDOM % 255))
local c=$((RANDOM % 255))
local d=$((RANDOM % 255))
echo "${a}.${b}.${c}.${d}"
}
# ======================== 查询IP属地 ========================
get_ip_location() {
local ip=$1
local random_ip=$(generate_random_ip)
local xff_header="X-Forwarded-For: ${random_ip}"
log "INFO" "查询IP ${ip} 的属地信息"
# 调用太平洋电脑网IP属地接口
local response=$(curl -m ${CURL_TIMEOUT} \
--retry ${CURL_RETRY} \
--header "${xff_header}" \
-A "${USER_AGENT}" \
-sLk -o - \
"http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=${ip}" 2>/dev/null)
# 处理响应:GBK转UTF-8 → jq解析 → 提取addr字段 → 清理特殊字符
local location=$(echo "${response}" | \
iconv -f gbk -t utf-8//IGNORE 2>/dev/null | \
jq -r '.addr // ""' 2>/dev/null | \
sed -e 's/[() ]//g' -e 's/[[:space:]]//g' 2>/dev/null)
# 容错:若查询失败,返回"未知属地"
if [[ -z "${location}" || "${location}" == "null" ]]; then
location="未知属地"
log "WARN" "IP ${ip} 属地查询失败,响应: ${response:0:100}..."
else
log "INFO" "IP ${ip} 属地: ${location}"
fi
echo "${location}"
}
# ======================== 参数校验 ========================
if [[ $# -ne 1 ]]; then
echo "用法: $0 <目标IP>"
echo "示例: $0 23.95.215.199"
exit 1
fi
# 校验目标IP格式
if ! echo "${TARGET_IP}" | egrep -q "^([0-9]{1,3}\.){3}[0-9]{1,3}$"; then
echo "错误:目标IP格式无效!"
exit 1
fi
# ======================== 执行MTR并解析 ========================
log "INFO" "开始执行MTR测试,目标IP: ${TARGET_IP}"
# 执行MTR(CSV格式、报告模式、数字格式)
mtr -C -r -n "${TARGET_IP}" 2>/dev/null | while read line; do
# 提取行中的IP地址
ip=$(echo "${line}" | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | head -n1)
if [[ -n "${ip}" ]]; then
# 有IP,查询属地并输出
location=$(get_ip_location "${ip}")
echo "${line} | 属地: ${location}"
else
# 无IP,直接输出原始行
echo "${line}"
fi
done
log "INFO" "MTR测试完成,目标IP: ${TARGET_IP}"
echo "MTR测试完成!详细日志请查看: ${LOG_FILE}"
命令行版本:
mtr -C -r -n 23.95.215.199 2>/dev/null |while read line;do npk="$(echo "$line" |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}")";if [ -n "$npk" ];then sdihepe="X-Forwarded-For: $(echo |awk -v A=$(date +%S%N) '{srand();a=int(A*rand())%254+1;srand();b=int(A*rand())%255+1;srand();c=int(A*rand())%253+1;srand();d=int(A*rand())%252+1;printf"%s.%s.%s.%s\n",a,b,c,d}')";ounerilesal="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36";roltsarsn="$(curl -m 60 --retry 3 --header "$sdihepe" -A "$ounerilesal" -sLk -o - "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=${npk}" |iconv -f gbk -t utf-8//IGNORE |jq . |awk -F'["]' '/"addr":/{gsub(" ","",$4);print $4}' |sed 's/)\|(//g')";echo "$line $roltsarsn";else echo "$line";fi;done
Categories:
系统运维