在 bash 中检测公共 IP 地址的方法
Posted
技术标签:
【中文标题】在 bash 中检测公共 IP 地址的方法【英文标题】:Methods to detect public IP address in bash 【发布时间】:2013-01-13 16:29:38 【问题描述】:作为安装脚本的一部分,我想对机器的公共 IP 地址进行“有根据的猜测”。它应该尽可能健壮,可以在各种主机和平台上工作。这是一个例子:
https://gist.github.com/4669037
此脚本使用 3 种方法,然后默认为 /etc/hostname
的值。到目前为止,我只在 Ubuntu 上对此进行了测试。这可能适用于其他发行版吗?还有我可以添加的其他方法吗?
【问题讨论】:
只要安装了 curl 就可以在任何发行版中使用。curl ifconfig.me
下面的答案很棒。但我想要备用方法,以防 curl 不可用或 ifconfig.me 站点不可用。
@ruakh 示例脚本已经在 curl 行中有 2> /dev/null
。这不会隐藏 curl 错误吗?
@Jeroen:哎呀,对不起,我不知何故没看到。没关系。 :-)
请参阅this answer,其中有一个脚本尝试各种 DNS 服务器和 HTTP 服务,直到得到回复。它使用dig
或curl
或wget
(按此顺序),具体取决于它在路径中找到的那个。截至 2017 年 2 月,服务器列表良好。
【参考方案1】:
我在其他命令的末尾得到了空白字符:
$ curl -s https://api.ipify.org
255.255.255.255%
我发现使用 jsonip.com 结合jq 摆脱了这个。这样,解析IP地址就像jq表达式一样简单:
$ curl -s https://jsonip.com | jq -r '.ip'
255.255.255.255
看到这个jq play。
【讨论】:
api.ident.me 没有空格 ;)【参考方案2】:curl ipinfo.io/ip
或者
wget -q -O - ipinfo.io/ip
或者
lynx -source ipinfo.io/ip
get public ip address
【讨论】:
谢谢,这些都很棒。现在我只需要一个本地回退方法,以防这些主机在安装过程中不可用。 在CURL
中使用-L
重定向url 有好处:curl -L ipinfo.io/ip
【参考方案3】:
我使用 IPGrab 是因为它易于记忆。
curl http://ipgrab.io
【讨论】:
【参考方案4】:如果在 AWS EC2 上您可以使用:
curl checkip.amazonaws.com
注意:此服务可以从任何网络客户端使用。
【讨论】:
【参考方案5】:仅使用 bash(在 icanhazip.com 的帮助下):
exec 3<>/dev/tcp/icanhazip.com/80
echo -e 'GET / HTTP/1.0\r\nhost: icanhazip.com\r\n\r' >&3
while read i
do
[ "$i" ] && myip="$i"
done <&3
echo "$myip"
bash打开一个socket到icanhazip并发送一个http请求,IP地址在返回数据的最后一个非空行返回。 (前几行是http头)
这避免了需要像 wget 或 curl 这样的 http 客户端。
【讨论】:
【参考方案6】:使用 ipify API:
curl 'https://api.ipify.org?format=json'
Bash 脚本:
#!/bin/bash
ip=$(curl -s https://api.ipify.org)
echo "My public IP address is: $ip"
【讨论】:
curl -s https://api.ipify.org
在末尾添加空格字符。请参阅here 进行修复。【参考方案7】:
您要查找多少公共公共 IP?如果机器在 NAT 后面怎么办?
curl
/ wget
/ netcat
(nc
) <URL>
其中包含请求者的地址:大部分时间应该可以工作,但可能该站点可能无法从机器访问(可能是防火墙或临时/永久不可用)。您将获得尽可能多的公共 IP。
ifconfig
:必须以 root 身份运行,否则您还必须尝试 /sbin/ifconfig
或 /usr/sbin/ifconfig
。如果机器有更多的网卡怎么办?您如何判断哪个 IP 是正确的?如果机器的 LAN 上只使用 IPv6 会怎样?在任何情况下,您都将获得尽可能少的公共 IP(如果在机器上配置了更多接口,则可能是错误的 IP - 如今使用网络分流设备和/或无处不在的虚拟化通常就是这种情况)。
/etc/hostname
:不需要存在,在很多系统上它是/etc/HOSTNAME
,它不包含IP地址,而应该包含主机名(通常是FQDN)。
关键是,它可能失败的方式很多,您可能应该考虑 a) 更准确地指定您的目标系统或 b) 您是否真的需要知道 IP - 是一种解决方案当它在稍微复杂的设置中惨遭失败时,这似乎在值得使用的简单情况下工作?如果您认为自己需要 IP,请准备一种方法来优雅地处理故障,以防您根本没有获得 IP 或获得错误的 IP。
【讨论】:
脚本将以 root 身份运行。随意提出一种更好的方法来从ifconfig
中提取 ip :-)
@Jeroen 我认为没有“更好”的方法:( - 它们都存在某种缺陷(因此您无法获得 100% 有效的解决方案)。请参阅更新的答案.
我不期待一个完美的解决方案,我想要一个聪明的猜测。用户以后仍然可以手动修改该值。【参考方案8】:
试试这个命令:
wget -O - -q icanhazip.com
【讨论】:
【参考方案9】:如果你落后于 nat 或其他东西,此解决方案将不起作用。它在没有 3rd 方服务的情况下提供帮助。如果机器上有连接(例如服务器或 ppp 连接),它就可以工作。
不是一个完全正确的问题答案,但可能会帮助其他人(比如我) 在大多数(或全部?) 情况下都需要 root 权限你可以从route -n
获取(第一个)默认路由,找到它使用的接口,找到它拥有的ip。
MAINIF=$( route -n | grep '^0\.0\.0\.0' | head -n 1 | awk 'print $NF' )
IP=$( ifconfig $MAINIF | IFS=' :';read r;read r r a r;echo $a; )
【讨论】:
【参考方案10】:使用 curl 击球 shtuff.it IP service
curl http://shtuff.it/myip/short
【讨论】:
【参考方案11】:curl ifconfig.me
是最好的选择,以防你没有 curl:
wget -qO- ifconfig.me/ip
【讨论】:
那个网站不好,比较ifconfig.me status和ipinfo.io status以上是关于在 bash 中检测公共 IP 地址的方法的主要内容,如果未能解决你的问题,请参考以下文章
CENTOS 7 内网网段在用IP地址检测Shell脚本优化版