This post continues from Part 6: Remote Access
This is another one of those things that isn't strictly necessary, but has some minor benefits and sets you up to do other cool things. A proxy is sort of like a relay. A client sends a request to the proxy, the proxy relays that request to the server hosting the content, and then the proxy sends the response back to the client. Since it sits in the middle of the client and the server the proxy can log and manipulate the traffic going through it. It's not even necessary for the client to know the traffic is going through a proxy, a setup known as transparent proxying. As long as you control the network traffic you can route the traffic to a transparent proxy.
One of the most widely used proxies out there is called Squid. Chances are every public network you've ever connected to, including your own ISP's, has a Squid box running on it somewhere. And there's good reason. Squid is what's known as a caching web proxy. This means it keeps a copy of the things that get proxied through it. If another request is made for the same content it can return the copy it already has stored. By avoiding making identical requests over and over the proxy can make requests faster and save a ton of bandwidth.
Squid is capable of proxying pretty much any type of network traffic, but it's most commonly used as an HTTP proxy. With the web moving to HTTPS, its effectiveness is declining but it still serves its purpose. It's not that it can't proxy HTTPS, but it would need to forge certificates which would cause scary security warnings to users and effectively break web security. Nevertheless, there's still a fair bit of HTTP traffic around so let's set up a Squid proxy to cache some of it.
Squid Installation and Configuration
First up, install Squid:
$> sudo apt-get install squid
Next you'll need to edit a few options in its configuration file. Be warned, the configuration file is a 5000+ line behemoth. You don't need to touch 99% of it. Just search over the file and find the lines you need to change.
/etc/squid/squid.conf and set the port the proxy will run on using the
http_port 3129 http_port 3128 intercept
This puts a regular HTTP proxy on port 3129 as well as enables a transparent (intercepting) proxy on port 3128. The next step is to configure which IP ranges are allowed to access the proxy. Create a network with an
acl lan src 192.168.0.0/24
And then grant access to that network:
http_access allow lan
Also make sure there is a deny rule to deny access from all other networks
http_access deny all
To allow outgoing proxy traffic to port 80 (HTTP) make sure port 80 is in the
Safe_ports ACL with a line like:
acl Safe_ports port 80
And then disable traffic on all non-safe ports:
http_access deny !Safe_ports
Lastly, you'll should create a disk cache for Squid to use. By default it will cache to memory, but if you want better cache hit rates you'll need to start caching things to disk. Add a line like:
cache_dir ufs /var/spool/squid 1024 16 256
This creates a disk cache at
/var/spool/squid with a maximum size of 1GB (1024 is the size of the cache in MB). You can adjust it to be larger or smaller to trade off hit rate for disk space.
Restart Squid for the new settings to take effect:
$> sudo systemctl restart squid
Routing Traffic to Squid
Squid should be ready to go now, but it's not actually receiving any traffic. We need to redirect normal web traffic to the proxy port for it to get run through Squid. This can be done with a
iptables destination NAT rule:
$> sudo iptables -t nat -A PREROUTING -i enx0050b617c34f \ -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:3128
This rule matches HTTP traffic (
-p tcp -m tcp --dport 80) coming from the LAN interface (
-i enx0050b617c34f) and applies a destination NAT (
DNAT) rule. That rule modifies the destination IP address and port before sending the packet through the routing pipeline (since it's in the
PREROUTING chain). In this case we're re-routing the packet to the Squid host and port.
Squid should now be automagically proxying and caching HTTP traffic from your LAN. You can test by making a request and looking for the HTTP headers Squid appends to the response:
$> curl -I http://neverssl.com HTTP/1.1 200 OK ... X-Cache: MISS from localhost.localdomain X-Cache-Lookup: MISS from localhost.localdomain:3129 Via: 1.1 localhost.localdomain (squid/3.5.12) ...
If the request went through Squid you should see some
X-Cache headers. In this particular example you can see the request was proxied but it could not be served from cache (it was a cache "miss"). Once you have traffic flowing through Squid there are a bunch more things you could try. You can mess with headers, modify content, and generally wreak havoc on your network's traffic. Have fun.
For the last post of this series we'll look at adding monitoring and visualization to your router. See you next week.