在無公網 IP 的 NAT 環境、容器、CI/CD Runner 中,ifconfig/ip a 只能看到內網位址。本文整理四種無需 root、跨平台可用的取得公網 IP 方法,並對比穩定度與適用場景。
# 純文字回傳
curl -s https://ifconfig.me
curl -s https://ipinfo.io/ip
curl -s https://api.ipify.org
curl -s https://checkip.amazonaws.com
# JSON 回傳(含地理位置、ASN)
curl -s https://ipinfo.io/json
# {"ip":"203.0.113.45","city":"Taipei","region":"Taiwan","country":"TW","loc":"25.0330,121.5654","org":"AS3462 Chunghwa Telecom","timezone":"Asia/Taipei"}
優點:無相依、支援 IPv4/IPv6、可解析地理資訊。
缺點:依賴第三方服務可用性、可能被限流。
# OpenDNS
dig +short myip.opendns.com @resolver1.opendns.com
# Google
dig +short TXT o-o.myaddr.l.google.com @ns1.google.com | tr -d '"'
# Cloudflare
dig +short TXT whoami.cloudflare.com @1.1.1.1 | tr -d '"'
優點:僅需 dig/drill,無 HTTP 堆疊開銷,回應通常 < 50ms。
缺點:需 UDP 53 通,部分企業防火牆封鎖外部 DNS。
# 登入遠端主機後
echo $SSH_CLIENT | awk '{print $1}'
# 或
who am i | awk '{print $5}' | tr -d '()'
適用於 Bastion Host / Jump Server 確認來源 IP。
# 取得預設閘道介面
ip route get 8.8.8.8 | awk '{print $7; exit}'
# 再取得該介面的公網 IP(需配合 upnp/nat-pmp 或路由器 API)
# 純本機無法直接得知公網 IP,此法僅適用於有公網 IP 直掛的介面
| 方法 | 穩定度 | 速度 | 適用場景 | 備援策略 |
|---|---|---|---|---|
| HTTP API | ★★★☆☆ | ~200ms | 通用腳本、容器啟動 | 輪詢 3 組 API,超時 3s |
| DNS 反查 | ★★★★☆ | ~30ms | 高頻輪詢、嵌入式裝置 | 備援 2 組 DNS 提供商 |
| SSH 反查 | ★★★★★ | 即時 | 登入腳本、審計日誌 | N/A |
| 路由推導 | ★★☆☆☆ | 即時 | 公網 IP 直掛介面 | N/A |
#!/bin/bash
# get_pub_ip.sh — 多源備援、支援 IPv4/IPv6
set -euo pipefail
get_ip_v4() {
for url in \
"https://api.ipify.org" \
"https://ifconfig.me" \
"https://checkip.amazonaws.com"; do
ip=$(curl -4 -fsSL --max-time 3 "$url" 2>/dev/null | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}') && echo "$ip" && return
done
# DNS 備援
dig +short -4 myip.opendns.com @resolver1.opendns.com 2>/dev/null | head -1
}
get_ip_v6() {
curl -6 -fsSL --max-time 3 https://api6.ipify.org 2>/dev/null || \
dig +short -6 myip.opendns.com @resolver1.ipv6.opendns.com 2>/dev/null | head -1
}
echo "IPv4: $(get_ip_v4)"
echo "IPv6: $(get_ip_v6)"
結語: 生產環境建議「HTTP API 為主、DNS 為備」,並將取得的 IP 寫入 /etc/hosts 或 Consul/Etcd 供服務發現使用。避免在迴圈中高頻呼叫單一 API,以免觸發限流導致誤判。