Splash Networks Blog

Web Filtering as a Service on pfSense

pfSense and Squid logos with a filter funnel

This post is about implementing web filtering as a service using a cloud hosted pfSense appliance. Using the setup documented below it is possible to offer web and URL filtering as a service for a safe web experience for schools, businesses and homes. It will also allow visibility into users’ traffic for compliance and logging purposes. This setup was tested on a pfSense appliance v2.4.5-RELEASE-p1 that was installed on an AWS EC2 instance (that setup is outside the scope of this post).

Users will use OpenVPN to connect to the pfSense appliance – which will be the OpenVPN server – where their traffic will be transparently intercepted, scanned, logged and forwarded or filtered based on our defined policies. Squid proxy will be deployed in transparent mode for web traffic interception and logging. SquidGuard will be used for web filtering.

OpenVPN Setup

To configure OpenVPN go to VPN => OpenVPN. The pfSense AWS appliance already has an OpenVPN server configured which is in disabled state. Select the edit icon at the right to set it up:

pfSense OpenVPN Servers list with the edit icon highlighted

This opens up OpenVPN server settings. Uncheck the Disabled option to enable OpenVPN server. Select Server Mode as Remote Access (User Auth). Protocol should be “UDP on IPv4 only”. The rest of the settings should be kept as per the defaults:

pfSense OpenVPN server general settings with server mode Remote Access (User Auth) and UDP on IPv4 only

Select these as the NCP algorithms:

pfSense OpenVPN NCP algorithms with AES-128-GCM and AES-128-CBC allowed

Update the default subnet if needed. Redirect IPv4 Gateway option should be checked:

pfSense OpenVPN tunnel settings with an IPv4 tunnel network and Redirect IPv4 Gateway checked

In DNS Server settings provide the IP of local Unbound DNS Resolver which we will setup later:

pfSense OpenVPN advanced client settings with a DNS server enabled and its address entered

In Gateway Creation select IPv4 only:

pfSense OpenVPN Gateway creation option set to IPv4 only

Go to System => Package Manager to install OpenVPN Client Export package. This package allows us to export .ovpn configuration files for OpenVPN clients.

To export .ovpn file go to VPN => OpenVPN => Client Export. In Host Name Resolution select Other, enter the WAN IP address of the AWS pfSense Instance and save these settings:

pfSense OpenVPN Client Export with Host Name Resolution set to Other and the server address entered

Download configurations for your required client type (for Windows select Most Clients):

pfSense OpenVPN Client Export download buttons with Most Clients highlighted

Create a local user in System => User Manager for authentication ( it is also possible to use RADIUS authentication instead of local).

Use the downloaded configuration file and the login credentials created in User Manager to connect using OpenVPN client:

Windows notification showing the pfSense OpenVPN connection is connected with an assigned IP address

To setup static IP for an OpenVPN client (so that IP based rules can be later setup for that client) go to VPN => OpenVPN => Client Specific Overrides and click Add.

In name field enter the username of the VPN user, and in Advanced enter the static IP address they should get in this format:

ifconfig-push 172.24.42.100 255.255.255.0;

pfSense OpenVPN client specific override with an ifconfig-push static IP address in the Advanced field

Press Save to save changes.

Interface & Firewall Setup

In pfSense go to Interface => Assignments and assign the OpenVPN ovpns1 interface to LAN (this assignment will come in handy when we have to setup Squid proxy later):

pfSense Interface Assignments with the OpenVPN ovpns1 interface assigned to LAN

Select LAN and enable this interface.

In Firewall rules make sure the rules allow OpenVPN access and other related services.

DNS Server Setup

It is vitally important that the clients and pfSense appliance both use the same caching DNS server in this setup, otherwise many popular websites like Google, YouTube, Reddit will not open (check this link for the technical explanation). Therefore we will setup Unbound DNS server on pfSense.

Go to Services => DNS Resolver. Enable it and make sure it is enabled on all interfaces.

pfSense DNS Resolver options with Enable DNS resolver checked and All network interfaces selected

Uncheck DNSSEC Support:

pfSense DNS Resolver with Enable DNSSEC Support unchecked

Click Save at the bottom of the page.

Squid & SquidGuard Setup

Go to System => Package Manager and download the packages named Squid and squidGuard. Squid is a widely used proxy server. SquidGuard is a URL filtering package that works with Squid.

After installation go to Services => Squid Proxy Server. First, we need to setup Local Cache. Go to Local Cache, set Hard Disk Cache Size as 500 MB and Clear Disk Cache once.

Squid hard disk cache settings with the cache size set to 500 MB and the Clear Disk Cache NOW button highlighted

Click Save and go back to the General tab. Under Squid General Settings check Enable Squid Proxy option and select all interfaces in Proxy Interface(s).

Squid general settings with Enable Squid Proxy checked and the proxy interfaces list

Under Transparent Proxy Settings enable Transparent HTTP Proxy and select all interfaces.

Squid transparent proxy settings with Transparent HTTP Proxy enabled and interfaces selected

Similarly, under SSL Man in the Middle Filtering enable HTTPS/SSL Interception, SSL/MITM Mode should be “Splice All” and select all interfaces:

Squid SSL Man in the Middle filtering with HTTPS/SSL Interception enabled and Splice All mode

Enable Access Logging and click Save at the bottom of the page:

Squid logging settings with Enable Access Logging checked

Squid Proxy has been set up.

To send Squid logs to syslog click on the “Show Advanced Options” button at the end of the page (in General tab). In Advanced Features add the following directive in Custom Options (Before Auth) – it will send all Squid logs to syslog with the given facility and severity level:

access_log syslog:local4.info

Squid custom options box containing the access_log syslog directive

Now we will configure SquidGuard Proxy Filter. Go to Services => SquidGuard Proxy Filter. Go to Target Categories and create a rule for URL filtering. In Domain List enter the domains you want to blacklist or whitelist:

SquidGuard Target categories tab with a custom_test rule and a domain list

Under General Options check Enable and click Apply. Under Logging options check Enable log and Enable log rotation.

SquidGuard logging options with Enable log and Enable log rotation checked

Click Save and Apply.

To apply common rules that apply to all users go to Common ACL and setup access rules like this:

SquidGuard Common ACL tab with the default access rule and Do not allow IP-Addresses in URL checked

The “Default access [all]” rule applies to all traffic. If we set it to “allow” it will allow all websites by default and any domains that need to be filtered will have to be blacklisted manually. If we set it to “deny” all domains will be blocked by default and any domain that needs to be allowed will have to be whitelisted manually.

It’s a good practice to check “Do not allow IP-Addresses in URL” so that users don’t use IP addresses to access websites in order to bypass URL filtering policies.

After any configuration change in SquidGuard, click on the Apply button in General Settings for the changes to take effect:

SquidGuard general settings with Enable checked and the Apply button highlighted

Per User URL Filtering

To apply different URL filtering rules for different users, go to Groups ACL and create a new rule:

In Client (source) enter the static IP address of the user:

SquidGuard Groups ACL rule with a client IP address as source and the custom_test category set to deny

In Target Rules enter the URL filtering policies for the user. In this case the domains mentioned in the “custom_test” ruleset will be blocked while all other websites will be allowed for this user.

Logging

The websites being visited by users are shown in the Squid access logs:

pfSense Squid access log table listing requests from a client IP address

Another tool for Squid reporting is LightSquid. To use it install the Lightsquid package. Then set it up by going to Status => Squid Proxy Reports. Configure its settings and click on the Refresh Full button. Then click on the Open Lightsquid button to access Lightsquid reports. It can give per-user (per-IP) reports of domains visited by the user as well as the data transferred:

LightSquid user access report listing the sites a client visited

The total upload/download of a user can be seen in Status => OpenVPN:

pfSense Status OpenVPN page showing a connected client with bytes sent and received

To enable remote logging to a syslog server, go to Status => System Logs => Settings and click on Enable Remote Logging. Enter the IP address(es) of remote syslog servers and select the log categories:

pfSense system log settings with remote logging enabled and Everything selected for remote syslog contents

By selecting Everything all syslogs from the pfSense appliance including Squid logs would then be available on the Syslog server.

SquidGuard logs of blocked sites are available in /var/squidGuard/log/block.log and by default cannot be sent to syslog. To send them to syslog we can use another technique. Access pfSense via SSH and enter the following command:

tail -f /var/squidGuard/log/block.log | logger -p local4.info &

It will start sending all new entries in /var/squidGuard/log/block.log to syslog. It should also be possible to create a cron job or script for starting this function automatically after reboot. It is left as an exercise for the reader.

References

https://openschoolsolutions.org/pfsense-web-filter-filter-https-squidguard/