Wednesday, January 17, 2018

Writing IPv6 Apps: Python Webserver

by Craig Miller


Moving to IPv6 starts at home. Applications have to speak IPv6 as well as the network. The good news is that there is lots of software available which already supports IPv6. Unfortunately, there is much more that doesn't.

For example, a Python-based webserver. Certainly not ready for a production network, but handy as a learning tool about how easy it can be to support IPv6 in your application.

Why Python? Python is a wonderful programming language, and getting only better with version 3. There are libraries for most needs, including one which serves up the web. And it runs just about anywhere that Python runs (Windows, Linux, BSD, Mac, Pi, ODROID, etc)

Python module SimpleHTTPServer


The python module SimpleHTTPServer supports IPv4 out of the box with the simple command:
python -m SimpleHTTPServer
However it does not support IPv6. There is no one-line equivalent to support IPv6, so a small script is required.

Looking at the code


The ipv6-httpd script is a short script supporting both IPv4 and IPv6. Looking at the following sections:
  1. Initialization of the HTTPServer object (from SimpleHTTPServer library)
  2. Class creation (of HTTPServerV6) to support IPv6
As with all Python scripts, the details roll backwards from the bottom. Initialization occurs in main
def main():
    global server
    server = HTTPServerV6(('::', listen_port), MyHandler)
    print('Listening on port:' + str(listen_port) + '\nPress ^C to quit')
    server.serve_forever()
    os._exit(0)

The IPv6 part


In order to support IPv6, we use a bit of object oriented inheritance trickery to modify the default of an existing class HTTPServer
class HTTPServerV6(HTTPServer):
    address_family = socket.AF_INET6
This creates a new class (which is used in our server ) with the address_family set to AF_INET6 (aka IPv6). This two-line change to the script transforms an IPv4-only script into an application that also supports IPv6.

Running the code


Now that we have a server which supports both IPv4 and IPv6, all we need to do is cd to the directory we wish to share, and start the server
$ cd public/
$ ~/bin/ipv6-httpd.py 
Listening on port:8080
Press ^C to quit
2001:db8:ebbd:0:4d18:71cd:b814:9508 - - [09/Jul/2017 11:49:41] "GET / HTTP/1.1" 200 -
^CCaught SIGINT, dying

The webserver log is sent to standard out (stdout), and can be redirected to a file if desired. In the above example, an IPv6 client ..:9508 requests an index, then the server is terminated with a ^C.
Want to server from a different directory? Stop the server, cd to another directory, and restart the server, it will now serve files from the new current working directory (cwd) location.

Security (or lack there of)


This example is a personal webserver, designed to be started and stopped whenever you need it. It is NOT a production quality webserver that you should put on the internet. However it shows that supporting IPv6 doesn't have to be a hardship.

Adding IPv6 Support to your App


As you can see, it doesn't have to be difficult to add IPv6 to your apps, you just need to give it some thought when planning your App. By adding IPv6, you will future proof your App by being ready for the future of the Internet.