This guide will show you how to setup a transparent Squid proxy with HTTPS support directly on DD-WRT. Let’s dive right in!
NOTE: Links will open in a new tab\window.
Prerequisites
The only requirements are that you have a SSH connection and a working Optware installation. Visit the DD-WRT Optware1 page for additional information on installing Optware. In short, you need to mount /opt and run the bootstrap command. (Bootstrap may only be available in Kong builds.) How you mount /opt does not matter as long as the user nobody has read and write access. I won’t go into too much detail but, I have used a CIFS mount for mine:
/sbin/insmod /lib/modules/`uname -r`/kernel/crypto/md4.ko /sbin/insmod /lib/modules/`uname -r`/kernel/crypto/md5.ko /sbin/insmod /lib/modules/`uname -r`/kernel/crypto/des_generic.ko /sbin/insmod /lib/modules/`uname -r`/kernel/fs/fscache/fscache.ko /sbin/insmod /lib/modules/`uname -r`/kernel/fs/cifs/cifs.ko /bin/mount.cifs //192.168.x.x/ddwrt /opt -o uid=nobody,username=user,password=pass
NOTE: fscache.ko must be loaded before cifs.ko.
Getting Started
Once you have an SSH connection and Optware is properly functioning, install Squid. You may also want to install nano if you prefer nano over vi like I do:
opkg install squid opkg install nano
Create Missing Directories
Now that we have Squid installed, we need to create a few directories before Squid will run. The default installation is a bit broken and needs the following directories to be created:
mkdir /dev/shm chown nobody /dev/shm mkdir /opt/var/run/ mkdir /opt/etc/squid/ssl mkdir /opt/etc/squid/ssl/cacerts
IMPORTANT: As previously mentioned, make sure the user nobody has read and write access to all directories in /opt. If you are mounting via CIFS, ensure you use uid=nobody in your mount options. This will save you a lot of headaches.
My device does not create the /dev/shm/ directory so I create it and change the owner to nobody. You should check your device to see if the directory exists before doing this.
Certificates, Certificates and more Certificates
Now that we have our directories created, we need to initialize the certificate cache:
/opt/lib/squid/ssl_crtd -c -s /opt/etc/squid/ssl/ssl_db/
Next you will need to generate a self-signed root certificate and copy the certificate and key to /opt/etc/squid/ssl/. There are plenty of guides on how to generate your own certificate so, I will not be going into detail on this. However, if you need a place to start, you may visit the Squid Dynamic SSL Certificate Generation2 page where you can find a few clues as to the correct commands to use. Just be sure to have the certificate and key separated or change the Squid configuration file to point to a combined certificate and key file.
Squid doesn’t come with any Global Root Certificates by default so you’ll need to copy our own into /opt/etc/squid/ssl/cacerts/. There are several ways you can obtain Root Certificates. The easiest method is to copy them from /etc/ssl/certs/ on a Debian based system. You may also download them from Curl’s CA Extract4 page.
Once you have your Root Certificate generated, create a DER certificate and import it into your web browser. Visit the Squid Dynamic SSL Certificate Generation2 page for additional information on creating the DER certificate.
Modern Ciphers
It’s a good idea to generate a DH/EDH cipher and copy it to /opt/etc/squid/ssl/. This will help to harden your Squid connections. If you have a version of Squid less than 3.5.27, you may need to use a different directive in the Squid configuration file. Visit the link above to obtain the relevant directive.
Visit the Squid Modern DH/EDH Ciphers3 page for additional information.
If you don’t want to use a modern cipher then you can skip this section but, be sure to change the Squid configuration file accordingly.
Squid Configuration File
Add the following configuration directives to the end of /opt/etc/squid/squid.conf:
# If you have 64 MB device RAM you can use 16 MB cache_mem, default is 8 MB cache_mem 8 MB maximum_object_size_in_memory 100 KB maximum_object_size 32 MB # Leave coredumps in the first cache dir coredump_dir /opt/var/cache/squid # Set the cache directory location and size cache_dir aufs /opt/var/cache/squid 500 16 256 # Listen on port 3130 for https https_port 3130 intercept ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/opt/etc/squid/ssl/cert.pem key=/opt/etc/squid/ssl/key.pem tls-dh=prime256v1:/opt/etc/squid/ssl/tls-dh.pem # Listen on port 3129 for http http_port 3129 intercept # Squid normally listens to port 3128 for direct browser connections # Squid refuses to run if port 3128 is missing - giving a "no forwarding proxy configured" error http_port 3128 # Visit https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit#Troubleshooting for additional information on the following version differences # For Squid 3.5.x only sslcrtd_program /opt/lib/squid/ssl_crtd -s /opt/etc/squid/ssl/ssl_db -M 4MB sslcrtd_children 5 # For Squid 4 and newer #tls_outgoing_options options=NO_SSLv3,SINGLE_DH_USE,SINGLE_ECDH_USE sslproxy_options NO_SSLv2,NO_SSLv3,SINGLE_ECDH_USE sslproxy_cipher EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS sslproxy_capath /opt/etc/squid/ssl/cacerts # Replace this section with your own ssl_bump and acl rules # Visit https://wiki.squid-cache.org/Features/SslPeekAndSplice for additional information # NOTE: You should splice banking websites acl step1 at_step SslBump1 acl excludeServerFromProxy ssl::server_name .example.org ssl_bump peek step1 ssl_bump splice excludeServerFromProxy ssl_bump stare all
The important parts here are the cache size, ports, rules and file paths. Ensure they are what you expect them to be before continuing. As there are so many possible configuration directives, I will not be going into further detail about the configuration directives and what they do. Visit the Squid Configuration Directives Documentation5 page for additional information.
Cache Building
Next, build the cache that Squid will use:
squid -z
You should receive similar output to the following:
2019/01/05 15:43:09 kid1| Set Current Directory to /opt/var/cache/squid 2019/01/05 15:43:09 kid1| Creating missing swap directories 2019/01/05 15:43:09 kid1| /opt/var/cache/squid exists 2019/01/05 15:43:09 kid1| Making directories in /opt/var/cache/squid/00 2019/01/05 15:43:09 kid1| Making directories in /opt/var/cache/squid/01 2019/01/05 15:43:10 kid1| Making directories in /opt/var/cache/squid/02 2019/01/05 15:43:10 kid1| Making directories in /opt/var/cache/squid/03 2019/01/05 15:43:10 kid1| Making directories in /opt/var/cache/squid/04 2019/01/05 15:43:11 kid1| Making directories in /opt/var/cache/squid/05 2019/01/05 15:43:11 kid1| Making directories in /opt/var/cache/squid/06 2019/01/05 15:43:11 kid1| Making directories in /opt/var/cache/squid/07 2019/01/05 15:43:12 kid1| Making directories in /opt/var/cache/squid/08 2019/01/05 15:43:12 kid1| Making directories in /opt/var/cache/squid/09 2019/01/05 15:43:12 kid1| Making directories in /opt/var/cache/squid/0A 2019/01/05 15:43:13 kid1| Making directories in /opt/var/cache/squid/0B 2019/01/05 15:43:13 kid1| Making directories in /opt/var/cache/squid/0C 2019/01/05 15:43:13 kid1| Making directories in /opt/var/cache/squid/0D 2019/01/05 15:43:14 kid1| Making directories in /opt/var/cache/squid/0E 2019/01/05 15:43:14 kid1| Making directories in /opt/var/cache/squid/0F
If you do not get the above output, ensure that file permissions are correct and that /opt/var/cache/squid/ exists. REMEMBER: The user nobody must have read and write access.
The Virgin Voyage
Now it is finally time to try to start Squid. Let’s start Squid in a special debugging mode so that we can see what is happening in case something goes wrong.
squid -d 1
You should receive output similar to the following:
2019/01/05 15:44:30 kid1| Set Current Directory to /opt/var/cache/squid 2019/01/05 15:44:30 kid1| Starting Squid Cache version 3.5.27 for arm-openwrt-linux-gnu... 2019/01/05 15:44:30 kid1| Service Name: squid 2019/01/05 15:44:30 kid1| Process ID 23227 2019/01/05 15:44:30 kid1| Process Roles: worker 2019/01/05 15:44:30 kid1| With 1024 file descriptors available 2019/01/05 15:44:30 kid1| Initializing IP Cache... 2019/01/05 15:44:30 kid1| DNS Socket created at 0.0.0.0, FD 6 2019/01/05 15:44:30 kid1| Adding nameserver 192.168.x.x from /etc/resolv.conf 2019/01/05 15:44:30 kid1| helperOpenServers: Starting 5/5 'ssl_crtd' processes 2019/01/05 15:44:30 kid1| Local cache digest enabled; rebuild/rewrite every 3600/3600 sec 2019/01/05 15:44:30 kid1| Logfile: opening log stdio:/dev/null 2019/01/05 15:44:30 kid1| Swap maxSize 51200000 + 262144 KB, estimated 3958626 objects 2019/01/05 15:44:30 kid1| Target number of buckets: 197931 2019/01/05 15:44:30 kid1| Using 262144 Store buckets 2019/01/05 15:44:30 kid1| Max Mem size: 262144 KB 2019/01/05 15:44:30 kid1| Max Swap size: 51200000 KB 2019/01/05 15:44:30 kid1| Rebuilding storage in /opt/var/cache/squid (no log) 2019/01/05 15:44:30 kid1| Using Least Load store dir selection 2019/01/05 15:44:30 kid1| Set Current Directory to /opt/var/cache/squid 2019/01/05 15:44:30 kid1| Finished loading MIME types and icons. 2019/01/05 15:44:30 kid1| HTCP Disabled. 2019/01/05 15:44:30 kid1| Pinger socket opened on FD 25 2019/01/05 15:44:30 kid1| Squid plugin modules loaded: 0 2019/01/05 15:44:30 kid1| Adaptation support is off. 2019/01/05 15:44:30 kid1| Accepting NAT intercepted HTTP Socket connections at local=0.0.0.0:3129 remote=[::] FD 21 flags=41 2019/01/05 15:44:30 kid1| Accepting HTTP Socket connections at local=0.0.0.0:3128 remote=[::] FD 22 flags=9 2019/01/05 15:44:30 kid1| Accepting NAT intercepted SSL bumped HTTPS Socket connections at local=0.0.0.0:3130 remote=[::] FD 23 flags=41 2019/01/05 15:44:34 kid1| Done scanning /opt/var/cache/squid dir (0 entries) 2019/01/05 15:44:34 kid1| Finished rebuilding storage from disk. 2019/01/05 15:44:34 kid1| 0 Entries scanned 2019/01/05 15:44:34 kid1| 0 Invalid entries. 2019/01/05 15:44:34 kid1| 0 With invalid flags. 2019/01/05 15:44:34 kid1| 0 Objects loaded. 2019/01/05 15:44:34 kid1| 0 Objects expired. 2019/01/05 15:44:34 kid1| 0 Objects cancelled. 2019/01/05 15:44:34 kid1| 0 Duplicate URLs purged. 2019/01/05 15:44:34 kid1| 0 Swapfile clashes avoided. 2019/01/05 15:44:34 kid1| Took 4.61 seconds ( 0.00 objects/sec). 2019/01/05 15:44:34 kid1| Beginning Validation Procedure 2019/01/05 15:44:34 kid1| Completed Validation Procedure 2019/01/05 15:44:34 kid1| Validated 0 Entries 2019/01/05 15:44:34 kid1| store_swap_size = 0.00 KB 2019/01/05 15:44:35 kid1| storeLateRelease: released 0 objects
Issue the following command to check if Squid has successfully started:
ps | grep -i squid
This will give you output similar to:
23225 root 11236 S squid -d 1 23227 nobody 16680 S {squid} (squid-1) -d 1 23229 nobody 3452 S {ssl_crtd} (ssl_crtd) -s /opt/etc/squid/ssl/ssl_db -M 4MB 23230 nobody 3364 S {ssl_crtd} (ssl_crtd) -s /opt/etc/squid/ssl/ssl_db -M 4MB 23231 nobody 3364 S {ssl_crtd} (ssl_crtd) -s /opt/etc/squid/ssl/ssl_db -M 4MB 23232 nobody 3364 S {ssl_crtd} (ssl_crtd) -s /opt/etc/squid/ssl/ssl_db -M 4MB 23233 nobody 3364 S {ssl_crtd} (ssl_crtd) -s /opt/etc/squid/ssl/ssl_db -M 4MB 23277 root 1196 S grep squid
If you do not get any output other than the grep line, then something is wrong with Squid. You should check the output from the previous squid -d 1 command for clues as to what went wrong.
iptables (Yay!)
NOTE: If you don’t want to setup Squid to be a transparent proxy, then skip this step and configure your web browser’s proxy settings to send traffic to port 3128. (You still need to open the port with the first iptables line from below.) You may also want to remove the relevant http_port/https_port lines from your configuration file for the other ports. Be aware that you’ll lose the HTTPS proxy function as browsers do not yet have good support for direct communication to an HTTPS proxy. Hence why you should only be using one port with this type of configuration.
Now that we have Squid up and running, we can redirect our traffic to the correct port so that Squid can receive it. Be sure your configured ports match the redirection rule’s ports. If you forward non-https traffic to Squid’s https port, it will be refused. Also, make sure that you are using the correct interface — in this case br0.
Issue the following commands to add the redirect rules using iptables:
iptables -I INPUT -p tcp --dport 3128 -j ACCEPT iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 3129 iptables -I INPUT -p tcp --dport 3129 -j ACCEPT iptables -t nat -A PREROUTING -i br0 -p tcp --dport 443 -j REDIRECT --to-port 3130 iptables -I INPUT -p tcp --dport 3130 -j ACCEPT
Lift off!
You made it! Congratulations, you should now be able to happily browse the Internet at decent first-page-load speeds and blazing fast subsequent-page-load speeds. If you are unable to pleasantly browse the worldwide inter-webs, scroll to the Notes and Comments section at the end of this article for some useful hints.
Making it Permanent
At this point, you should have a fully functioning Squid installation. The only problem is, it is temporary. When you restart your router, Squid will not be started automatically and special directories will once again be missing.
To fix this, add the following to your startup script by opening your router’s DD-WRT configuration page (usually at http://192.168.0.1) and navigating to the Administration Tab -> Commands Tab.
Input the following into the Command Shell field:
/bin/mkdir /dev/shm /bin/chown nobody /dev/shm /opt/sbin/squid &
Click on Save Startup to save your changes.
NOTE: If you are using a CIFS mount, you should add the relevant commands from the top of this article to your startup script as well.
After you have saved the startup script, input the following into the Command Shell field to add the iptables commands to the firewall script:
iptables -I INPUT -p tcp --dport 3128 -j ACCEPT iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 3129 iptables -I INPUT -p tcp --dport 3129 -j ACCEPT iptables -t nat -A PREROUTING -i br0 -p tcp --dport 443 -j REDIRECT --to-port 3130 iptables -I INPUT -p tcp --dport 3130 -j ACCEPT
Click on Save Firewall to save your changes.
Finish Line!
Now it is time reboot and marvel at your work. If all is good, you should be able to browse the Internet without problems but, we still need to verify the proxy is actually working.
To do this, visit https://example.com in your web browser. Open the properties for the certificate of the website and look for your Root Certificate’s information to be populated under the Issued by field. If your Root Certificate’s information is not present, then your traffic is not being proxied correctly.
You’ll also want to visit https://www.ssllabs.com/ssltest/viewMyClient.html6. This site can tell you a lot about your connection to the outside world when it comes to certificate support. Visit https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit#Hardening7 for additional information on what to expect.
Fine Tuning
Some fine tuning needs to be done after you have a working installation. You’ll probably want to change the acl directives at the end of your Squid configuration file to be what you want.
Specifically, you need to change .example.org in the acl line to a banking website or a website that you do not want to be included in the proxy. You may add additional acl lines to exclude multiple sites.
You may also want to enable logging. To do this, edit the configuration file and remove the following lines:
access_log none cache_log /dev/null cache_store_log stdio:/dev/null logfile_rotate 0 logfile_daemon /dev/null
Create the /opt/var/logs/ directory:
mkdir /opt/var/logs
Next, add a cronjob to rotate the logs by visiting your router’s DD-WRT configuration page (usually at http://192.168.0.1) and navigating to Administration Tab -> Management Tab.
Input the following into the Cron section:
0 0 * * * /usr/local/squid/bin/squid -k rotate
Click on Save to save your changes. Reboot the router or run squid -k reconfigure to make your changes immediate.
Notes and Comments
The following commands are very useful when troubleshooting:
squid -k reconfigure
squid -k shutdown
ps | grep -i squid
killall squid
The following are only useful if you have logging enabled:
tail -n 50 -f /opt/var/logs/access.log
tail -n 50 -f /opt/var/logs/cache.log
If your browser displays warnings about the certificate not being trusted, you need to install your Self-Signed Root Certificate into the browser.
Issue the following command to allow a device to bypass the proxy altogether (you must replace [IPADDRESS]):
iptables -t nat -I PREROUTING -i br0 -s [IPADDRESS] -j ACCEPT
Delete an iptables entry by first viewing the list:
iptables -t nat --list --line-numbers
Then issue the following (you must replace # with the number of the rule you want to delete):
iptables -t nat -D PREROUTING #
Some errors Squid spits out are a little vague. If you receive a segmentation fault of any kind, it is most likely due to missing directories or incorrect permissions. Here is a list of errors I have ran across while installing Squid and the solutions to each:
FATAL: Failed to verify one of the swap directories, Check cache.log for details. Run 'squid -z' to create swap directories if needed, or if running Squid for the first time.
Check that the /var/cache/squid/ directory exists and that the user nobody has read and write access to it. Run squid -z if the directory is empty.
FATAL: Ipc::Mem::Segment::create failed to shm_open(/squid-cf__metadata.shm): (2) No such file or directory
Check that the /dev/shm/ directory exists and that the user nobody has read and write access to it.
FATAL: Unable to open HTTPS Socket
For any errors similar to this one, check that Squid is not already running and that no other process is using any of Squid’s ports (3128, 3129, 3130).
pinger: Initialising ICMP pinger ... icmp_sock: (1) Operation not permitted pinger: Unable to start ICMP pinger. icmp_sock: (97) Address family not supported by protocol pinger: Unable to start ICMPv6 pinger. FATAL: pinger: Unable to open any ICMP sockets.
These error messages regard the ping utility. They can be safely ignored.
FATAL: Received Segment Violation...dying.
I’m not sure what this was about. It happened once when I issued the squid -k restart command. Regardless, the restart never works so, I just don’t use it. I use squid -k shutdown instead and bring Squid back up with squid after about 30 seconds. (Squid waits 30 seconds before shutting down during a clean shutdown.)
BUG: Unexpected state while connecting to a cache_peer or origin server
I’m not sure of the cause of this error either. I received it when posting to the DD-WRT forums along with messages about the queue being overloaded and to increase the number of ssl_crtd processes in the configuration file. I did so to no avail and the Squid process finally died one of the times I attempted to issue the squid -k reconfigure command. For now, I deleted and rebuilt the ssl_db directory, then rebooted. The error seems to be gone.
Thanks for reading!
Links in this Article
https://wiki.dd-wrt.com/wiki/index.php/Optware1
https://wiki.squid-cache.org/Features/DynamicSslCert2
https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit#Modern_DH.2FEDH_ciphers_usage3
https://curl.haxx.se/docs/caextract.html4
http://www.squid-cache.org/Doc/config/5
https://www.ssllabs.com/ssltest/viewMyClient.html6
https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit#Hardening7
Links of Interest
https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit#Hardening
https://wiki.dd-wrt.com/wiki/index.php/Squid_Transparent_Proxy
https://forum.dd-wrt.com/phpBB2/viewtopic.php?t=80678&postdays=0&postorder=asc&start=30&sid=f60feaf2c1f415edc4e5a1e9382e45a3
Comments are closed.