For monitoring purposes, I'd like to find out all public IPv4 and IPv6 addresses of a mobile-warrior UNIX box.
Note that this is different from Finding the Public IP address in a shell script because of the following extra requirements:
- the mobile warrior itself probably does not have any public IPv4 addresses at all;
- it may or may not have IPv6 (but we're only interested in active ones that would be used in actual outgoing connections);
- the underlying internet connection might be load-balanced, details unknown, where a combination of UDP, TCP, ICMP and source/destination IP address, may determine which upstream will be used; we need to try our best to find out all such IP addresses for a complete picture on the underlying internet connectivity of the gateway, without having direct access to the gateway itself.
Explanation
We can determine the public IP address through DNS with
dig
(the DNS lookup utility from BIND), this lets us try out both UDP (with the+notcp
option) and TCP (+tcp
option), leaving only ICMP behind. However, we can try sending all these queries to multiple independent destination IPv4 and IPv6 addresses, making it more likely that the load-balancing of the connection will take place, returning more unique responses.It would appear that the positioning of the
-4
and-6
options withdig
might also be handled differently depending on the order of the arguments — if positioned right afterdig
before the@
specifier, then it's enforced as a hard requirement; if positioned past the@
specifier and/or as a final argument, then it's enforced as a soft requirement (IPv4 will be used if IPv6 connectivity is missing); the snippet below uses it as a soft requirement to avoid having to implement error-handling.We can use GNU Parallel to mix-and-match several commands and options that are at stake here.
Solution
Here's the full solution:
Here's the same snippet as a single line:
Here's the same snippet SO inline:
parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
Testing
Here's a demonstration of what the above
parallel
invocation would work to accomplish:P.S. More of GNU Parallel
To extend on our solution above, the following could be used to perform whois and rDNS lookups on all found addresses; note that for IPv6 lookups to work on BSDs and macOS, one might have to specify
-a
for ARIN,-A
for APNIC or-r
for RIPE as an option towhois
:parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp | sort -n | uniq | parallel -vk ::: "echo" "host" "whois -a" :::: /dev/stdin