Linux – How to Get External IP Address in a Shell Script

iplinuxshell-script

I need to find my external IP address from a shell script. At the moment I use this function:

myip () { 
    lwp-request -o text checkip.dyndns.org | awk '{ print $NF }'
}

But it depends on perl-libwww, perl-html-format, perl-html-tree installed. What other ways can I get my external IP?

Best Answer

I'd recommend getting it directly from a DNS server.

Most of the other answers below all involve going over HTTP to a remote server. Some of them required parsing of the output, or relied on the User-Agent header to make the server respond in plain text. Those change quite frequently (go down, change their name, put up ads, might change output format etc.).

  1. The DNS response protocol is standardised (the format will stay compatible).
  2. Historically, DNS services (Akamai, Google Public DNS, OpenDNS, ..) tend to survive much longer and are more stable, more scalable, and generally more looked-after than whatever new hip whatismyip dot-com HTTP service is hot today.
  3. This method is inherently faster (be it only by a few milliseconds!).

Using dig with an OpenDNS resolver:

$ dig @resolver4.opendns.com myip.opendns.com +short

Perhaps alias it in your bashrc so it's easy to remember

# https://unix.stackexchange.com/a/81699/37512
alias wanip='dig @resolver4.opendns.com myip.opendns.com +short' 
alias wanip4='dig @resolver4.opendns.com myip.opendns.com +short -4'
alias wanip6='dig @resolver1.ipv6-sandbox.opendns.com AAAA myip.opendns.com +short -6'

Responds with a plain ip address:

$ wanip # wanip4, or wanip6
80.100.192.168 # or, 2606:4700:4700::1111

Syntax

(Abbreviated from https://ss64.com/bash/dig.html):

usage:  dig [@global-dnsserver] [q-type] <hostname> <d-opt> [q-opt]

    q-type   one of (A, ANY, AAAA, TXT, MX, ...). Default: A.

    d-opt    ...
             +[no]short          (Display nothing except short form of answer)
             ...

    q-opt    one of:
             -4                  (use IPv4 query transport only)
             -6                  (use IPv6 query transport only)
             ...

The ANY query type returns either an AAAA or an A record. To prefer IPv4 or IPv6 connection specifically, use the -4 or -6 options accordingly.

To require the response be an IPv4 address, replace ANY with A; for IPv6, replace it with AAAA. Note that it can only return the address used for the connection. For example, when connecting over IPv6, it cannot return the A address.

Alternative servers

Various DNS providers offer this service, including OpenDNS, Akamai, and Google Public DNS:

# OpenDNS (since 2009)
$ dig @resolver3.opendns.com myip.opendns.com +short
$ dig @resolver4.opendns.com myip.opendns.com +short
80.100.192.168

# OpenDNS IPv6
$ dig @resolver1.ipv6-sandbox.opendns.com AAAA myip.opendns.com +short -6
2606:4700:4700::1111

# Akamai (since 2009)
$ dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short
80.100.192.168

# Akamai approximate
# NOTE: This returns only an approximate IP from your block,
# but has the benefit of working with private DNS proxies.
$ dig +short TXT whoami.ds.akahelp.net
"ip" "80.100.192.160"

# Google (since 2010)
# Supports IPv6 + IPv4, use -4 or -6 to force one.
$ dig @ns1.google.com TXT o-o.myaddr.l.google.com +short
"80.100.192.168"

Example alias that specifically requests an IPv4 address:

# https://unix.stackexchange.com/a/81699/37512
alias wanip4='dig @resolver4.opendns.com myip.opendns.com +short -4'

$ wanip4
80.100.192.168

And for your IPv6 address:

# https://unix.stackexchange.com/a/81699/37512
alias wanip6='dig @ns1.google.com TXT o-o.myaddr.l.google.com +short -6'

$ wanip6
"2606:4700:4700::1111"

Troubleshooting

If the command is not working for some reason, there may be a network problem. Try one of the alternatives above first.

If you suspect a different issue (with the upstream provider, the command-line tool, or something else) then run the command without the +short option to reveal the details of the DNS query. For example:

$ dig @resolver4.opendns.com myip.opendns.com

;; Got answer: ->>HEADER<<- opcode: QUERY, status: NOERROR

;; QUESTION SECTION:
;myip.opendns.com.      IN  A

;; ANSWER SECTION:
myip.opendns.com.   0   IN  A   80.100.192.168

;; Query time: 4 msec
Related Question