Pinterest Stumbleupon Whatsapp
Ads by Google

It’s a common use case scenario: you want to broadcast a public WiFi network for anyone to use, but you’ve got strict requirements that only cat images be permitted. Great news: your Raspberry Pi is a perfect transmoggification machine. Intrigued? Read on.

What You’ll Need

The Theory

This project starts out identical to the Onion Router Build Your Own: Safeplug (Tor Proxy Box) Build Your Own: Safeplug (Tor Proxy Box) Why pay $50 for a Tor proxy box when you can make your own with a Raspberry Pi and USB WiFi dongle? Read More we built a few weeks back. We’ll make the Raspberry Pi into a standard WiFi network first, then place a proxy in the middle. The proxy will be filtering posts through a Perl script, which will replace the images on every HTTP request with cat GIFs from Watch as befuddled users are both intensely frustrated, yet strangely calmed. Here’s the BBC, post-cat modifications.


Making a WiFi Network

Since this part of the tutorial is exactly the same as the DIY Onion Router Build Your Own: Safeplug (Tor Proxy Box) Build Your Own: Safeplug (Tor Proxy Box) Why pay $50 for a Tor proxy box when you can make your own with a Raspberry Pi and USB WiFi dongle? Read More , please follow the instructions there up to the point of Install Tor.

The only small change we need to make is to broadcast an open WiFi network instead of one secured with WPA. Once you’ve followed the setup there, change /etc/hostapd/hostapd.conf, pasting in the following configurations instead. Restart to apply the changes.


You should now have a wireless network being broadcasted on your Raspberry Pi that’s publicly accessible. The rest of this guide will focus on getting the interesting stuff happening.

Ads by Google

If things aren’t working, type:

ifconfig -a

and look for an IP address on wlan0. If one isn’t being assigned on reboot, try the following:

sudo nano /etc/default/ifplugd

Change the following lines from:




Reboot, and verify you’re able to connect to the WiFi network, and access the Internet.

Squid Proxy and IPTables

Start by installing the prerequisites, then create a new routing table. We’ll be serving images from the Raspberry Pi later, so we’ll also need Apache web-server.

sudo apt-get install squid3 bridge-utils apache perl

Paste the following:

iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -t nat -A PREROUTING -i wlan0 -p tcp -m tcp --dport 80 -j DNAT --to-destination
iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128

Save, then exit.

chmod +x
sudo cp /etc/init.d/
sudo update-rc.d start 99


Ignore the warnings, it just means we haven’t complied with some Debian rules (but doesn’t break anything). Lastly, we still have the old iptables rules on boot, so remove the following line from /etc/network/interfaces

up iptables-restore < /etc/iptables.ipv4.nat

(Delete or comment it out)

Then restart. Next We’ll delete the default Squid proxy config, and make a fresh one.

sudo rm /etc/squid3/squid.conf
sudo nano /etc/squid3/squid.conf

Paste the following into the blank file:

cache_mgr pi
cachemgr_passwd pi all
redirect_program /home/pi/
acl manager proto cache_object
acl localhost src ::1
acl to_localhost dst ::1
acl localnet src # RFC1918 possible internal network
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128 transparent
umask 022
cache_mem 128 MB
cache_dir ufs /var/spool/squid3 1500 16 256
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320

Save and exit. Initialise the cache directories with the following command, then edit the script we’ll use to catify all the images:

sudo squid3 -z
nano /home/pi/

Paste in:

$count = 0;
$pid = $$;

open (DEBUG, '>>/tmp/cats.log');
autoflush DEBUG 1;
print DEBUG "########################################################################\n";

while (<>) {
        chomp $_;
        if (m/nosquid/) {
              print DEBUG "Input NOSQUID: $url\n";
              print "$_\n";
              print DEBUG "Output NOSQUID: $_\n";
        elsif ($_ =~ /(.*\.jpg)/i) {
                $url = $1;
                print DEBUG "Input: $url\n";
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.gif", "");
                chmod 0777,"/var/www/images/$pid-$count.gif";
                print "$pid-$count.gif\n";
        elsif ($_ =~ /(.*\.gif)/i) {
                $url = $1;
                print DEBUG "Input: $url\n";
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.gif", "");
                chmod 0777,"/var/www/images/$pid-$count.gif";
                print "$pid-$count.gif\n";
        elsif ($_ =~ /(.*\.png)/i) {
                $url = $1;
                print DEBUG "Input: $url\n";
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.gif", "");
                chmod 0777,"/var/www/images/$pid-$count.gif";
                print "$pid-$count.gif\n";
        elsif ($_ =~ /(.*\.jpeg)/i) {
                $url = $1;
                print DEBUG "Input: $url\n";
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.gif", "");
                chmod 0777,"/var/www/images/$pid-$count.gif";
                print "$pid-$count.gif\n"; 
        else {
                print "$_\n";

Make the script executable, and we also ned to make some directories for it to work with.

sudo chmod +x
sudo mkdir /var/www/images
sudo chmod 777 /var/www/images
sudo usermod -a -G www-data proxy
sudo chown www-data:www-data /var/www
sudo chown www-data:www-data /var/www/images
touch /tmp/cats.log
chmod 777 /tmp/cats.log

You can tail the log at any time with:

tail -f /tmp/cats.log


Try logging into Pinterest, and suddenly all those stupid DIY potted plant projects and mens fashions picks and will be far more appealing.


If you’d rather serve upside down images (credit for the original script to Ex-Parrot, I only modified to deal with some permissions errors), create and paste in the following.

$count = 0;
$pid = $$;
while (<>) {
        chomp $_;
        if ($_ =~ /(.*\.jpg)/i) {
                $url = $1;
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.jpg", "$url");
                system("/usr/bin/mogrify", "-flip","/var/www/images/$pid-$count.jpg");
		chmod 0777,"/var/www/images/$pid-$count.jpg";
                print "$pid-$count.jpg\n";
        elsif ($_ =~ /(.*\.gif)/i) {
                $url = $1;
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.gif", "$url");
                system("/usr/bin/mogrify", "-flip","/var/www/images/$pid-$count.gif");
                chmod 0777,"/var/www/images/$pid-$count.gif";
		print "$pid-$count.gif\n";

        elsif ($_ =~ /(.*\.png)/i) {
                $url = $1;
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.png", "$url");
                system("/usr/bin/mogrify", "-flip","/var/www/images/$pid-$count.png");
                chmod 0777,"/var/www/images/$pid-$count.png";
		print "$pid-$count.png\n";

        elsif ($_ =~ /(.*\.jpeg)/i) {
                $url = $1;
                system("/usr/bin/wget", "-q", "-O","/var/www/images/$pid-$count.jpeg", "$url");
                system("/usr/bin/mogrify", "-flip","/var/www/images/$pid-$count.jpeg");
                chmod 0777,"/var/www/images/$pid-$count.jpeg";
		print "$pid-$count.jpeg\n";
        else {
                print "$_\n";;

Follow the other steps above, changing the filename, to make the script executable, and modify the Squid config to point at instead of Lastly, you’ll need to restart Squid with:

sudo service squid3 restart

The results are pretty awesome in either case. If you make any modifications or improve on these scripts with additional features, please let me in the comments and put a Pastebin link to your script.

Need something more complicated? You could try combining this project with a Raspberry Pi NAS Turn Your Raspberry Pi Into An NAS Box Turn Your Raspberry Pi Into An NAS Box Do you have a couple of external hard drives lying around and a Raspberry Pi? Make a cheap, low powered networked attached storage device out of them. While the end result certainly won't be as... Read More or an always-on torrent downloader How To Turn Your Raspberry Pi Into An Always-On Downloading Megalith How To Turn Your Raspberry Pi Into An Always-On Downloading Megalith Do your part for the global "Linux distribution network" by building a dedicated, secure, torrent-downloading megalith that barely uses 10W of power. It will, of course, be based on a Raspberry Pi. Read More !

  1. baerchen
    March 12, 2015 at 11:15 pm

    will this work with https sites?

  2. Daniel
    March 4, 2015 at 6:24 pm

    This works really well for me, thanks for this!
    I do have a question, though. When I was looking through the /var/www/images folder I found an awful lot of cat images just sitting there. Do these images automatically get overwritten or deleted at a later date, or will I have to delete them manually at intervals? I would rather not slowly fill up more and more space on the Pi...

    • James Bruce
      March 5, 2015 at 6:33 pm

      Excellent point. I really hadn't planned for this to be used for any serious length of time... I guess you'll need a cron script that runs every night and just deletes them all.

  3. alex
    March 4, 2015 at 12:06 pm

    Hi and thank you for this tutorial.

    I followed it and have configured my raspberry as wifi access point. But something is not working like I'd wish to : the connected clients have access to my local network. I would like to only share the internet connection and nothing else on that hotspot... Do you have any idea ?

    • James Bruce
      March 5, 2015 at 6:36 pm

      Apologies Alex, that's beyond my abilities and not something I'd considered at the time. I suspect it's something you need to tweak in the "hostap" config, but I'm not sure exactly what. I'd suggest asking on StackOverflow, but check the existing hostap questions first:

    • alex
      March 6, 2015 at 12:46 pm

      Thanks for your answer James

      I should have searched better. My turn for apologies :-)
      The solution is to add a iptables rule like iptables -A FORWARD -j DROP -d x.x.x.x/xx
      where x.x.x.x/xx (example is the IP range we want to block. All calls to this IP via the wifi hotspot will be blocked.

  4. Spencer
    January 28, 2015 at 6:11 am

    hey james, im wondering if theres anyway that this can be implimented on a windows or linux based laptop, i have a bunch of computers lying around but unfortunately no pi. also could this be injected into a wireless router running an open source firmware?

    • James Bruce
      January 28, 2015 at 7:47 am

      This could all be done almost word-for-word on debian linux (not that I've tried, but there's no reason it shouldnt be). You would still need a compatible wifi card though.

      Straight onto a router? That's beyond me, but i don't see why it couldn't work.

  5. Anonymous
    September 6, 2014 at 10:32 pm

    I haven't figured it out, sorry man

  6. Lee Cunningham
    June 28, 2014 at 3:32 am

    Hey James,
    I tinkered around but couldn't get it to work with apache2 either. I really like the idea and I will keep an eye out if you update this page for the newer apache, but for now am going to try some different projects.

    • Jon Jones
      September 6, 2014 at 5:50 pm

      Did you ever find a workaround for this? I'm stuck at the same place you are with apache. :(

      I've completed the tutorial twice, once on a minimally-modified Raspbian setup, and then on another completely new and untouched installation from the latest source. So far it will broadcast the SSID properly but all my devices get stuck on obtaining an IP address. I'm able to get it to work as a router from the "Build your own Safeplug" tutorial all the way up to the Install Tor steps, but after I complete this tutorial, I can no longer connect. I'm new to Linux and pretty stuck here, and don't know what to troubleshoot. Any help would be appreciated. :

  7. Lee Cunningham
    June 27, 2014 at 4:37 pm

    Yeah i am using a brand new install of raspbian, the 6/20/14 version. I changed your line to sudo apt-get install squid3 bridge-utils apache2 perl which doesn't give me an error and starts downloading, I will see if this works

  8. Lee Cunningham
    June 26, 2014 at 11:39 pm

    I thought this was a great idea and I tried to use it but could not get it to work. First of all I have an Edimax wifi dongle that uses RTL8188CUS chipset so I had to do a workaround with a different driver to get it set up as a normal hotspot. I was able to do this and attempted starting from the Squid proxy and IP tables section, but running the command

    sudo apt-get install squid3 bridge-utils apache perl

    gave me the following error:

    Package apache is not available, but is referred to by another package.
    This may mean that the package is missing, has been obsoleted, or
    is only available from another source.

    I attempted to download apache2 and squid3 separately and complete the instructions but I cannot connect to the internet at all through the pi router now. I don't know a lot about this stuff and I assume that the way I got squid and apache is the problem, but I also have a different baseline router setup than your instructions, so I think there are too many variables and I don't know enough to troubleshoot it. Cool idea though, wish I could get it to work, if you have any suggestions I would be happy to hear them!

    • James B
      June 27, 2014 at 7:26 am

      Hi Lee - are you running on a fresh install of Raspian? Apache should definately be available. It sounds like you've got the wifi thing worked out fine, but I cant see any reason for that error I'm afraid.

    • Max
      February 19, 2015 at 8:48 pm

      I had the same problem. I just replaced Apache with Apache2. That worked fine

  9. Daniel
    June 22, 2014 at 12:46 am

    after changing the this cat proxy, the traffic runs not longer over tor proxy :(

    what i made wrong?
    any ideas? can anybody help?

    best regards,

    • James Bruce
      June 22, 2014 at 7:24 am

      Thats not wrong, this is a different tutorial. I'm afraid I'm not sure how to make the Tor redirection and cat proxy scripts stack together.

  10. dragonmouth
    June 19, 2014 at 11:38 am

    I assume that with few minor tweaks, this write-up can be used to limit the transmission to any particular subject.

    • James Bruce
      June 20, 2014 at 9:59 am

      The neighbourhood cats have reliably informed me that this should never be used with dog pictures though.

    • dragonmouth
      June 20, 2014 at 10:28 am

      I was actually thinking of mice and rats.

  11. DaTruth
    June 19, 2014 at 11:23 am


    • Adam
      June 19, 2014 at 9:11 pm

      So you can setup an open wireless network, and annoy the people that try to freeload. It's a lot like trolling. Think of how frustrating it would be for someone that's trying to look up pron.

    • rob
      July 11, 2014 at 12:18 pm

      Why not?!

Leave a Reply

Your email address will not be published. Required fields are marked *