Get the external IP address in shell without dig in 2016?

This question: “How can I get my external IP address in bash?

Solves the question with a call to dig:

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

that is the fastest resolution possible, as it involves a single udp packet.

However, that is only one site: OpenDNS, Is there any alternative?

And, makes use of dig, that is not available by default.
Again, Is there an alternative?


Note: I needed to solve this problem as the OpenDNS service didn’t work locally due to a (also local) redirect of port 53. I finally found out the reason (I had forgotten about the redirect). First, by using this command to find if dnssec is working (locally missing ad flag):

dig pir.org +dnssec +multi

And also using this command to find out if your ISP is redirecting OpenDNS resolutions:

host -t txt which.opendns.com 208.67.220.220

If being redirected, you will get an answer of: "I am not an OpenDNS resolver."

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

An alternative is Google DNS:

myip(){   dig @8.8.8.8 -t txt o-o.myaddr.l.google.com |
          grep "client-subnet" |
          grep -o "([0-9]{1,3}.){3}([0-9]{1,3})" ;   }

If your system does not have dig, then host will be exactly equivalent:

myip(){   host -t txt o-o.myaddr.l.google.com 8.8.8.8 |
          grep -oP "client-subnet K(d{1,3}.){3}d{1,3}";   }

Both GNU grep (Perl-like -P) and basic (BRE) regex are shown.

And, of course the original site, will also work.
With dig:

myip(){   dig myip.opendns.com @208.67.220.222  |
          grep "^myip.opendns.com."             |
          grep -o "([0-9]{1,3}.){3}([0-9]{1,3})"  ; }

And with host:

myip(){   host myip.opendns.com 208.67.220.222  |
          grep -oP "^myip.opendns.com.* K(d{1,3}.){3}(d{1,3})" ; }

The two snippets above will work with any of this four OpenDNS resolver addresses:

echo 208.67.22{0,2}.22{0,2}

If the direct DNS solution fails in the future, use curl to one of this sites (urls):

IFS=$'n' read -d '' -a urls <<-'_end_of_text_'
api.ipify.org
bot.whatismyipaddress.com/
canhazip.com/
checkip.dyndns.com/
corz.org/ip
curlmyip.com/
eth0.me/
icanhazip.com/
ident.me/
ifcfg.me/
ifconfig.me/
ip.appspot.com/
ipecho.net/plain
ipof.in/txt
ip.tyk.nu/
l2.io/ip
tnx.nl/ip
wgetip.com/
whatismyip.akamai.com/
_end_of_text_

Call an array address like this:

$ i=5; curl -m10 -L "http://${urls[i]}"
116.132.27.203

In some sites https may also work.

Method 2

I’ve concluded that many of these items are beacons that can identify you to somebody sniffing your network traffic and/or the service you are requesting this information from.

I recommend an HTTPS query to a service that preserves your privacy:

wget -qqO- 'https://duckduckgo.com/?q=what+is+my+ip' 
  | grep -Pow 'Your IP address is K[0-9.]+'

(In the event you’re on an embedded or other limited system and don’t have grep -P (libpcre), use
… | grep -ow 'Your IP address is [0-9.]*[0-9]' | grep -ow '[0-9][0-9.]*'  instead).

If you (and/or others on your IP) don’t use the privacy-conscientious DuckDuckGo search engine, then perhaps even that is a beacon (though your query is itself indecipherable to a third party, perhaps the fact that there was any query is too much?). You can do the same thing with Google, though Google expressly denies access to wget and similar utilities, so you have to forge your User Agent:

wget -U Mozilla/5.0 -qqO- 'https://www.google.com/search?q=what+is+my+ip' 
  | grep -Po '>K[0-9.]{7,}(?=<.{0,99}>Your public IP)'

This may violate Google’s terms of use.

Presumably, you’ll have to change the regex class from [0-9.] to [0-9a-f:] for IPv6. I don’t know what it’ll look like if you’re dual-stack.

Method 3

I use the following:

dig @1.1.1.1 TXT whoami.cloudflare.com +short | tr -d "

Or, with host:

$ host=whoami.cloudflare.com
$ host -t TXT "$host" 1.1.1.1 | sed -En "s/^$host.+"'"([^"]*)"/1/p'


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x