Building an Open Source Secure Web Gateway

Updated: Mar 29

What is a secure web gateway?

A secure web gateway in it's purest sense allows for the enforcement of policies and provides real-time threat protection for clients browsing the web.

Why should you the reader consider a secure web gateway?

There are a number of benefits a secure web gateway can provide, some of my favourites are the following:

  • Real-time anti-virus scanning

  • Corporate policy enforcement (Prevent users from viewing adult content, watching netflix, etc.)

  • Logging of web activity

This tutorial will walk you through the creation of an open source secure web gateway using e2guardian, clamav, and debian 9 stretch. If any part of this tutorial is unclear or you are unable to follow the instructions please let me know in the comments and I will do my best to help. This tutorial is for someone with Linux experience, and a high level understanding of how the TCP, SSL, HTTP, and DNS protocols work.

Start by installing debian 9 to your preferences and configuring a static IP address. Our lab network already has a gateway so I used an IPv4 address of on my debian host and left the gateway at

Download the e2guardian deb package with the command below:


Before we install the deb package we need to install some dependencies. Run the commands below to install them:

sudo apt update

sudo apt install -y libevent-core-2.0-5 libevent-pthreads-2.0-5 libtommath1

Once the above commands are finished we can run the command below to install e2guardian:

sudo dpkg -i e2debian_V5.3.2_20190315.deb

Now to inspect HTTPS traffic there is some additional work we need to do. Start by running the commands below to create some additional directories we need:

sudo mkdir /etc/e2guardian/generatedcerts

sudo mkdir /etc/e2guardian/ssl

Change you working directory with the command below:

sudo cd /etc/e2guardian/ssl

Run the command below to create a private key for use with the CA certificate we are going to create:

sudo openssl genrsa 4096 > private_e2cakey.pem

Use the command below to generate the CA certificate:

sudo openssl req -new -x509 -days 3650 -key private_e2cakey.pem -out e2_rootCA.pem

Use the command below if you would like to be able to import the CA into web browsers:

sudo openssl x509 -in e2_rootCA.pem -outform DER -out e2_rootCA.der

Lastly we need to generate one more private key to use for auto generated certificates:

sudo openssl genrsa 4096 > e2_cert_key.pem

Tighten up the permissions on the certificates we just created with the commands below:

sudo chown -R e2guardian:e2guardian /etc/e2guardian/generatedcerts

sudo chown -R e2guardian:e2guardian /etc/e2guardian/ssl

sudo chmod 600 /etc/e2guardian/ssl/*

Open e2guardian's primary configuration file (/etc/e2guardian/e2guardian.conf) with your favourite text editor or use the following sed commands (Much faster and easier) to make the edits for you. Enable SSL support with the command below:

sudo sed -i "/enablessl =*/c\enablessl = on" /etc/e2guardian/e2guardian.conf

Run the commands below to tell e2guardian where its certificates and privates keys are located:

sudo sed -i "/cacertificatepath =/c\cacertificatepath = \'/etc/e2guardian/ssl/e2_rootCA.pem\'" /etc/e2guardian/e2guardian.conf

sudo sed -i "/caprivatekeypath =/c\caprivatekeypath = \'/etc/e2guardian/ssl/private_e2cakey.pem\'" /etc/e2guardian/e2guardian.conf

sudo sed -i "/certprivatekeypath =/c\certprivatekeypath = \'/etc/e2guardian/ssl/e2_cert_key.pem\'" /etc/e2guardian/e2guardian.conf

Tell e2guardian where to store auto generated certificates with the command below:

sudo sed -i "/generatedcertpath =/c\generatedcertpath = \'/etc/e2guardian/generatedcerts\'" /etc/e2guardian/e2guardian.conf

Now we haven't installed it yet, but we will be using clamav for content scanning. Run the command below to configure the content scanner setting:

sudo sed -i "/clamdscan.conf/c\contentscanner = \'\/etc\/e2guardian\/contentscanners\/clamdscan.conf\'" /etc/e2guardian/e2guardian.conf

Now we need to modify the default group configuration file (/etc/e2guardian/e2guardianf1.conf ). Run the command below to instruct e2guardian to MITM (Man in the middle) SSL connections:

sudo sed -i "/sslmitm = off/c\sslmitm = on" /etc/e2guardian/e2guardianf1.conf

Modify the clamav content scanner configuration file (/etc/e2guardian/contentscanners/clamdscan.conf) and tell e2guardian where to find the clamav unix socket. Run the command below to accomplish this:

sudo sed -i "/clamdudsfile =/c\clamdudsfile = \'/var/run/clamav/clamd.ctl\'" /etc/e2guardian/contentscanners/clamdscan.conf

To make distributing our CA certificate less of a pain we will stand up a quick nginx server to help us out. Run the commands below to accomplish this:

sudo apt-get install -y nginx

sudo rm /var/www/html/index.nginx-debian.html

sudo sed -i '/listen 80 default_server;/c\\tlisten 8081 default_server;' /etc/nginx/sites-enabled/default

sudo sed -i '/listen [::]:80 default_server;/c\\t# IPv6 config removed' /etc/nginx/sites-enabled/default

sudo cp /etc/e2guardian/ssl/e2_rootCA.pem /var/www/html/e2_rootCA.pem

sudo chmod +r /var/www/html/e2_rootCA.pem

sudo service nginx start

sudo systemctl enable nginx

If you have run the above commands your CA certificate will now be available to clients to download via <your_server_ip>:8081/e2_rootCA.pem. If you would like the der format or a pfx format to shared easily you can drop them in the /var/www/html directory. Just make sure you remember to set permissions so nginx can serve them to clients.

Run the command below to install the clamav and freshclam (keeps clamav signatures up to date):

sudo apt-get install -y clamav clamav-base clamav-daemon clamav-docs clamav-freshclam clamdscan

Use the command below to give clamav the ability to scan files created by e2guardian:

sudo usermod clamav -G e2guardian

Run the commands below to start the clamav and freshclam services and ensure they start at boot:

sudo service clamav-daemon start

sudo service clamav-freshclam start

sudo systemctl enable clamav-daemon

sudo systemctl enable clamav-freshclam

Enable routing in the linux kernel with the command below:

sudo sysctl -w net.ipv4.ip_forward=1

sudo echo 1 > /proc/sys/net/ipv4/ip_forward

Now we need to use iptables to get everything working properly. Start by installing the iptables-persistent package with the command below:

sudo apt install -y iptables-persistent

Add the required iptables rules with the commands below:

sudo iptables -t nat -A PREROUTING -i ens18 -p tcp --dport 443 -j REDIRECT --to-port 8443

sudo iptables -t nat -A PREROUTING -i ens18 -p tcp --dport 80 -j REDIRECT --to-port 8080

Finally start the e2guardian service and configure it start on boot with the commands below:

sudo service e2guardian start

sudo systemctl enable e2guardian

Once those services are started you should have a fully functional secure web gateway. Clients must either be configured to use this server as their gateway or in some cases you can selectively route HTTP and HTTPS traffic to this gateway. The commands below are an example of how to configure a debian 9 client to selectively route HTTP and HTTPS traffic to the e2guardian server.

sudo echo 200 proxy-route >> /etc/iproute2/rt_tables

sudo ip route add default via dev ens18 table proxy-route

sudo ip rule add fwmark 0x1 table proxy-route

sudo iptables -A OUTPUT -t mangle -o ens18 -p tcp --dport 443 -j MARK --set-mark 1

sudo iptables -A OUTPUT -t mangle -o ens18 -p tcp --dport 80 -j MARK --set-mark 1

Now some traffic we are not going to want to touch. This may be users browsing to their banking web site, video streaming like Netflix, and so on. To get around this we can use iptables, ipset, and a little bit of python (or any other scripting language you like). Start by running the command below to install ipset:

sudo apt install ipset -y

Create an ipset to use in a future iptables rule by running a command similar to the one below:

sudo ipset create test hash:ip

Use an iptables rule similar to the command below:

iptables -t nat -I PREROUTING -i ens18 -p tcp -m set --match-set test dst -j ACCEPT

Finally, here is some example code that will read a list of domains and add them to the ipset.