E2guardian Web Content Filtering Proxy on AWS User Guide
Overview
This guide covers deploying and operating E2guardian on AWS using the cloudimg AWS Marketplace image. E2guardian is a mature open source web content filtering proxy: it sits between your users and the internet and applies URL, domain, phrase and content policy to every request, returning a clear block page when a request is refused. It runs as a headless daemon configured through /etc/e2guardian/, with no web console.
The image builds E2guardian 5.5.9r from a sha256-pinned upstream source tarball (GPL 2.0) rather than the distribution archive package, which is two minor series behind. It runs standalone: E2guardian connects directly to origin sites, so there is no second proxy to deploy, and it can be chained to an existing Squid caching proxy with two configuration lines if you already run one.
Never an open relay. An exposed proxy is one of the most abused assets on the internet. E2guardian itself has no source-address allowlist, so this image ships one: e2guardian-firewall.service installs an nftables table that accepts the proxy port on 8080 only from loopback and RFC1918 client networks and drops every other source. e2guardian.service declares Requires=e2guardian-firewall.service, so if that allowlist cannot be applied the proxy does not start at all - the appliance fails closed rather than opening a relay. Scope your AWS security group to your own client subnet as the mandatory second layer.

No TLS interception, no CA key. E2guardian can perform SSL interception, which would require a certificate authority key. This image deliberately does not: enablessl is off, /etc/e2guardian/private is empty, and no CA certificate or private key exists anywhere in the image or on your instance, so there is no shared interception authority to leak. HTTPS is still filtered by CONNECT hostname against the site lists.
What is included:
- E2guardian 5.5.9r built from pinned upstream source, run under systemd (
e2guardian.service) as the unprivilegede2guardianuser, listening on port 8080 e2guardian-firewall.service- a fail-closed nftables source allowlist (loopback + RFC1918 only); the proxyRequires=it, so it never starts without access control- A documented, self demonstrating local block list seeded with one IANA reserved documentation domain (
example.org) so you can prove filtering works in one command, then add your own policy - The GPL 2.0 corresponding source and a written offer shipped on the image at
/usr/share/doc/cloudimg/ - A structured access log at
/var/log/e2guardian/access.log, ready to forward to your SIEM - No product login and no bootstrap password: administration is over your own key based SSH
Connecting to your instance
This is a headless network service - there is no web console. You administer it over SSH as the default login user for your operating system variant.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
Connect with your EC2 key pair (replace the key file and address with your own):
ssh -i <your-key>.pem ubuntu@<public-ip>
On login the message of the day summarises the proxy endpoint, the access-control posture and the commands below.
Security group
E2guardian listens on TCP 8080. In the instance's security group:
- Allow TCP 22 inbound from your administration network only, for SSH.
- Allow TCP 8080 inbound only from your trusted client subnets - the networks whose users you want to filter.
Never open port 8080 to 0.0.0.0/0. An internet-reachable proxy is abused within hours. The nftables allowlist on the instance already drops any source outside loopback and RFC1918, but the security group is your first and most important layer - keep it scoped to your own clients:
aws ec2 authorize-security-group-ingress \
--group-id <your-security-group-id> \
--protocol tcp --port 8080 \
--cidr <your-client-subnet-cidr>
Prove filtering works
The image ships a self demonstrating policy: example.org (IANA's reserved documentation domain) is blocked, everything else is allowed. SSH in and run the two commands below. A permitted site is fetched through the proxy and returns the real page:
curl -fsS -m 20 --retry 3 --retry-connrefused -x http://127.0.0.1:8080 http://example.com/ \
| grep -qi "Example Domain" \
&& echo "ALLOWED-OK: permitted URL served through the proxy"

A banned site is refused with E2guardian's own Access Denied block page, with the real content withheld:
curl -s -m 20 --retry 3 --retry-connrefused -x http://127.0.0.1:8080 http://example.org/ \
| grep -qi "Access Denied" \
&& echo "BLOCKED-OK: banned URL refused with the E2guardian block page"

Every request is written to the access log, so the block is auditable:
tail -n 5 /var/log/e2guardian/access.log
Confirm it is not an open relay
The proxy is bound to all interfaces but the fail-closed nftables allowlist accepts it only from loopback and RFC1918 sources. Confirm the service is up and coupled to its access-control unit:
systemctl is-active e2guardian e2guardian-firewall \
&& systemctl show -p Requires --value e2guardian | grep -q e2guardian-firewall.service \
&& echo "OK: proxy active and Requires the source allowlist (fails closed without it)"
Because e2guardian.service requires e2guardian-firewall.service, if the allowlist ever fails to apply the proxy will not start - it can never come up as an open relay.

Add your own filtering policy
Your block list lives in the filter group's list directory. The per-instance info file records the exact path:
cat /root/e2guardian-info.txt
To block your own domains, add one per line to localbannedsitelist (a bare domain also blocks its subdomains) and reload. This example uses a placeholder - substitute your real domains and remove the demo example.org entry when you are ready:
echo '<your-domain>' | sudo tee -a /etc/e2guardian/lists/example.group/localbannedsitelist
sudo systemctl reload e2guardian
E2guardian also ships upstream category, URL and phrase lists under /etc/e2guardian/lists/ and filter-group configuration under /etc/e2guardian/e2guardianf1.conf. See the E2guardian documentation for the full policy language.
Point clients at the proxy
Configure the HTTP and HTTPS proxy on your client machines (or your DHCP / group policy / PAC file) to the instance's private address on port 8080. For a quick test from a permitted client:
export http_proxy=http://<instance-private-ip>:8080
export https_proxy=http://<instance-private-ip>:8080
curl -I https://example.net/
Chain to an existing Squid (optional)
This image runs standalone by default. If you already operate a Squid caching proxy and want E2guardian to filter in front of it, set proxyip and proxyport in /etc/e2guardian/e2guardian.conf to your Squid, then sudo systemctl restart e2guardian.
Licensing
E2guardian is distributed under the GNU General Public License version 2. The complete corresponding source for the binaries in this image and a written offer are shipped on the instance at /usr/share/doc/cloudimg/. cloudimg is not affiliated with or endorsed by the E2guardian project; "E2guardian" is used nominatively to identify the software.
Support
cloudimg provides 24/7 technical support for this image via email (support@cloudimg.co.uk) and live chat. Our engineers help with scoping client access, restricting the proxy port to trusted subnets, building filtering policy, chaining to an upstream Squid, forwarding the access log to your SIEM, and version upgrades.