How To Make a WiFi Network That Only Transmits Cat Pictures With A Raspberry Pi

How To Make a WiFi Network That Only Transmits Cat Pictures With A Raspberry Pi

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

  • Raspberry Pi model B (New to Raspberry Pi? Here’s everything a beginner would need to know, in video form)
  • 4GB or larger SD card
  • Ethernet cable
  • Compatible WiFi adapter
  • MicroUSB power cable and adapter

The Theory

This project starts out identical to the Onion Router 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 TheCatAPI.com. Watch as befuddled users are both intensely frustrated, yet strangely calmed. Here’s the BBC, post-cat modifications.

post-cat-bbc

Making a WiFi Network

Since this part of the tutorial is exactly the same as the DIY Onion Router, 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.

interface=wlan0  driver=nl80211  ssid=Kittens  hw_mode=g  channel=6  auth_algs=1  wmm_enabled=0

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.

If things aren’t working, type:

Ads by Google
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:

INTERFACES="auto"  HOTPLUG_INTERFACES="all"  

to:

INTERFACES="eth0"  HOTPLUG_INTERFACES="eth0"  

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  nano iptables.sh  

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 192.168.42.1:3128  iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128  

Save, then exit.

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

iptable-sh-error

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/cats.pl  acl manager proto cache_object  acl localhost src 127.0.0.1/32 ::1  acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1  acl localnet src 192.168.42.0/24 # 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  acl CONNECT method CONNECT  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/cats.pl  

Paste in:

#!/usr/bin/perl  $|=1;  $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", "http://thecatapi.com/api/images/get?format=src&type=gif&nosquid");                  chmod 0777,"/var/www/images/$pid-$count.gif";                  print "http://127.0.0.1/images/$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", "http://thecatapi.com/api/images/get?format=src&type=gif&nosquid");                  chmod 0777,"/var/www/images/$pid-$count.gif";                  print "http://127.0.0.1/images/$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", "http://thecatapi.com/api/images/get?format=src&type=gif&nosquid");                  chmod 0777,"/var/www/images/$pid-$count.gif";                  print "http://127.0.0.1/images/$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", "http://thecatapi.com/api/images/get?format=src&type=gif&nosquid");                  chmod 0777,"/var/www/images/$pid-$count.gif";                  print "http://127.0.0.1/images/$pid-$count.gif\n";           }          else {                  print "$_\n";          }          $count++;  }    

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

sudo chmod +x cats.pl  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  

tail-log

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

better-pinterest

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 upsidedown.pl and paste in the following.

#!/usr/bin/perl  $|=1;  $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 "http://127.0.0.1/images/$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 "http://127.0.0.1/images/$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 "http://127.0.0.1/images/$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 "http://127.0.0.1/images/$pid-$count.jpeg\n";          }          else {                  print "$_\n";;          }          $count++;  }  

Follow the other steps above, changing the filename, to make the script executable, and modify the Squid config to point at upsidedown.pl instead of cats.pl. 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 or an always-on torrent downloader!

Join live MakeUseOf Groups on Grouvi App Join live Groups on Grouvi
Raspberry Pi Projects
Raspberry Pi Projects
15 Members
DIY Tech Projects
DIY Tech Projects
11 Members
Arduino Projects
Arduino Projects
12 Members
Ads by Google
Comments (23)
  • baerchen

    will this work with https sites?

  • Daniel

    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

      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.

  • alex

    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

      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: http://stackoverflow.com/search?q=hostap

    • alex

      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 192.168.0.2/255) is the IP range we want to block. All calls to this IP via the wifi hotspot will be blocked.

  • Spencer

    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

      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.

  • Anonymous

    I haven’t figured it out, sorry man

Load 10 more
Affiliate Disclamer

This review may contain affiliate links, which pays us a small compensation if you do decide to make a purchase based on our recommendation. Our judgement is in no way biased, and our recommendations are always based on the merits of the items.

For more details, please read our disclosure.
Affiliate Disclamer

This review may contain affiliate links, which pays us a small compensation if you do decide to make a purchase based on our recommendation. Our judgement is in no way biased, and our recommendations are always based on the merits of the items.

For more details, please read our disclosure.