-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathdiscover-internal-ip.sh
executable file
·84 lines (70 loc) · 2.65 KB
/
discover-internal-ip.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env sh
# shellcheck shell=dash
# Checked with ShellCheck (https://www.shellcheck.net/)
#/ Use DNS to find out about the external IP of the running system.
#/
#/ This script is useful when running from a machine that sits behind a NAT.
#/ Due to how NAT works, machines behind it belong to an internal or private
#/ subnet, with a different address space than the external or public side.
#/
#/ Typically it is possible to make an HTTP request to a number of providers
#/ that offer the external IP in their response body (eg: ifconfig.me). However,
#/ why do a slow and heavy HTTP request, when DNS exists and is much faster?
#/ Well established providers such as OpenDNS or Google offer special hostnames
#/ that, when resolved, will actually return the IP address of the caller.
#/
#/ https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script/81699#81699
#/
#/
#/ Arguments
#/ ---------
#/
#/ --ipv4
#/
#/ Find the external IPv4 address.
#/ Optional. Default: Enabled.
#/
#/ --ipv6
#/
#/ Find the external IPv6 address.
#/ Optional. Default: Disabled.
# Shell setup
# ===========
# Shell options for strict error checking.
for OPTION in errexit errtrace pipefail nounset; do
set -o | grep -wq "$OPTION" && set -o "$OPTION"
done
# Trace all commands (to stderr).
#set -o xtrace
# Discover the private IP address
# ===============================
if [ "$CFG_IPV4" = "true" ]; then
COMMANDS='dig @resolver1.opendns.com myip.opendns.com A -4 +short
dig @ns1.google.com o-o.myaddr.l.google.com TXT -4 +short | tr -d \"
dig @1.1.1.1 whoami.cloudflare TXT CH -4 +short | tr -d \"
dig @ns1-1.akamaitech.net whoami.akamai.net A -4 +short'
is_valid_ip() {
# Check if the input looks like an IPv4 address.
# Doesn't check if the actual values are valid; assumes they are.
echo "$1" | grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
}
else
COMMANDS='dig @resolver1.opendns.com myip.opendns.com AAAA -6 +short
dig @ns1.google.com o-o.myaddr.l.google.com TXT -6 +short | tr -d \"
dig @2606:4700:4700::1111 whoami.cloudflare TXT CH -6 +short | tr -d \"'
is_valid_ip() {
# Check if the input looks like an IPv6 address.
# It's almost impossible to check the IPv6 representation because it
# varies wildly, so just check that there are at least 2 colons.
[ "$(echo "$1" | awk -F':' '{print NF-1}')" -ge 2 ]
}
fi
IFS="$(printf '\nx')" && IFS="${IFS%x}"
for COMMAND in $COMMANDS; do
if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then
printf '%s' "$IP"
exit 0
fi
done
echo "[$0] All providers failed" >&2
exit 1