Skip to the content.

Privoxy Setup Guide

This guide walks through setting up Privoxy to provide network-wide ad and tracker filtering.

Architectural Strategy & Design Choices

1. Install and Configure Privoxy

Installation

Run the following commands on your Raspberry Pi:

sudo apt update
sudo apt install -y privoxy

Configure Network Bindings

Open Privoxy’s main configuration file:

sudo nano /etc/privoxy/config

Locate the listen-address directives (around line 780). By default, Privoxy binds to IPv4 127.0.0.1:8118 and IPv6 [::1]:8118.

Replace both entries with a single IPv4 wildcard binding:

listen-address  0.0.0.0:8118

Note: Binding to a single dual-stack IPv6 wildcard [::]:8118 binding should tell the Linux dual-stack networking engine to listen on all IPv6 interfaces as well as all IPv4 interfaces simultaneously, avoiding port conflicts while providing full dual-stack coverage. But this fails overnight due to a companion cleanup service restarting privoxy with IPv4 forced.

Restart Privoxy to apply the binding change:

sudo systemctl restart privoxy
sudo systemctl enable privoxy

2. Streamline & Configure Auto-Updating Blocklists

Use privoxy-blocklist.sh to download AdBlock Plus lists and convert them into native Privoxy action files.

Install Dependencies & Script

sudo apt install -y wget sed grep
sudo wget https://raw.githubusercontent.com/Andrwe/privoxy-blocklist/master/privoxy-blocklist.sh -O /usr/local/bin/privoxy-blocklist.sh
sudo chmod +x /usr/local/bin/privoxy-blocklist.sh

Configure Filter Lists

Generate the default configuration file:

sudo /usr/local/bin/privoxy-blocklist.sh -q

Open the configuration file to customize the downloaded lists:

sudo nano /etc/privoxy-blocklist.conf

Find the URLS= array. Remove EasyList Germany (included by default by the script author) to save memory and processing overhead. Add comprehensive AdBlock Plus lists:

URLS=(
  "https://easylist-downloads.adblockplus.org/easylist.txt"
  "https://easylist-downloads.adblockplus.org/easyprivacy.txt"
  "https://easylist-downloads.adblockplus.org/fanboy-annoyance.txt"
  "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/badware.txt"
)

Clean Up and Build Action Files

To remove old action files (such as easylistgermany.script.action) and generate the new rule set cleanly, reset the script database and execute a fresh run:

sudo /usr/local/bin/privoxy-blocklist.sh -r
sudo /usr/local/bin/privoxy-blocklist.sh

Restart Privoxy:

sudo systemctl restart privoxy

3. Automate Blocklist Updates with Cron

To keep filter rules current, schedule a weekly root cron job.

Why crontab -e?

Always use sudo crontab -e instead of directly editing /etc/crontab. Editing via crontab -e:

  1. Performs automatic syntax validation upon saving.
  2. Immediately signals the cron daemon to reload the schedule without restarting the service.
  3. Edits the root user’s individual cron spool file directly, avoiding syntax differences across system cron files.

Add Cron Entry

Open root’s crontab editor:

sudo crontab -e

Add a PATH definition at the top to ensure the script can be found, if it is not already present:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Add the following line at the bottom to schedule the script to run weekly at 3 AM on Sunday:

0 3 * * 0 /usr/local/bin/privoxy-blocklist.sh >/dev/null 2>&1

Output Redirection Syntax Explained

4. Verify Script Execution & Privoxy Operation

Verify Script Execution

Confirm the update script created and registered the action files properly:

  1. Check generated action files:
ls -la /etc/privoxy/*.script.action

  1. Check Privoxy configuration integration:
grep "script.action" /etc/privoxy/config

Test Privoxy in the Browser

Set your browser proxy manually to your Pi’s local IP on port 8118 and test the connection:

5. Client Auto-Failover via External .PAC File

To ensure seamless internet connectivity when the Raspberry Pi is offline, host the .PAC file on an always-on external host (such as a secret GitHub Gist or GitHub Pages).

PAC File Content (proxy.pac)

Create a file named proxy.pac containing the following logic:

function FindProxyForURL(url, host) {
    // 1. Direct connection for plain hostnames (e.g., http://router)
    if (isPlainHostName(host)) {
        return "DIRECT";
    }

    // 2. Direct connection for local IP subnets
    if (
        isInNet(host, "192.168.0.0", "255.255.0.0") ||
        isInNet(host, "10.0.0.0", "255.0.0.0") ||
        isInNet(host, "172.16.0.0", "255.240.0.0") ||
        isInNet(host, "127.0.0.1", "255.255.255.255")
    ) {
        return "DIRECT";
    }

    // 3. Send all traffic to Privoxy.
    // If Privoxy is unreachable, immediately fall back to DIRECT internet.
    return "PROXY 192.168.1.50:8118; DIRECT";
}

(Replace 192.168.1.50 with your Raspberry Pi’s actual static local IP).

Client Setup Instructions

Publish the file to your external host and copy the raw HTTPS URL (e.g., https://raw.githubusercontent.com/username/repository/main/proxy.pac).

If you don’t want to use a PAC file, you can manually set the proxy in these locations. This will affect all browsers, but provide no failover.

Browser Extensions

Although there is some overlap, the browser extension uBlock Origin complements the proxy well. However, it is limited on non-Firefox browsers (e.g. Chrome, Edge).