【问题标题】:Discovering public IP programatically in bash on Linux在 Linux 上的 bash 中以编程方式发现公共 IP
【发布时间】:2012-05-15 03:32:54
【问题描述】:

我找到了一个帖子,可以满足我的需要,但在 Windows 上:

Discovering public IP programmatically

> tracert -d www.yahoo.com

`Tracing route to www-real.wa1.b.yahoo.com [69.147.76.15]
over a maximum of 30 hops:`

1    <1 ms    <1 ms    <1 ms  192.168.14.203
2     *        *        *     Request timed out.
3     8 ms     8 ms     9 ms  68.85.228.121
4     8 ms     8 ms     9 ms  68.86.165.234
5    10 ms     9 ms     9 ms  68.86.165.237
6    11 ms    10 ms    10 ms  68.86.165.242

The 68.85.228.121 is a Comcast (my provider) router. We can ping that:

ping -r 9 68.85.228.121 -n 1

Pinging 68.85.228.121 with 32 bytes of data:

Reply from 68.85.228.121: bytes=32 time=10ms TTL=253 Route: 66.176.38.51 -&gt;

68.85.228.121 -&gt;

68.85.228.121 -&gt;

192.168.14.203

Voila! The 66.176.38.51 is my public IP.

这个(第三个)答案显示了一种获取我的 ISP 的 IP,然后使用 ping 来获取我的 IP 的方法。

它在 Linux 上未经修改就无法工作。 Traceroute 可以代替 tracert 工作,但是因为它的输出是不可预测的,所以我不知道如何解析它。

我做到了

IP="$(traceroute -d www.yahoo.com | grep ' 2 ' | sed -e 's/.*(\(.*\)).*/\1/')"

但是 grep 是(很差)硬编码的。我没有看到如何让 ping 像示例中那样工作。

我们将不胜感激。

【问题讨论】:

  • 这将是一种非常不可靠的发现您的公共 IP 地址的方法。无论如何,你需要它做什么?
  • 我想让它成为一个 bash 函数。我最初的用途是在一个脚本中,当指定端口在打开和关闭之间更改状态时通知我,我需要的不仅仅是本地 ip 才能获得真正的答案。
  • @nikhil ifconfig 在连接到电缆调制解调器的 WRT54GL 上为 wlan0 返回 inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0。它无法让我通过我的路由器。

标签: bash networking ip


【解决方案1】:

就我个人而言,我会运行这个命令:

wget -qO- whatismyip.org

【讨论】:

  • 你真的尝试过吗?它返回: 如果我在源代码中单击它,我会看到我的 IP 的图像 - 而不是文本。当我直接从浏览器访问该站点并查看该页面的源代码时,其中嵌入了一个 IP,但它不是该站点上显示的正确 IP。
【解决方案2】:

这不是一个可靠的解决方案,一种被动的方法是编写一个脚本来拉取你自己的路由器的“WAN”状态页面。您可以根据需要多次这样做,没有人会抱怨过度探测。

【讨论】:

  • 我不知道该怎么做。 ifconfig 为 wlan0 返回 inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0 ,这不会让我通过我的路由器。我不确定如何从路由器实际获取网页。
  • 我刚刚浏览了连接到电缆调制解调器的 WRT54GL 路由器的屏幕,但在任何地方都找不到我的外部 IP。
  • 比萨 - 太棒了,几乎是美妙的。以下获取我的IP:shelelia@halo:~/bin$ wget -o status.txt -O - --user my-user --password my-password 192.168.1.1/Status_Router.asp | grep "wan_ip" |头-1 | cut -d '"' -f 2 但里面有我的明文路由器用户名和密码,并且只能在那个路由器上工作(假设没有固件升级)。总之,一定有更好的方法!
  • 如果你对这个探测的要求不是太高,你必须依赖外部服务器,比如checkip.dyndns.org,当我说你原来的方法不可靠时,是因为一些ISP过滤了ICMP在他们的路由器。您可以使用的另一条路线是注册其中一个动态 IP 服务商并使用它们的更新方法来查找您的 IP。如果您使用外部来源来查找您的 IP,如果您过度使用它,他们几乎总是会过滤您。
【解决方案3】:

好的,我知道这是一个老帖子,但这篇文章向我揭示了一些事情,并将其与我已经学到的知识结合起来,我想我已经想出了一个可靠的解决方案。

你想要的 grep 是:

grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

我个人查找外部 IP 的解决方案曾经是:

curl icanhazip.com

现在是:

ISP=`traceroute -M 2 -m 2 8.8.8.8 | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'` | ping -R -c 1 -t 1 -s 1 $ISP | grep RR | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > .extIP

然后

cat .extIP

玩得开心!

【讨论】:

  • 刚刚调查了一下。乍一看,我的 traceroute 和 ping 版本似乎不支持您使用的所有选项,并且它们都因使用消息而出错。我对这两个命令都不是特别熟悉,所以我得进一步研究。
  • 让我知道您使用的是什么 linux 发行版,我今天将尝试在 linux vm 中测试我的脚本并更新我的帖子!还发布您收到的任何错误消息。同时,尝试traceroute -f 2 -m 2 8.8.8.8traceroute -S 2 -m 2 8.8.8.8 我认为我使用的“-M 标志在 linux 中需要是“-f”或“-S”...输入man traceroute 并寻找一个标志“ max ttl”。这些标志的作用是在结果中仅显示 hop 2。要查看 hop 3,请将您的标志更改为“-f 3 -m 3”
【解决方案4】:

我只是将@pizza 所说的内容与this 答案结合起来,并生成了以下工作脚本。它不如使用traceroute之类的东西好,但它要简单得多。

   #!/bin/bash
   content="$(wget http://checkip.dyndns.org/ -q -O -)"
   myip="$(<<< "$content" sed -e 's/.*Current IP Address: //' -e 's/<.*//')"
   echo "myip = [${myip}]"

wget 命令检索向 dyndns 询问我的 IP 的结果。然后,sed 在 IP 地址 dyndns 返回之前和之后砍掉所有内容。

如其他地方所述,如果此类请求过于频繁,诸如 dyndns 之类的网站可能会阻止此类请求,但由于您的 IP 在大多数情况下应该至少在您的会话期间保持不变,如果不是很多天,它应该不必经常运行此脚本。

【讨论】:

  • 既然您已经评论说您可以在许多不同的路由器上使用它,您需要注意双 NAT 问题。 CGN每次都会杀了你,那些只为无线使用防火墙/路由/WAP而不将其设置为桥接模式的白痴也会如此。
【解决方案5】:

如果您想要的是简单,并且您不介意依赖其他服务器(或服务),请尝试:

dig +short myip.opendns.com @resolver1.opendns.com

那只会吐出你的地址

或者,

#!/bin/bash
myip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
echo "myip = [${myip}]"

【讨论】:

    猜你喜欢
    • 2010-10-11
    • 2018-05-28
    • 2013-01-13
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 2015-06-13
    相关资源
    最近更新 更多