我在路由器后面,我需要一个简单的命令来发现我的公共IP(而不是谷歌搜索我的IP并单击结果之一)

有这方面的标准协议吗?我听说过 STUN,但不知道如何使用它?

附:我打算写一个简短的 python 脚本来做到这一点

有帮助吗?

解决方案

编辑:curlmyip.com不再可用。 (感谢maxywb)

原帖

撰写本文时,curlmyip.com有效。从命令行:

curl curlmyip.com

这是一个第三方网站,可能会在未来几年内推出或未推出。但就目前而言,这似乎很简单。

其他提示

这可能是最简单的方法。解析以下命令的输出:

  1. 运行traceroute以查找距离您的计算机少于3跳的路由器。
  2. 使用选项运行ping以记录源路由并解析输出。记录路线中的第一个IP地址是您的公共IP地址。
  3. 例如,我在Windows机器上,但同样的想法也应该来自unix。

    > 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
    

    68.85.228.121是Comcast(我的提供商)路由器。我们可以说:

    > 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 ->
               68.85.228.121 ->
               68.85.228.121 ->
               192.168.14.203
    

    瞧! 66.176.38.51是我的公共IP。

我制作了一个连接 http://automation.whatismyip.com/n09230945.asp的程序 这是用D写的,让其他人告诉你他们看到你的ip是可能最可靠的方式:

/*
    Get my IP address
*/


import tango.net.http.HttpGet;
import tango.io.Stdout;

void main()
{
      try
      {
          auto page = new HttpGet ("http://automation.whatismyip.com/n09230945.asp");
          Stdout(cast(char[])page.read);
      }
      catch(Exception ex)
      {
          Stdout("An exception occurred");
      }
}

编辑python代码应该是:

from urllib import urlopen
print urlopen('http://automation.whatismyip.com/n09230945.asp').read()

瞄准www.whatsmyip.org很粗鲁。他们请求不要在页面上这样做。

只有与目标处于同一NAT级别的系统才会看到相同的IP。 例如,您的应用程序可能位于多层NAT后面(当您离开美国时,会发生更多这种情况,因为美国的IP过剩)。

STUN确实是最好的方法。 通常,您应该计划在某个地方运行(STUN)服务器 应用程序可以问:不要硬编码其他人的服务器。你必须编码 发送一些特定的消息,如rfc5389中所述。

我建议阅读和相关链接。 http://www.ietf.org/html.charters/behave-charter.html

您可能更愿意查看IPv6和Teredo以确保始终拥有IPv6访问权限。 (微软Vista让这很容易,我被告知)

每当我想这样做时,我就会刮掉 whatismyip.org 。当您访问该网站时,它会为您提供纯文本公共IP。简单明了。

让您的脚本访问该网站并阅读IP。

我不知道您是否在帖子中暗示这一点,但是无法从您自己的计算机上获取您的公共IP。它必须来自外部来源。

2013编辑:此网站现在返回图片而不是文字,因此无法用于此目的。

我喜欢 ipify.org:

  • 它是免费使用的(甚至可以通过编程方式使用,甚至可以在大流量的情况下使用)
  • 响应仅包含IP地址,没有任何垃圾(无需解析)
  • 您还可以请求 JSON 格式的响应
  • 适用于 IPv4 和 IPv6
  • 它托管在云中
  • 它是开源的
$ curl api.ipify.org
167.220.196.42

$ curl "api.ipify.org?format=json"
{"ip":"167.220.196.42"}

正如好几个人提到的, 眩晕 确实是正确的解决方案。

如果网络上有网络上运行的UpNp服务器,您就可以与网关通话并询问其外部IP地址。

最简单的方法可能是询问网络外部的某个服务器。

要记住的一件事是,不同的目的地可能会为您看到不同的地址。路由器可以是多宿主的。而这正是问题开始的地方。

要获取外部IP,您可以使用特殊主机名“myip.opendns.com”对服务器服务器进行dns查询:

from subprocess import check_output

ip = check_output(["dig", "+short", "@resolver1.opendns.com",
                   "myip.opendns.com"]).decode().strip()

在Windows上,您可以尝试 nslookup

Python stdlib中没有允许指定自定义DNS服务器的dns模块。您可以使用第三方库,例如 Twisted 来进行dns查询:

from twisted.internet     import task # $ pip install twisted
from twisted.names.client import Resolver
from twisted.python.util  import println

def main(reactor):
    opendns_resolvers = [("208.67.222.222", 53), ("208.67.220.220", 53)]
    resolver = Resolver(servers=opendns_resolvers, reactor=reactor)
    # use magical hostname to get our public ip
    return resolver.getHostByName('myip.opendns.com').addCallback(println)
task.react(main)

使用 dnspython 时,情况相同:

import dns.resolver # $ pip install dnspython

resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = ["208.67.222.222", "208.67.220.220"]
print(resolver.query('myip.opendns.com')[0])
另一种厚颜无耻的方式: 如果您的路由器可以选择在 DynDNS 上更新它的网络IP,您可以使用类似的方式获取自己的IP :

IP=`resolveip -s myalias.dyndns-home.com`

Duck Duck Go可以根据自己的页面免费访问他们的API: https://duckduckgo.com/api

如果您需要IP地址,请输入以下网址: http://api.duckduckgo.com/?q=my+ip&format= JSON

返回一个JSON对象。 Answer 属性有一个人类可读的字符串,其中包含您的IP地址。例如:

{
    ...
    "Answer": "Your IP address is ww.xx.yyy.zzz in <a href=\"http://open.mapquest.com/?q=aaaaa(bbbbb)\">aaaaa(bbbbb)</a>"
    ...
}

如果您认为这个字符串不会改变或者您愿意需要定期修复它。

或者,如果你想要一个更加面向未来的方法,你可以遍历 split()返回的所有内容,并返回第一个作为ip地址的项目。请参阅此处以验证IP地址: 如何在Python中验证IP地址?

curl api.infoip.io - 完整详情

curl api.infoip.io/ip - 只是ip地址

curl api.infoip.io/country - 只是国家/地区名称

......以及更多相同的

您可以在 http://docs.ciokan.apiary.io/ 查看文档

我正在向您分享我的方法,无需使用外部 API 即可检索服务器的公共 IP 地址(这当然存在安全风险)

INTERFACE=`ip route get 8.8.8.8 | grep 8.8.8.8 | cut -d' ' -f5`
HOSTIP=`ifconfig $INTERFACE | grep "inet " | awk -F'[: ]+' '{ print $4 }'`

或者如果你愿意的话也可以用Python:

import subprocess
public_ip = subprocess.check_output(["ifconfig `ip route get 8.8.8.8 | grep 8.8.8.8 | cut -d' ' -f5` | grep \'inet \' | awk -F'[: ]+' '{ print $4 }'"], shell=True)

它的工作原理如下:

  • 确定到达 google DNS 服务器的最佳接口
  • grep 公共IP ifconfig 该接口的条目

现在托管您自己的“无服务器”非常便宜API。所有主要的云提供商都为此提供服务。例如,使用Google Cloud Functions只需:

exports.requestIP = (req, res) => {
    res.status(200).send(req.ip)
}

这种方法可能比使用上面的公共服务更可靠,您可以在函数名称中添加一个长的随机字符串,以使其保密。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top