At times, it will be necessary for many applications to look-up the location of the IP addresses. For example, many website owners can be interested in tracking the location of their visitors and in classifying their IPs according to criteria, such as country, city, and so on. There is a third-party library called python-geoip, which has a robust interface for giving you the answer to your IP location query. This library is provided by MaxMind, which also provides the option for shipping a recent version of the Geolite2 database as the python-geoip-geolite2
package. This includes the GeoLite2 data created by MaxMind, which is available at www.maxmind.com under the creative commons Attribution-ShareAlike 3.0 Unported License. You can also buy a commercial license from their website.
Let's see an example of how to use this Geo-lookup library.:
import socket from geoip import geolite2 import argparse if __name__ == '__main__': # Setup commandline arguments parser = argparse.ArgumentParser(description='Get IP Geolocation info') parser.add_argument('--hostname', action="store", dest="hostname", required=True) # Parse arguments given_args = parser.parse_args() hostname = given_args.hostname ip_address = socket.gethostbyname(hostname) print("IP address: {0}".format(ip_address)) match = geolite2.lookup(ip_address) if match is not None: print('Country: ',match.country) print('Continent: ',match.continent) print('Time zone: ', match.timezone)
This script will show an output similar to the following:
$ python 6_3_geoip_lookup.py --hostname=amazon.co.uk IP address: 178.236.6.251 Country: IE Continent: EU Time zone: Europe/Dublin
You can find more information about this package from the developer's website, which is at http://pythonhosted.org/python-geoip/.
The IP address can be translated into human readable strings called domain names. DNS is a big topic in the world of networking. In this section, we will create a DNS client in Python, and see how this client will talk to the server by using Wirshark.
A few DNS cleint libraries are available from PyPI. We will focus on the dnspython
library, which is available at http://www.dnspython.org/. You can install this library by using either the easy_install
command or the pip
command:
$ pip install dnspython
Making a simple query regarding the IP address of a host is very simple. You can use the dns.resolver
submodule, as follows:
import dns.resolver answers = dns.resolver.query('python.org', 'A') for rdata in answers: print('IP', rdata.to_text())
If you want to make a reverse look-up, then you need to use the dns.reversename
submodule, as shown here:
import dns.reversename name = dns.reversename.from_address("127.0.0.1") print name print dns.reversename.to_address(name)
Now, let's create an interactive DNS client script that will do a complete look-up of the possible records, as shown here:
import dns.resolver if __name__ == '__main__': loookup_continue = True while loookup_continue: name = input('Enter the DNS name to resolve: ') record_type = input('Enter the query type [A/MX/CNAME]: ') answers = dns.resolver.query(name, record_type) if record_type == 'A': print('Got answer IP address: %s' %[x.to_text() for x in answers]) elif record_type == 'CNAME': print('Got answer Aliases: %s' %[x.to_text() for x in answers]) elif record_type == 'MX': for rdata in answers: print('Got answers for Mail server records:') print('Mailserver', rdata.exchange.to_text(), 'has preference', rdata.preference) print('Record type: %s is not implemented' %record_type) lookup_more = input("Do you want to lookup more records? [y/n]: " ) if lookup_more.lower() == 'n': loookup_continue = False
If you run this script with some input, then you will have an output similar to the following:
$ python 6_4_dns_client.py Enter the DNS name to resolve: google.com Enter the query type [A/MX/CNAME]: MX Got answers for Mail server records: Mailserver alt4.aspmx.l.google.com. has preference 50 Got answers for Mail server records: Mailserver alt2.aspmx.l.google.com. has preference 30 Got answers for Mail server records: Mailserver alt3.aspmx.l.google.com. has preference 40 Got answers for Mail server records: Mailserver aspmx.l.google.com. has preference 10 Got answers for Mail server records: Mailserver alt1.aspmx.l.google.com. has preference 20 Do you want to lookup more records? [y/n]: y Enter the DNS name to resolve: www.python.org Enter the query type [A/MX/CNAME]: A Got answer IP address: ['185.31.18.223'] Do you want to lookup more records? [y/n]: y Enter the DNS name to resolve: pypi.python.org Enter the query type [A/MX/CNAME]: CNAME Got answer Aliases: ['python.map.fastly.net.'] Do you want to lookup more records? [y/n]: n
In previous chapters, perhaps you noticed how we captured network packets between the client and the server by using Wireshark. Here is an example of the session capturing, while a Python package was being installed from PyPI:
In Wireshark you can specify port 53
by navigating to Capture | Options | Capture filter. This will capture all the DNS packets that were sent to/from your machine.
As you can see in the following screenshot, the client and the server have several request/response cycles the DNS records. It was started with a standard request for the host's address (A) and it was followed by a suitable response.
If you look deep inside a packet, then you can see the request format of the response from the server, as shown in the following screenshot: