IP 資訊查詢
查詢 IP 位址的地理位置、ISP、ASN 等詳細資訊
IPv4 與 IPv6:為何需要 IPv6?
IPv4(1981 年)
格式:4 組十進位數字(如 192.168.1.1)
總數:約 43 億個位址(2³² = 4,294,967,296)
問題:位址已接近枯竭,早在 2011 年就已分配完畢
長度:32 位
IPv6(1998 年)
格式:8 組十六進位數(如 2001:0db8::1)
總數:約 340 萬億億億億個位址(2¹²⁸)
優勢:位址數量幾乎無限,足夠分配給地球上的每一粒沙子
長度:128 位
為什麼 IPv4 不夠用?
- • 全球人口 80 億,每人至少有 2-3 台裝置(手機、電腦、平板)
- • 物聯網裝置爆發式增長(智慧家居、汽車、穿戴式裝置)
- • 企業與資料中心需要大量 IP 位址
- • 早期分配不合理(例如 MIT 擁有 1600 萬個 IP)
特殊 IP 位址段
迴圈位址(Loopback)
127.0.0.0/8(127.0.0.1 - 127.255.255.255)
用於本機測試,資料不會發送到網路,常用 127.0.0.1 表示 localhost
用途:測試本機服務、開發除錯
私有位址(Private)
- 10.0.0.0/8(10.0.0.0 - 10.255.255.255)- A 類
- 172.16.0.0/12(172.16.0.0 - 172.31.255.255)- B 類
- 192.168.0.0/16(192.168.0.0 - 192.168.255.255)- C 類
用於區域網路內部,無法直接存取互聯網,需透過 NAT 轉換
用途:家庭網路、企業內網
APIPA 位址
169.254.0.0/16
當 DHCP 伺服器不可用時,系統自動分配的暫時位址
用途:自動設定(表示網路設定失敗)
多播位址(Multicast)
224.0.0.0/4(224.0.0.0 - 239.255.255.255)
用於一對多通訊,如影片直播、IPTV
保留位址
- 0.0.0.0/8 - 表示"本網路"
- 255.255.255.255 - 廣播位址
- 192.0.2.0/24 - 文件範例專用
- 198.18.0.0/15 - 基準測試專用
最強公共 DNS 伺服器
Google DNS
8.8.8.8 / 8.8.4.4
2001:4860:4860::8888 / 2001:4860:4860::8844
全球最快、最穩定、支援 DNSSEC
Cloudflare DNS
1.1.1.1 / 1.0.0.1
2606:4700:4700::1111 / 2606:4700:4700::1001
注重隱私、速度極快、不記錄日誌
Quad9 DNS
9.9.9.9 / 149.112.112.112
安全防護、阻止惡意網站
OpenDNS
208.67.222.222 / 208.67.220.220
家長控制、內容過濾
亞洲地區 DNS
- 阿里雲 DNS(中國):223.5.5.5 / 223.6.6.6
- DNSPod(中國):119.29.29.29
- 114 DNS(中國):114.114.114.114
有趣的 IP 知識
💰 最貴的 IP 地址段
1.0.0.0/8 曾被 APNIC 以數百萬美元購入,用於研究。某些「靚號」IP(如 8.8.8.8、1.1.1.1)價值連城,Cloudflare 花費巨資從電信公司手中購得了 1.1.1.1。
📍 為什麼同一個 IP 會顯示不同位置?
- • IP 地理位置資料庫不同(各家 API 數據來源不同)
- • 動態 IP 地址會變動(運營商重新分配)
- • VPN/代理伺服器(顯示代理伺服器位置)
- • CDN 節點(顯示最近的 CDN 伺服器位置)
- • 行動網路(基地台位置可能不準確)
📊 IPv6 普及率
截至 2024 年,全球 IPv6 普及率約 40%,印度、美國、德國領先,中國約 30%。比利時是全球 IPv6 普及率最高的國家,超過 60%。
🎂 第一個 IP 地址
1983 年 1 月 1 日,網際網路正式採用 TCP/IP 協議,第一個 IP 地址由此誕生。BBN Technologies 的 Leonard Kleinrock 被認為是第一個使用 IP 地址的人。
🗑️ IP 地址分配的不合理
早期網際網路分配 IP 極其慷慨:MIT(一所大學)擁有 1600 萬個 IP(整個 18.0.0.0/8),蘋果公司擁有 1600 萬個 IP(17.0.0.0/8)。而整個中國大陸僅分配到約 3.3 億個 IP,卻要服務近 10 億網際網路用戶——按人均 2 台設備計算,至少需要 20 億個 IP。這種分配不均導致中國不得不大量使用 NAT 技術共享 IP。
🚫 IP 黑名單
全球有多個 IP 黑名單資料庫(如 Spamhaus),用於標記垃圾郵件、惡意軟體、DDoS 攻擊等來源的 IP。一旦 IP 被列入黑名單,可能會導致郵件被拒收、網站被屏蔽。
🤯 IP 地理位置的奇葩案例
美國堪薩斯州一戶普通家庭,因被 MaxMind 公司的 IP 資料庫設為預設位置(座標 38°N 97°W,美國地理中心),導致數百萬個無法精確定位的 IP 都指向此地。這家人莫名其妙成了「全美國的駭客窩點」,收到無數 FBI、警察、債主、詐騙受害者的騷擾電話與上門拜訪,甚至有人深夜闖入。2016 年,這家人將 MaxMind 告上法庭,最終獲得賠償。
💸 IPv4 地址可以買賣
由於 IPv4 地址枯竭,IP 地址已成為可交易商品。黑市價格可高達 40 美元/個。2011 年,微軟以 750 萬美元從破產的 Nortel 公司購買了 66.6 萬個 IP 地址,平均每個 IP 約 11.25 美元。2014 年,亞馬遜、微軟等科技巨頭瘋狂搶購 IPv4 地址,價格一度飆升。
🤦 IPv4 設計者的「失算」
1981 年,IPv4 的設計者們認為「42 億個地址,人類一輩子都用不完」。他們完全沒想到互聯網會發展到今天的規模:全球 80 億人口,每人至少 2–3 台裝置,再加上物聯網裝置的爆發式增長。如果當初設計成 64 位或 128 位,就不會有今天的地址枯竭問題了。
🏠 127.0.0.1 的秘密
127.0.0.1(localhost)不僅僅是一個地址,整個 127.0.0.0/8 段(約 1600 萬個地址)都是迴環地址。你可以 ping 127.0.0.2、127.1.2.3 等任意地址,都會指向本機。
⏰ IPv4 地址枯竭時間線
2011 年 2 月 3 日,IANA 分配完最後的 IPv4 地址區塊。2011 年 4 月 15 日,亞太地區(APNIC)耗盡。2012 年 9 月,歐洲(RIPE NCC)耗盡。2015 年 9 月,北美(ARIN)耗盡。
📏 最長的 IP 地址
IPv6 位址最長可寫成 39 個字元(8 組,每組 4 個十六進位數字,加上 7 個冒號)。但透過省略規則,可以大幅縮短,例如 ::1 表示 IPv6 回環位址。
🚀 IP 位址與網速無關
很多人誤以為更換 IP 位址可以提升網速,但實際上 IP 位址只是網路中的「門牌號碼」,網速取決於頻寬、路由、伺服器等因素,與 IP 位址本身無關。
相關 IP 資訊查詢服務
本工具使用以下 API 提供服務,同時推薦其他優秀的 IP 查詢服務:
IP-API.com
本工具使用 ⭐本工具主要使用的 API。完全免費(非商業用途),支援批量查詢,提供 JSON/XML/CSV 格式。限制:45 次/分鐘。
IPapi.co
本工具使用 ⭐本工具備用 API。提供貨幣、語言、連線類型等額外資訊。免費版每月 30,000 次請求。
IPInfo.io
資料準確、API 友好提供詳細的 IP 資訊、ASN 資料、地理位置、公司資訊等。提供免費方案(Free Plan)。
IPGeolocation.io
功能豐富提供 IP 地理位置、時區、貨幣、天氣等資訊。免費版每月 30,000 次請求。
MaxMind GeoIP2
最準確、企業級業界標準的 IP 地理位置資料庫,準確度高。提供離線資料庫和線上 API。
IPStack
安全檢測支援 IPv4 和 IPv6,提供安全模組(檢測代理、VPN、Tor)。免費版每月 100 次請求。
IPData.co
威脅情資提供威脅情資、ASN 資訊、公司資料。免費版每天 1,500 次請求。
Abstract API
簡單易用簡單易用的 IP 地理位置 API。免費版每月 1,000 次請求,限制 1 次/秒。
IPRegistry
註冊送 10 萬次提供 IP 地理位置、公司資訊、威脅檢測、使用者代理解析。註冊後贈送 100,000 次免費配額。
DB-IP
開源資料庫提供免費的 IP 地理位置資料庫下載,並有線上查詢服務。
IPify
獲取公網 IP專注於獲取公網 IP 位址,簡單快速,完全免費。
如何透過程式設計獲取 IP 位址?
以下是不同程式語言中獲取訪客 IP 位址的範例程式碼:
Java (Spring Boot)
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
public class IpController {
@GetMapping('/ip')
public String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("CF-Connecting-IP");
if (ip == null || ip.isEmpty()) {
ip = request.getHeader("X-Forwarded-For");
if (ip != null) {
ip = ip.split(",")[0];
}
}
if (ip == null || ip.isEmpty()) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.isEmpty()) {
ip = request.getRemoteAddr();
}
return ip;
}
}
PHP
function getClientIp() {
$ipKeys = [
'HTTP_CF_CONNECTING_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'REMOTE_ADDR'
];
foreach ($ipKeys as $key) {
if (!empty($_SERVER[$key])) {
$ips = explode(',', $_SERVER[$key]);
return trim($ips[0]);
}
}
return $_SERVER['REMOTE_ADDR'] ?? 'Unknown';
}
$ip = getClientIp();
echo "Your IP: " . $ip;
JavaScript (Node.js)
const express = require('express');
const app = express();
app.get('/ip', (req, res) => {
const ip = req.headers['cf-connecting-ip'] ||
req.headers['x-forwarded-for']?.split(',')[0] ||
req.headers['x-real-ip'] ||
req.socket.remoteAddress;
res.json({ ip: ip });
});
app.listen(3000);
Python (Flask)
from flask import Flask, request
app = Flask(__name__)
@app.route('/ip')
def get_ip():
ip = request.headers.get('CF-Connecting-IP') or \
request.headers.get('X-Forwarded-For', '').split(',')[0] or \
request.headers.get('X-Real-IP') or \
request.remote_addr
return {'ip': ip}
if __name__ == '__main__':
app.run()
Rust
use actix_web::{web, App, HttpRequest, HttpServer, Responder};
fn get_client_ip(req: &HttpRequest) -> String {
if let Some(ip) = req.headers().get("CF-Connecting-IP") {
return ip.to_str().unwrap_or("").to_string();
}
if let Some(forwarded) = req.headers().get("X-Forwarded-For") {
if let Ok(forwarded_str) = forwarded.to_str() {
if let Some(first_ip) = forwarded_str.split(',').next() {
return first_ip.trim().to_string();
}
}
}
if let Some(ip) = req.headers().get("X-Real-IP") {
return ip.to_str().unwrap_or("").to_string();
}
req.peer_addr()
.map(|addr| addr.ip().to_string())
.unwrap_or_else(|| "Unknown".to_string())
}
async fn ip_handler(req: HttpRequest) -> impl Responder {
let ip = get_client_ip(&req);
format!("Your IP: {}", ip)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().route("/ip", web::get().to(ip_handler))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Go
package main
import (
"net/http"
"strings"
)
func getClientIP(r *http.Request) string {
if ip := r.Header.Get("CF-Connecting-IP"); ip != "" {
return ip
}
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
ips := strings.Split(forwarded, ",")
return strings.TrimSpace(ips[0])
}
if ip := r.Header.Get("X-Real-IP"); ip != "" {
return ip
}
return r.RemoteAddr
}
func handler(w http.ResponseWriter, r *http.Request) {
ip := getClientIP(r)
w.Write([]byte("Your IP: " + ip))
}
func main() {
http.HandleFunc("/ip", handler)
http.ListenAndServe(":8080", nil)
}
注意事项:
- • 注意:如果網站使用了 CDN(如 Cloudflare)或反向代理(如 Nginx),需從特定的 HTTP 標頭中取得真實 IP
- • 優先順序:CF-Connecting-IP > X-Forwarded-For > X-Real-IP > RemoteAddr
- • X-Forwarded-For 可能包含多個 IP(以逗號分隔),第一個為用戶端真實 IP
- • 瀏覽器端 JavaScript 無法直接取得 IP,需呼叫第三方 API