Get Public IP address from Shell or Python
Both the shell and Python methods get public IPv4 and IPv6 addresses. This is good for verifying the computer IP is in the organization’s IP address range. These scripts use the “reflector” method, which can be more reliable on complex networks.
Shell: specify the network interface with curl --interface eth0
option.
url=('https://ident.me' 'https://api.ipify.org')
for u in ${url[@]}; do
curl -6 -s -m 2 $u && break
done
for u in ${url[@]}; do
curl -4 -s -m 2 $u && break
done
Python script getIP.py
#!/usr/bin/env python
"""
gets interface IPv4 and IPv6 public addresses using libCURL
This uses the "reflector" method, which seems more reliable for finding public-facing IP addresses,
WITH THE CAVEAT that man-in-the-middle, etc. attacks can defeat the reflector method.
"""
from ipaddress import ip_address
import pycurl
from io import BytesIO
urls = ['https://ident.me', # ipv6 and ipv4
'https://api.ipify.org'] # ipv4 only
length=45
# https://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
def getip(interface=None):
for url in urls:
addr = []
for ipv in (pycurl.IPRESOLVE_V4,pycurl.IPRESOLVE_V6):
buffer = BytesIO() # must clear like this
C = pycurl.Curl()
if interface:
C.setopt(pycurl.INTERFACE,interface)
C.setopt(C.URL, url)
C.setopt(pycurl.IPRESOLVE, ipv)
C.setopt(C.WRITEDATA, buffer)
try:
C.perform()
result = buffer.getvalue()
try: #validate response
addr.append(ip_address(result.decode('utf8')))
except ValueError:
pass
except pycurl.error:
pass
finally:
C.close()
if len(addr)>1: #IPv4 and IPv6 found
break
return addr
if __name__ == '__main__':
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
from argparse import ArgumentParser
p = ArgumentParser()
p.add_argument('-i','--iface',help='network interface to use')
p = p.parse_args()
addr = getip(p.iface)
print(addr)