公網 IP 查詢:curl 命令、線上檢測與連接埠可達性驗證
公網 IP 查詢的原理是向外發一個請求,讓對端告訴你它看到的來源位址:Linux 和 macOS 執行 curl -4 myip.ipip.net,Windows 用 curl.exe 或 nslookup myip.opendns.com resolver1.opendns.com,curl -6 查 IPv6。結果和網路卡位址不同就是中間做了 NAT;能查到公網 IP 也不等於連接埠對外可達,要從外部探測並在本機抓包確認。
公網 IP 查詢的方法是向外發一個請求,讓對端把它看到的來源位址告訴你。Linux 和 macOS 上執行 curl -4 myip.ipip.net,Windows 上用 curl.exe 或 nslookup myip.opendns.com resolver1.opendns.com,返回的就是你此刻的出口公網 IPv4。查到的位址與 ip addr 或 ipconfig 看到的網路卡位址不一樣,說明你和網際網路之間有 NAT,可能是家裡的路由器、運營商的大 NAT、雲平台的彈性 IP 或者一個代理。下面給出各系統的命令、線上檢測站怎麼用、兩個位址不一致的原因,以及更重要的一步:怎麼驗證某個連接埠從外面真的能存取到。
範例裡公網位址用文件專用的 203.0.113.0/24,伺服器位址用 203.0.113.10。
一條命令查出口公網 IP
| 系統 | 命令 | 說明 |
|---|---|---|
| Linux / macOS | curl -4 myip.ipip.net |
國內站點,返回“當前 IP:… 來自於:…”,附帶歸屬地和運營商 |
| Linux / macOS | curl -4 cip.cc |
國內站點,多行輸出,含歸屬地、運營商 |
| Linux / macOS | curl -4 -s https://ifconfig.me |
只返回位址,不帶多餘文字,指令碼里好用 |
| Linux / macOS | curl -4 -s http://checkip.amazonaws.com |
同上,只返回位址 |
| Linux / macOS | curl -6 -s https://api64.ipify.org 或 curl -6 -s https://ifconfig.co |
強制走 IPv6,查出口 IPv6 |
| 任意系統 | dig +short myip.opendns.com @resolver1.opendns.com |
走 DNS 協議,HTTP 被代理時仍能得到真實出口 |
| Windows cmd | curl.exe -4 myip.ipip.net |
Windows 10 1803 及以後自帶 curl.exe |
| Windows cmd | nslookup myip.opendns.com resolver1.opendns.com |
不依賴 curl,看 Non-authoritative answer 下面的位址 |
| Windows PowerShell | (Invoke-WebRequest -Uri https://ifconfig.me/ip -UseBasicParsing).Content |
PowerShell 裡 curl 是 Invoke-WebRequest 的別名,要用原生 curl 寫 curl.exe |
幾個用法細節:
- 加
-4或-6是為了確定答案。雙棧機器上不加引數,curl 可能優先走 IPv6,返回一個很長的位址,讓你誤以為 IPv4 查詢失敗。 - 加
-s不顯示進度;返回值末尾沒有換行的站點,後面補; echo,指令碼里好處理。 - 設定了
http_proxy或https_proxy環境變數時,curl 走代理,查到的是代理的出口。要查本機的真實出口,用curl --noproxy '*' …或者用上面的 DNS 方法。 - 境外站點在個別線路上可能連不上或很慢,換一個站點即可。同一台機器連查幾個站點,結果應該一致;不一致說明有多條出口或某個站點被代理,繼續往下看原因對照。
線上檢測站怎麼用、看什麼
在搜尋引擎裡直接搜“IP”,結果頁頂部通常會顯示你的公網 IP;ip138、ip.cn、ipip.net 這類檢測站除了位址,還給出歸屬地、運營商和位址型別。使用時注意三點:
- 看位址本身,和命令列查到的對一下,不同就是瀏覽器走了代理或外掛。
- 看運營商,機房伺服器上查到的運營商應與分配單一致,不一致說明走了錯誤的出口或上游線路切換了。
- 歸屬地只能參考。它來自離線位址庫,位址段遷移後可能幾個月才更新;要確認位址的真實登記歸屬,用
whois 203.0.113.10查序號產生器構資料庫的 netname、descr 和 country。
部分檢測站會標註“資料中心 IP”“代理 IP”,那是根據位址段用途庫做的分類,機房位址被標為資料中心是正常的。有的站還提供“連接埠線上檢測”,可以當作外部探測點用,但要知道它只能告訴你 TCP 連線能不能建立,判斷不了背後是哪一層攔截,後文的抓包方法才能定位。
查到的 IP 和網路卡 IP 不一樣是怎麼回事
| 場景 | 網路卡上看到的 | 查到的公網 IP | 說明 |
|---|---|---|---|
| 家庭或辦公寬頻 | 192.168.x.x 等私網位址 | 路由器 WAN 口位址 | 路由器做 NAT,正常 |
| 運營商級 NAT(CGNAT) | 路由器 WAN 口是 100.64.0.0/10 或 10.x | 運營商共享出口 | 多個使用者共用一個公網 IP,連接埠對映無效,沒有真正的公網 IP |
| 雲伺服器 | 私網位址,如 10.x.x.x、172.16.x.x | 彈性公網 IP | 雲平台在網路卡外做一對一 NAT,網路卡上看不到公網位址,這是正常設計 |
| 機房 NAT 型伺服器 | 私網位址 | 機房共享出口 | 沒有獨立公網 IP,做服務需要機房做連接埠對映 |
| 機房獨立公網 IP 的伺服器 | 公網位址 | 與網路卡一致 | 不一致時查代理設定和策略路由 |
| 掛了代理或 VPN | 任意 | 代理的出口 | 瀏覽器代理、系統代理、http_proxy 變數分別檢查 |
| 多出口或多 IP | 多個位址 | 由路由和源位址選擇決定 | 用 --interface 指定源位址測試 |
| 沒加 -4 | — | 返回了 IPv6 | 雙棧下 curl 優先 IPv6,加 -4 重查 |
判斷網路卡上的位址是不是公網位址,看它落在哪個範圍:
| 範圍 | 含義 |
|---|---|
| 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 | RFC 1918 私網位址,不會在公網路由 |
| 100.64.0.0/10 | RFC 6598 運營商級 NAT 共享位址,出現在路由器 WAN 口就說明上游還有 NAT |
| 169.254.0.0/16 | 鏈路本地位址,沒拿到 DHCP 位址時系統自動配的 |
| 127.0.0.0/8 | 環回 |
| 192.0.2.0/24、198.51.100.0/24、203.0.113.0/24 | 文件範例位址,只出現在教程裡 |
| 224.0.0.0/4、240.0.0.0/4 | 組播與保留位址,不會配在網路卡上當單播位址用 |
| 其餘 | 一般就是公網位址 |
雲伺服器要特別說一下:網路卡上是私網位址、查出來是公網位址,這不是故障。彈性公網 IP 由平台做一對一 NAT 對映到例項的私網位址上,入站流量同樣會被對映回來,連接埠能不能存取取決於安全組,而不是網路卡上有沒有公網位址。
怎麼驗證連接埠對外可達
能查到公網 IP,只說明出站沒問題。入站要分四層驗證,一層一層來:
第一層:服務在監聽,而且監聽的不是 127.0.0.1。
# Linux:Local Address 列應為 0.0.0.0:80、[::]:80 或 203.0.113.10:80
ss -tlnp | grep ':80 '
:: Windows
netstat -ano | findstr :80
只監聽在 127.0.0.1:80 的服務,本機 curl localhost 能通,外面永遠到不了,這是最常見的誤判。
第二層:本機防火牆放行。
sudo iptables -L INPUT -n --line-numbers # iptables
sudo nft list ruleset # nftables
sudo firewall-cmd --list-all # firewalld
sudo ufw status # ufw
Windows 在“高階安全 Windows Defender 防火牆”的入站規則裡確認該連接埠已放行,或者臨時關閉防火牆做一次對比測試。
第三層:從外部探測。 在另一台公網機器上執行,沒有的話用手機關掉 Wi-Fi 走流量存取,或者用線上連接埠檢測站:
nc -zv -w 3 203.0.113.10 80
nmap -Pn -p 22,80,443 203.0.113.10
Test-NetConnection 203.0.113.10 -Port 80
nmap 的三種結果含義不同:open 是包到了且有服務應答;closed 是包到了但沒服務監聽,收到了 RST,說明網路路徑是通的,問題在第一層;filtered 是包被丟棄,問題在防火牆或上游。
第四層:在伺服器上抓包,定位是哪一層攔的。 外部探測的同時在伺服器上抓目標連接埠的 SYN 包:
sudo tcpdump -ni eth0 'tcp port 80 and tcp[tcpflags] & tcp-syn != 0'
| 抓包結果 | 結論 |
|---|---|
| 抓到 SYN,也看到本機回了 SYN/ACK,但外部仍不通 | 回包被攔,檢查出站規則、策略路由或雙網路卡的回程路徑 |
| 抓到 SYN,本機沒有回應 | 本機防火牆丟棄,或服務沒監聽該位址 |
| 抓不到 SYN | 包沒到伺服器:雲平台安全組、機房防火牆、運營商遮蔽(家庭寬頻的 80、443、8080、25 常被遮蔽,以運營商為準)、或者前面有 CGNAT |
UDP 連接埠沒有握手,nc -u -zv 的結果不可靠,要用應用層方法驗證,例如 DNS 服務用 dig @203.0.113.10 example.com。
多 IP 與多出口伺服器:指定源位址測試
一台伺服器配了多個公網 IP,或者有兩條上聯,就要分別驗證每個位址的出站路徑:
# 指定源位址或網路卡發請求,返回值應等於指定的位址
curl -4 -s --interface 203.0.113.11 https://ifconfig.me; echo
curl -4 -s --interface eth1 https://ifconfig.me; echo
# 看核心預設會用哪個源位址去存取某個目標
ip route get 1.1.1.1
ip route get 輸出裡的 src 欄位就是預設出口位址。多 IP 伺服器上常見的問題是:所有 IP 都配在網路卡上,但出站一律用主 IP,第二個 IP 只能被動接收,這是源位址選擇的預設行為,需要為每個 IP 單獨做策略路由才能讓它的回包從對應的出口走。
動態公網 IP:定時檢測與變更通知
家庭寬頻和部分企業寬頻的公網 IP 會在重新撥號後變化。用 cron 每 5 分鐘查一次,變了就記錄並觸發 DDNS 更新或通知:
#!/bin/bash
# /usr/local/bin/pubip-watch.sh
last=$(cat /var/tmp/pubip 2>/dev/null)
now=$(curl -4 -s --max-time 10 https://ifconfig.me/ip)
if [ -n "$now" ] && [ "$now" != "$last" ]; then
echo "$now" > /var/tmp/pubip
logger -t pubip "public ip changed: ${last:-none} -> $now"
# 在這裡呼叫 DDNS 更新介面或傳送通知
fi
# crontab -e
*/5 * * * * /usr/local/bin/pubip-watch.sh
--max-time 10 防止網路不通時指令碼掛住;-n "$now" 的判斷保證查詢失敗時不會把空值寫進檔案。查詢站點換成任何一個只返回位址的都行,長期跑的指令碼不要指望單一站點永遠線上,可以寫成失敗時換下一個。
機房裡公網 IP 的登記與校驗
對 IDC 服務商和託管客戶來說,公網 IP 查詢有一個固定場景:伺服器上架或換 IP 之後,確認分配單上的位址真的配上了、真的能用。核對順序是:網路卡上的位址、掩碼、閘道器與分配單一致;ping 閘道器通;curl -4 返回的位址等於網路卡位址;從外部 nc 能探到業務連接埠。前三條都對、第四條不通,常見原因是交換器連接埠的 VLAN 不對,或者機房在交換器上做了 IP 與 MAC 的繫結、源位址校驗,而客戶換了網路卡或改了 IP,新來源的包在連接埠上就被丟掉了,這時要聯絡機房更新繫結,而不是在伺服器上反覆改防火牆。
繫結本身是機房防止 IP 被盜用的手段:Toplink DCIM 的交換器管理在接入連接埠上下發 ARP 繫結和源位址校驗,只放行源 IP 屬於該連接埠的流量;IP 位址管理登記每個公網位址分給了哪台伺服器,客戶工單裡報“公網 IP 不通”時,先查位址歸屬和連接埠繫結記錄,多數問題在登入伺服器之前就能定位。
常見問題
怎麼查一個域名或別人伺服器的公網 IP?
用 DNS 解析:nslookup example.com,或 dig +short example.com,返回的 A 記錄就是它對外公佈的位址;ping 域名也能順帶看到解析結果。注意用了 CDN 或雲防護的域名,查到的是就近的 CDN 節點位址,不是源站,而且不同地區解析結果不同。
為什麼瀏覽器查到的公網 IP 和 curl 查到的不一樣?
兩者走的出口不同。瀏覽器可能配置了代理或開著瀏覽器內的加速外掛,curl 預設讀取 http_proxy 環境變數,也可能一個走了 IPv6、一個走了 IPv4。用 curl -4 和 curl -6 分別查,再核對代理設定。
沒有公網 IP,怎麼從外面存取家裡的裝置?
三條路:向運營商申請開通公網 IPv4;用 IPv6,國內寬頻多數已經下發公網 IPv6 字首,在路由器的 IPv6 防火牆裡放行目標裝置即可,存取方也要有 IPv6;或者租一台有公網 IP 的伺服器做內網穿透(frp 一類工具),家裡的裝置主動連到伺服器,由伺服器把外部流量轉發回來。