Discovering public IP programmatically

2020-01-25 06:06发布

I'm behind a router, I need a simple command to discover my public ip (instead of googling what's my ip and clicking one the results)

Are there any standard protocols for this? I've heard about STUN but I don't know how can I use it?

P.S. I'm planning on writing a short python script to do it

15条回答
▲ chillily
2楼-- · 2020-01-25 06:40

To get your external ip, you could make a dns query to an opendns server with the special hostname "myip.opendns.com":

from subprocess import check_output

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

On Windows, you could try nslookup.

There is no dns module in Python stdlib that would allow to specify custom dns server. You could use third party libraries e.g., Twisted to make the dns query:

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)

Here's the same using dnspython library:

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])
查看更多
在下西门庆
3楼-- · 2020-01-25 06:41

Duck Duck Go gives free access to their API according to their own page here: https://duckduckgo.com/api

Here's the URL you hit if you want your IP address: http://api.duckduckgo.com/?q=my+ip&format=json

That returns a JSON object. The Answer attribute has a human readable string with your ip address in it. Example:

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

You could extract the ip address from that string by using split()[4], if you think that it's a safe assumption that this string won't ever change or you're willing to need to periodically fix it.

Alternatively, if you want to have a more future proof method, you could loop over everything returned by split() and return the first item that is an ip address. See here for validating IP addresses: How to validate IP address in Python?

查看更多
The star\"
4楼-- · 2020-01-25 06:44

Your simplest way may be to ask some server on the outside of your network.

One thing to keep in mind is that different destinations may see a different address for you. The router may be multihomed. And really that's just where problems begin.

查看更多
登录 后发表回答