Privoxy 4.2.0 on AWS User Guide
Overview
This guide covers launching and verifying Privoxy 4.2.0 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other VPN, proxy and remote access servers in the listing are described on the listing's guide hub.
Privoxy is a non-caching web proxy with advanced filtering: it removes ads, banners and web bugs, rewrites or strips headers that leak information about you, and blocks unwanted hosts and paths using its actions and filter files. It is a headless network service with no web console to log in to; its built-in status pages at http://config.privoxy.org/ are served by the proxy itself.
What cloudimg adds
- The current upstream release, verified. Ubuntu 24.04 only carries Privoxy 3.0.34 in its community-maintained universe component. This image ships Privoxy 4.2.0, built from the unmodified upstream source tarball after its SHA-256 checksum and its OpenPGP signature (Privoxy release key
4F36 C17F 3816 9136 54A1 E850 6918 2291 8BA2 371C) were verified. 4.2.0 includes the two security fixes announced with it. The compiler and build tools are removed again before the image is captured. - No HTTPS inspection code. The binary is built without any TLS library, so Privoxy cannot intercept or decrypt HTTPS. HTTPS sites pass through it as normal encrypted
CONNECTtunnels. - An authenticating front end. Privoxy itself has no client passwords. In this image Privoxy listens on
127.0.0.1:8118only, and clients in your VPC reach it through HAProxy (from Ubuntu's main archive) on port 8119, which requires the proxy usercloudimgand a password generated on each instance's first boot. - Not an open proxy. HAProxy drops connections from any source outside loopback and the private ranges 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 before reading the request, and the security group opens SSH only.
- No route to the instance's own services or metadata. Privoxy refuses destinations in 127.0.0.0/8, 0.0.0.0/8 and 169.254.0.0/16 for every address a name resolves to, both services are blocked from the EC2 instance metadata service at the system level, and
CONNECTtunnels are allowed to port 443 only. - Hardened services. Privoxy runs as an unprivileged
privoxyuser that owns and can write no file, with no capabilities, a read-only system and a restricted set of system calls. The web actions editor is not compiled in and remote toggling is off. - No request log. Privoxy logs only start-up messages, warnings and errors, never the requests it serves, and HAProxy logs the client address, status and byte count without the request line.
Prerequisites
- An AWS account and permission to launch EC2 instances
- An EC2 key pair in the Region you launch in
- A VPC subnet for the proxy, and the CIDR ranges of the clients that will use it
Recommended instance type: m5.large. A proxy for a handful of clients runs comfortably on t3.small or larger.
Connecting to your instance
| Version | Operating system | SSH user |
|---|---|---|
| Privoxy 4.2.0 on Ubuntu 24.04 | Ubuntu 24.04 LTS | ubuntu |
| Port | Protocol | Purpose | Who should reach it |
|---|---|---|---|
| 22 | TCP | SSH administration, and SSH tunnels to the proxy | Your administrators |
| 8119 | TCP | The authenticated proxy (HAProxy in front of Privoxy). Closed by default. | Clients in your VPC only, never 0.0.0.0/0 |
| 8118 | TCP | Privoxy itself, on 127.0.0.1 only (not reachable from the network) | SSH tunnel users |
Step 1: Launch the instance
Option A: AWS Marketplace console
- Open the cloudimg Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- Once the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose Privoxy 4.2.0 on Ubuntu 24.04, then choose your Region.
- Pick an instance type (
m5.largerecommended; the software charge is $0.04 per vCPU per hour) and your key pair. - Security group: the listing's default group allows SSH (22) only. Restrict it to your own IP address. You will open the proxy port to your clients in Step 5.
- Choose your VPC and subnet, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.
Option B: AWS CLI
Run this on your own workstation. It creates a security group that allows SSH from your management address and the proxy port from your VPC only, then launches the instance. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and CIDR ranges with your own:
SG=$(aws ec2 create-security-group --group-name privoxy \
--description "Privoxy filtering proxy" --vpc-id vpc-0123456789abcdef0 \
--query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 8119 --cidr <vpc-cidr>
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids "$SG" \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=privoxy}]'
You do not need --metadata-options: the AMI already makes IMDSv2 required.
Step 2: Connect and read the credentials
Connect as ubuntu with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>
First boot finishes within a minute of launch. It generates this instance's proxy password, stores only a SHA-512 hash of it in the HAProxy configuration, starts Privoxy and HAProxy and checks that the front end refuses requests without the password and accepts them with it. The details are in /root/privoxy-credentials.txt, readable only by root. This command prints everything except the password line:
sudo grep -v '^PROXY_PASSWORD=' /root/privoxy-credentials.txt
# Privoxy 4.2.0 - generated on first boot by privoxy-firstboot.service.
# The password below is unique to this instance; nothing was baked into the image. Keep this file private.
#
# VPC clients: HTTP proxy 172.31.91.209:8119 with the user and password below (open TCP 8119 in the security group to
# your VPC or client security group only - never 0.0.0.0/0). SSH tunnel: ssh -L 8118:127.0.0.1:8118 ... then use
# 127.0.0.1:8118 as the proxy (no password; SSH is the authentication).
PROXY_HOST=172.31.91.209
PROXY_PORT=8119
PROXY_USER=cloudimg
PRIVOXY_LOOPBACK=127.0.0.1:8118
# Self-test: sudo privoxy-selftest New password: sudo privoxy-access rotate-password Clients: sudo privoxy-access list
# Guide: https://www.cloudimg.co.uk/guides/privoxy-4-2-0-on-ubuntu-24-04-aws/
PROXY_HOST is your instance's private IP address. To see the password when you need it, run sudo cat /root/privoxy-credentials.txt.
Step 3: Confirm the proxy is running
systemctl is-active privoxy haproxy privoxy-firstboot
sudo ss -Hltn | awk '{print $4}' | sort
active
active
active
0.0.0.0:22
0.0.0.0:8119
127.0.0.1:8118
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
Privoxy is on 127.0.0.1:8118 only. HAProxy, the authenticated front end, is on port 8119. The two :53 sockets are Ubuntu's local DNS resolver, which listens on loopback only.
Step 4: Run the self-test
The image includes a self-test that exercises the whole path without printing the password:
sudo privoxy-selftest
SELFTEST_OK privoxy+haproxy active; Privoxy 4.2.0 127.0.0.1:8118 only; 8119 407 without/with a wrong password, 200 with the instance password, 400 origin-form; ad host blocked; toggle 403, editor 404; metadata (503) and loopback (503) unreachable; guards OK
Step 5: Open the proxy to your clients
Clients in your VPC connect to the instance's private IP address on port 8119. In the EC2 console, edit the instance's security group and add an inbound rule:
- Type: Custom TCP, Port range: 8119
- Source: your VPC CIDR (for example
10.0.0.0/16) or the security group your client instances use
Never use 0.0.0.0/0. Even then the proxy only admits private source addresses and still needs the password, but the port should not be exposed to the internet at all.
Using the proxy from your workstation through SSH
You do not need to open any port to use Privoxy from your own machine. Forward a local port to Privoxy's loopback address over SSH; SSH is the authentication, so no proxy password is needed on this path:
ssh -i ~/.ssh/my-key-pair.pem -N -L 8118:127.0.0.1:8118 ubuntu@<public-ip>
Then set your browser or system HTTP and HTTPS proxy to 127.0.0.1 port 8118.
Step 6: Make requests through the proxy
From a client instance in your VPC, pass the user and password from Step 2. With curl:
curl -sS -o /dev/null -w '%{http_code}\n' --proxy http://<PROXY_HOST>:8119 --proxy-user '<PROXY_USER>:<PROXY_PASSWORD>' https://example.com/
200
Browsers and most command-line tools ask for the proxy user name and password when the proxy answers 407 Proxy Authentication Required, or accept them in the http_proxy and https_proxy environment variables. Note that this front end uses HTTP Basic authentication on the proxy connection itself, which is not encrypted: keep the proxy port inside your VPC, and use the SSH tunnel above when you connect across the internet.
Step 7: Confirm it is not an open proxy
Without credentials, the front end answers 407 and offers the Basic challenge:
curl -s -D - -o /dev/null -x http://127.0.0.1:8119 http://example.com/ | head -3
HTTP/1.1 407 Unauthorized
content-length: 112
cache-control: no-cache
Privoxy's own status page is served through the proxy. On the instance, the loopback port answers without a password:
curl -s -x http://127.0.0.1:8118 http://config.privoxy.org/ | sed -e 's/<[^>]*>//g' | grep -A1 'This is Privoxy'
This is Privoxy 4.2.0 on localhost (127.0.0.1), port 8118,
enabled
Remote toggling and the web actions editor are refused, so nobody using the proxy can switch filtering off or change its rules:
curl -s -o /dev/null -w 'toggle %{http_code}\n' -x http://127.0.0.1:8118 'http://config.privoxy.org/toggle?set=disable'
curl -s -o /dev/null -w 'editor %{http_code}\n' -x http://127.0.0.1:8118 'http://config.privoxy.org/edit-actions-list?f=user'
toggle 403
editor 404
Step 8: Metadata and local services are unreachable through the proxy
A proxy that will fetch any URL could be used to read the instance metadata service or to reach services that listen only on the instance itself. Privoxy refuses both:
curl -s -o /dev/null -w 'metadata %{http_code}\n' -x http://127.0.0.1:8118 http://169.254.169.254/latest/meta-data/
curl -s -o /dev/null -w 'loopback ssh %{http_code}\n' -x http://127.0.0.1:8118 http://127.0.0.1:22/
metadata 503
loopback ssh 503
503 is Privoxy's "connection failed" page: its destination rules refused the address before any connection was made. Independently of those rules, both services are blocked from 169.254.169.254 at the system level (systemctl show -p IPAddressDeny privoxy haproxy).
Step 9: See the filtering work
Privoxy's default actions block common ad and tracking hosts. A request to a host whose name matches an ad pattern is answered by Privoxy itself:
curl -s -o /dev/null -w '%{http_code}\n' -x http://127.0.0.1:8118 http://ads.example.com/
403
The rule sets are in /etc/privoxy: match-all.action, default.action and default.filter are upstream's, user.action and user.filter are yours to edit, and cloudimg.action holds the cloudimg defaults. Privoxy re-reads changed files automatically. To check which actions apply to a URL, open http://config.privoxy.org/show-url-info through the proxy.
Step 10: Allow another of your own networks (optional)
If your clients use addresses outside the private ranges (for example a 100.64.0.0/10 secondary VPC range), add them to the front end's source list:
sudo privoxy-access list
sudo privoxy-access allow <vpc-cidr>
privoxy-access refuses 0.0.0.0/0 and any network wider than /8, checks the configuration and reloads HAProxy. sudo privoxy-access remove <CIDR> takes a network out again. The security group still decides who can reach port 8119 at all.
Step 11: Rotate the password (optional)
sudo privoxy-access rotate-password
This generates a new password, replaces the hash in /etc/haproxy/haproxy.cfg, reloads HAProxy and writes the new password to /root/privoxy-credentials.txt. The old password stops working immediately.
Step 12: Allow more HTTPS ports (optional)
CONNECT tunnels are allowed to port 443 only. To allow another port, edit the {+limit-connect{443}} line in /etc/privoxy/cloudimg.action, for example to {+limit-connect{443,8443}}. Privoxy picks up the change on the next request.
Step 13: Logs
sudo journalctl -u privoxy -u haproxy -n 20 --no-pager
Privoxy runs in the foreground under systemd, so its messages go to the journal. The shipped configuration enables debug 4096 (start-up messages and warnings) and debug 8192 (errors) only, so the requests Privoxy serves are not logged; an error message can quote the address it refused, for example a denied attempt to use the remote toggle page. debug 1, which logs every request URL, is refused by the start guard unless you create /etc/privoxy/ALLOW-REQUEST-LOGGING first, because URLs can carry personal data and tokens. HAProxy logs each connection's client address, status and size without the request line.
How the secure start works
privoxy.service and haproxy.service only start once first boot has written /var/lib/cloudimg/privoxy-ready. Before each start, a guard checks the configuration: Privoxy must listen on 127.0.0.1:8118 only, admit only 127.0.0.1 and keep its destination rules; HAProxy must have exactly one user with a SHA-512 password hash, its source list and port 8119. If a check fails, the service does not start. Confirm the guards against the current configuration with:
sudo /usr/local/sbin/privoxy-guard && sudo /usr/local/sbin/privoxy-haproxy-guard && echo guards OK
guards OK
Security recommendations
- Keep port 8119 open only to the networks that need the proxy, and prefer the SSH tunnel across the internet.
- Rotate the proxy password when someone who knew it no longer needs it.
- Keep the instance patched. Ubuntu security updates, including HAProxy's, install automatically every day; Privoxy itself is updated by launching a newer version from the listing.
- Leave request logging off unless you need it for troubleshooting, and turn it off again afterwards.
Support and licensing
Privoxy is free software under the GNU General Public License, version 2 or (at your option) any later version. The unmodified source tarball this binary was built from, its OpenPGP signature, the licence texts and the build record are in /usr/local/share/doc/privoxy/. HAProxy is from Ubuntu's main archive under the GNU GPL.
Privoxy is developed by the Privoxy team (https://www.privoxy.org/). cloudimg is not affiliated with or endorsed by the Privoxy project. For help with this image, contact cloudimg support through the AWS Marketplace listing.