Appearance
Linux 怎么查 IP 归属地?一条命令加一个函数,日志排查看 IP 全靠它
敲一句 curl 就能在终端查 IP 归属地,不用开浏览器。但只停在"能查"不够——封装成 shell 函数,日志里揪出的 IP 挨个过、封禁前先看对方在哪个地区,几秒搞定。Ubuntu/Debian/CentOS 通用。
一、Linux 上什么时候要查 IP 归属地
说三个最常碰到的场景:
- SSH 爆破溯源。
/var/log/auth.log里全是 Failed password,来源 IP 一大串。逐个查归属地,发现都来自同一家海外机房——直接防火墙封段。 - Nginx 访问日志异常。某个 IP 疯狂刷接口,查归属地是住宅宽带还是机房再决定封不封:机房 IP 直接封误伤率低,住宅 IP 可能是真人,先观察。
- 多台服务器溯源。某台机器被攻击,登录先确认攻击来源是不是同事的出口 IP(分公司专线之类),查归属地 + 运营商比翻工单快。
人在终端里,不想为查个 IP 开网页、复制粘贴。命令行直接出结果,才能跟 grep、awk 串成流水线。
二、方案设计:免费接口 + curl + 一个解析函数
查询走 IP9 免费接口 https://ip9.com.cn/get?ip=<ip>,免注册、免 key,返回 JSON 含国家、省份、城市、运营商等字段,限速 60 次/分钟/IP,排查够用。
curl 直接返回 JSON,但一长串 {"country":"中国","prov":"广东"...} 在终端里不好读,所以拆两层:查询层用 curl 拿 JSON,展示层用 python3 解析排版(系统自带 python3,比 jq 稳)。两层包进 shell 函数 ipinfo,写进 ~/.bashrc 就能天天用。单条命令解决"查一次",函数解决"天天查"。
三、Shell 实现:一条命令 + 一个函数
先看裸命令:
bash
curl -s "https://ip9.com.cn/get?ip=114.114.114.114"JSON 里的 data 就是归属地结果。把它封装成函数,追加到 ~/.bashrc 末尾:
bash
# ipinfo —— 查 IP 归属地;ipinfo [ip],不传 ip 查本机出口
ipinfo() {
local ip="${1:-}"
local url="https://ip9.com.cn/get"
[ -n "$ip" ] && url="$url?ip=$ip"
local json
json=$(curl -s --max-time 5 "$url") || { echo "请求失败:网络不通或超时"; return 1; }
# python3 只负责解析排版
echo "$json" | python3 -c '
import sys, json
try:
j = json.load(sys.stdin)
except Exception:
print("返回的不是合法 JSON,可能被限流"); sys.exit(1)
if j.get("ret") != 200:
ret = j.get("ret")
print("查询失败 ret=" + str(ret) + "(400 格式非法,429 超限速)"); sys.exit(1)
d = j["data"]
loc = (d.get("country","") + " " + d.get("prov","") + " " + d.get("city","")).strip()
print("IP: " + d.get("ip",""))
print("归属地: " + loc)
print("运营商: " + d.get("isp",""))
print("经纬度: " + str(d.get("lat")) + ", " + str(d.get("lng")) + " (城市中心点)")
'
}
# iplog —— 从日志文件批量查 IP,自动去重 + 限速
iplog() {
local file="$1"
[ -z "$file" ] && { echo "用法: iplog /var/log/auth.log"; return 1; }
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$file" \
| sort | uniq -c | sort -rn | head -20 \
| while read -r cnt ip; do
printf "次数%-5s " "$cnt"
ipinfo "$ip" | sed -n '1,3p' | tr '\n' ' '
echo
sleep 1 # 免费版 60 次/分钟,必须限速
done
}source ~/.bashrc 后就能用:
bash
ipinfo # 查本机出口 IP 归属地
ipinfo 8.8.8.8 # 查指定 IP
iplog /var/log/auth.log # SSH 日志里最活跃的 20 个 IP 及其归属地输出:
text
次数 12 IP: 103.xxx.xxx.xxx 归属地: 中国 香港 运营商: 某某数据中心全是机房段,直接 iptables 封段或丢给 fail2ban。想确认是不是机房 IP,IP9 的 VIP 版多返回 ip_type(ISP 家庭/BUS 企业/IDC 机房)和 ip_asn;免费版先用省市 + 运营商判断也够。
四、落地注意事项
实操中容易踩的坑:
- 限速别踩:免费版 60 次/分钟/IP,
iplog已加sleep 1;自己写循环批量查几百个 IP,间隔至少 1 秒,否则撞ret=429。 - 分清内外网:
ip addr看到的是内网地址,直接查会得到"保留地址"之类的无效结果;函数不传参时返回的才是真实出口。 - 超时兜底:curl 带
--max-time 5,接口抽风不会挂死终端;函数对非 200、非 JSON 都有提示。 - 经纬度是城市中心:接口返回的经纬度是城市中心点坐标,大致标注可以,别当精确位置用。
- 别在生产脚本里裸奔:这是排查工具。上生产风控要把查询服务化、加缓存,别让业务请求直连第三方接口。
总结
把"查 IP 归属地"从"打开网页复制粘贴"变成终端里的一条命令、一个函数,日志溯源和封禁决策会顺手很多。核心就两步:curl 请求 https://ip9.com.cn/get?ip=<ip>,python3 把 JSON 排成好读的几行。函数放进 ~/.bashrc,SSH 爆破、爬虫乱爬、异常流量,来一个查一个。免费版够日常排查,要机房类型和 ASN 判断就看官网 https://www.ip9.com.cn 的 VIP 说明。