Intercepting HTTP traffic with Squid

Squid is a caching proxy that can be used for a variety of purposes. Following on from an earlier post, this post is going to look at using Squid to intercept HTTP traffic on a wireless access point.

Installation

Squid is part of the standard Debian repositories and can be installed with apt-get:

sudo apt-get update
sudo apt-get install squid3

Intercepting traffic

Once squid is install, /etc/squid3/squid.conf needs to be updated. Start by allowing connections from the local network:

acl localnet src 192.168.0.0/16       # RFC1918 possible internal network

Then put the http port into intercept mode:

http_port 3128 intercept

Once the configuration has been updated, restart Squid to pick up the changes, and enable the service to make sure it starts at boot:

systemctl restart squid3.service
systemctl enable squid3.service

The final step is to redirect inbound traffic on the wireless interface to Squid. This can be done with the following iptables rule:

iptables -t nat -A PREROUTING -i wlan0 -p tcp \
  --destination-port 80 -j REDIRECT --to-port 3128

Note: don't forget to run iptables-save if you want to make the rule persistent.

Replacing images

Once Squid is intercepting connections, it's possible to manipulate HTTP traffic. For example you could replace all JPG images with a cat:

WebMD before and after images are replaced with a cat.

Cat photograph by and copyright © of DrL. This image is licensed under the Creative Commons Attribution-Share Alike 2.5 Generic license and can be found on Wikimedia Commons. The website being modified is http://pets.webmd.com.

The first thing to do is setup and configure Apache to serve a cat image. This can be done with the following commands:

apt-get install apache2
systemctl enable apache2.service
systemctl start apache2.service
curl -o /var/www/html/cat.jpg \
  https://upload.wikimedia.org/wikipedia/commons/4/4c/Blackcat-Lilith.jpg

Once Apache is up and running add the following configuration to /etc/squid3/squid.conf:

url_rewrite_program /etc/squid3/more_cats.py

This will tell Squid to run more_cats.py which will allow us to manipulate HTTP requests. The more_cats.py script should look similar to the following:

#!/usr/bin/env python
"""Squid rewrite program to replace JPGs with a cat"""

import sys
from urlparse import urlparse

def modify_url(line):
    """Modify URLs ending in .jpg to request a cat photo"""
    request_url = urlparse(line.split(' ')[0])
    new_url = '\n'
    if request_url.path.endswith('.jpg'):
        new_url = 'http://127.0.0.1/cat.jpg\n'
    return new_url

def main():
    """Read info from Squid on stdin"""
    while True:
        line = sys.stdin.readline().strip()
        new_url = modify_url(line)
        sys.stdout.write(new_url)
        sys.stdout.flush()

if __name__ == '__main__':
    main()

Note: refer to the Squid documentation for more information on writing rewrite programs.

Finally Squid can be restarted and all files ending in .jpg will be replace with a cat as shown above:

systemctl restart squid3

More scripts

Rewrite scripts are obviously very powerful and let you do a wide range of things to HTTP traffic. GitHub is a good place to look for inspiration.

HTTPS adoption

The obvious way to prevent HTTP traffic being manipulated is end to end encryption. HTTPS is becoming far more common, and recently passed the half way mark:

Yesterday, for the first time, @Mozilla telemetry shows more than 50% of page loads were encrypted with HTTPS. - tweet from Let's Encrypt (@letsencrypt), 14 Oct 2016

If you don't already use it, I would highly recommend HTTPS Everywhere. Finally if you do manage a website, consider enabling HTTPS if you haven't already!