在 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 服务,直到得到回复。它使用digcurlwget(按此顺序),具体取决于它在路径中找到的那个。截至 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) &lt;URL&gt; 其中包含请求者的地址:大部分时间应该可以工作,但可能该站点可能无法从机器访问(可能是防火墙或临时/永久不可用)。您将获得尽可能多的公共 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脚本优化版

域名IP地址指向:** 花生壳客户端IP:** 经检测,您的域名已激活并指向正确。 IP与外网ip不一致,为啥?

如何在统一 c# 中检测用户 IP 地址? [关闭]

Linux下检测IP地址冲突及解决方法

检测ip冲突的方法

检测keepalived脑裂的脚本