HOW TO - OpenVPN to a public VPN provider + transparent SQUID

  • Let's write a how-to with a complex configuration which works. Maybe a more simple configuration is possible, but for now, I didn't find any way to make it easier.

    I assume you already know how to install and configure pfsense, and you have an openvpn account with a provider.

    First, here is what I wanted to do:

    • OpenVPN connexion to a public VPN provider, so by default all my WAN traffic is sent to this VPN provider and not my ISP.
    • Transparent SQUID to manage HTTP traffic, so my children can't go to sites I don't want, and I don't have to configure proxy manually on each computer.
    • All other traffic filtered with firewall rules.
    • Availability to make some WAN traffic go to ISP directly, bypassing VPN. That's mainly for performances issues: I want to access some servers with a high speed connexion, and VPN slows down traffic.

    Now here are the main issues I encountered:

    • SQUID and pfsense firewall don't like to work together. I know a very good work has been made with floating rules and NAT options, but I'll explain later why in this case it's still a nightmare to make them working on the same pfsense box.
    • OpenVPN to an external provider only works correctly with "redirect-gateway def1", but this "magic" makes traffic outgoing from pfense itself hard to manage.
    • I read it's not a good idea to run SQUID on a firewall, and I agree with that for security reasons.

    So finally I decided to make working the following configuration:

    • 1 physical computer running Linux Ubuntu
    • 2 pfsense running in virtual machines on this computer, using VirtualBox

    The idea of the 2 pfsense boxes is the following:

    • First pfsense is the main firewall, managing all firewall-based rules and openvpn connexion
    • Second pfsense manages squid

    See ScreenShot001 for a diagram.

    So in that case, traffic from squid will be seen as an incoming traffic by the firewall, and will be easier to manage, as described later.

    So now let’s begin the how-to itself :)

    First, you need a computer with at least 2 physical networks interfaces (but if you’re already running pfsense, it should be the case).
    On this computer, install Ubuntu (desktop or server). Surely Ubuntu server would be the best idea, but I installed Ubuntu desktop because I like the graphical interface and it’s easier to configure VirtualBox with the gui rather with command line.
    Once Ubuntu is installed and running, you must configure your WAN and LAN interfaces, so Ubuntu can reach both WAN and LAN sides. Don’t enable routing on Ubuntu, the goal is to manage routing with pfsense, not with Ubuntu.
    The WAN IP must be on a LAN of the ISP modem. So you must enable routing mode on ISP modem, or have another router between modem and Ubuntu computer.
    In my case, my WAN network is and my LAN network is

    Once Ubuntu is correctly configured, install VirtualBox package.
    Then create 2 virtual machines (with FreeBSD settings).
    The 1st will be called “firewall” and the second “proxy”.
    Starting from now, I’ll write “firewall VM” and “proxy VM” (VM for virtual machine).

    Now go back to Linux, and open a command-line box. The goal here is to add 2 virtual network interfaces on this machine, they’ll be needed later to make 2 pfsense VMs talking together in a DMZ environment. For that create tap10 and tap11 virtual interfaces like this (with root access):

    /usr/sbin/tunctl -t tap10
    /sbin/ifconfig tap10 up
    /usr/sbin/tunctl -t tap11
    /sbin/ifconfig tap11 up

    That means tap10 is a virtual interface with IP address, and tap11 is a virtual interface with IP address.

    If you want to enable it automatically on reboot, just add an entry in /etc/init.d/ (refer to linux documentation).

    Now go back to VirtualBox settings.

    On “firewall VM”, let’s enable 4 virtual network interfaces.
    The 1st interface will be bridged to Ubuntu’s WAN interface (eth0 or eth1).
    The 2nd interface will be bridged to Ubuntu’s LAN interface (eth1 or eth0).
    The 3rd interface will be bridged to Ubuntu’s tap10 interface.
    The 4th interface will be bridged to Ubuntu’s tap11 interface.

    Be sure to enable bridge mode, not NAT !

    On “proxy VM”, let’s enable 2 virtual network interfaces.
    The 1st interface will be bridged to Ubuntu’s tap11 interface.
    The 2nd interface will be bridged to Ubuntu’s tap10 interface.

    Now install pfsense on both VMs.

    On “firewall VM”, I configured networking like this:
    WAN IP:
    LAN IP:
    OPT1 IP:
    OPT2 IP:

    On “proxy VM”, I configured networking like this:
    WAN IP:
    LAN IP:

    If all is configured correctly, “firewall VM” should now be able to communicate with both WAN and LAN sides of your Ubuntu computer. “firewall VM” and “proxy VM” will communicate through and networks (that’s why for bridging modes we had to enable to virtual interfaces on Ubuntu machine).

    Not go take a good cup of tea or coffee, because you you’re on about 50% of work :)

    We’ll forget “proxy VM” for a short time, and focus on “firewall VM”.

    You can already configure options like DHCP, and whatever you want to enable internet access on your LAN machines.

    Let’s configure OpenVPN connexion. I suggest you the excellent tutorial from MrHorizontal here:,24435.0.html

    If all is ok, all your internet traffic should now be redirected to the OpenVPN provider, and not directly to your main ISP.

    Now inside “firewall VM”, add an interface for ovpnc1 (which belongs to openvpn connexion). Make it static, and put what ever you want in IP address, because it’s overrided when connexion is established.
    In “System / routing”, add a gateway for this interface. In “gateway” field write “dynamic”, and in “alternative monitor ip” field write “” (opendns IP, which is always reachable).
    See ScreenShot002. Don’t enable “default gateway” !

    Why all this stuff if openvpn connexion is already working ? Because now you’ll be able to choose between VPN gateway and ISP gateway in firewall rule !

    Imagine you want to reach some websites directly from your ISP. Just create a firewall alias called “NoVPN” and add hosts you want to reach directly. Then, make a firewall rule with “NoVPN” as desination, and “ISP” as gateway.

    You can test on some websites which show your external IP. You sould be able to choose between your ISP IP, and your VPN provider IP.

    So at this point, all your traffic is managed by pfsense firewall, by default it’s sent to your OpenVPN provider, and you’re able to make some traffic going directly to your ISP for some destinations.

    Now let’s focus on the second main point: availability to filter HTTP traffic transparently with Squid (and SquidGuard).

    First of all, I already tried to install squid packages on the same machine, BUT that doesn’t work as expected.
    You can read some topics for more information:,32452.0.html,19525.0.html,28410.0.html

    So if routing on “firewall VM” is working sucessfully, you’d be able to reach “proxy VM” gui from your LAN (in my example on IP

    On this “proxy VM” I’ve installed Squid, SquidGuard, and LightSquid packages.
    On WAN interface of this machine, set your “firewall VM” IP as gateway. In my example, that’s See ScreenShot003.

    So now “proxy VM” should be able to reach internet through “firewall VM”. That way, it’ll follow the same rules for reaching websites through VPN or not.

    Now let’s configure Squid package. Keep all by default, enable transparent proxy. Transparent proxy works on (internal IP), and squid is listening or port 3128 for standard proxy connexions (in non-transparent mode).
    So let’s make it listening on another reachable port in transparent mode.
    In “Custom options” field at the bottom, add: “http_port transparent” (see ScreenShot004). That way, Squid will enable transparent proxying on port 3129, which will be reachable outside of the machine.

    Now let’s configure the firewall to make http traffic going to proxy. Go back to “firewall VM” and add a port forward NAT rule like that:
    Src address: LAN net
    Dest address: not LAN address
    Dest port: 80 (http)
    NAT IP:
    NAT port: 3129
    See ScreenShot005.

    That means all http traffic will be NATted to proxy transparently.

    Test your web access from LAN machines… If it works, then congratulations, you can now configure SquidGuard if you want to add http restrictions for some LAN machines.

    So I hope this how-to will help some users. For future versions of pfsense, I’d suggest a way to implement squid on the same machine with different virtual interfaces, so it could be possible to make this configuration working on a single pfsense installation.

    Good luck and thanks for the pfsense team :)