Network Wide Transparent Proxying

By: Wylie Bayes & Brandon Folchi

The purpose of this article is to guide anyone who is interested in setting up their own transparent proxy capable of filtering outbound web-browsing of all devices on a network. While researching options to accomplish this we came across a program called DansGuardian. DansGuardian is an open source web content filter that runs on multiple ‘Unix like’ platforms. The concept behind this application is to truly filter the content the user is browsing instead of simply having a blacklist of websites you want to avoid. It is impossible to keep up with all of the new websites that are created each day plus we are probably going to be more strict on the content that we want available than most people.

We have never accomplished any kind of network wide transparent filtering before. When we brought this topic up in a discussion a friend brought to our attention the use of OpenDNS as a simple quick and dirty “catch-all” filtering method. We decided that a Squid/Dansguardian proxy was the best option for filtering, in conjunction with the OpenDNS “catch-all” in place as a backup.

Hardware
Necessary hardware:
1. One 32 or 64bit system.
2. Two supported NICs.
3. At least one Internet connection.
4. A switch or hub, preferably 100mbit or higher.
5. See http://www.openbsd.org/plat.html to ensure your hardware is supported.

The Setup
Installing OpenBSD
Boot off your required type of OpenBSD installation media (IE: cd, usb, etc.) It is suggested to manually partitioning your disk with simply everything allocated on /. Or separate /, /home, and /var. Both /, and /var need ample space.

Configuring DHCP
Modify your /etc/dhcpd.conf to something similar. (These DNS options should work for everyone in US.) This issues IP’s between .160 – and .250.

 option domain-name “example.com”;
 option  domain-name-servers 8.8.8.8, 8.8.4.4, 208.67.222.222, 208.67.220.220;

 subnet 172.16.10.0 netmask 255.255.255.0 {
         option routers 172.16.10.1;
         range 172.16.10.160 172.16.10.250;
 }

Configuring pf.conf
The following example shows the pf.conf options necessary to accommodate this setup. All options are commented to facilitate their purpose:

 ########### Macros ######################
 extnet="dc0"
 intnet="rl0"
 #Backup wifi router
 rum0="rum0"
 ########## Options #######################
 set block-policy return
 set loginterface $extnet
 set skip on lo
 set skip on {pfsync}
 set ruleset-optimization basic
 set optimization aggressive
 set limit {states 100000 table-entries 8000000}
 set reassemble yes no-df                        # NEW

 ### Divert rules!!! ####
 #FTP
 pass in quick on $extnet inet proto tcp to any port ftp divert-to 127.0.0.1 port 8021
 #Dansguardian, the following divert-to rule accomplishes the “transparent” proxy.
 pass in quick on $intnet inet proto tcp to port 80 divert-to 172.16.10.1 port 8081
 #Squid (bypasses dansguardian filtering, special purpose use)
 #pass in quick on $intnet inet proto tcp to port 80 divert-to 172.16.10.1 port 8080

 ############ NAT RULES ##############
 match in all scrub (no-df)

 #### LAN allowed out Cable conn. 172.16.10.0/24 network out
 match out on $extnet from $intnet:network nat-to ($extnet)

 ############# FILTER RULES ###############
 block in log (all, to pflog0)
 ######### Default pass traffic #######
 pass out keep state
 pass in quick on $intnet
 ##(Pass traffic to and from another network, in this case a Wifi network with a seperate internet conn.)
 pass in quick on $rum0:network to $intnet:network
 pass out quick on $rum0:network to $intnet:network
 #### Anchor / Antispoof
 anchor "ftp-proxy/*"
 anchor "http-proxy/*"
 antispoof quick for { lo $intnet }
 antispoof for $extnet inet

 #### All outbound internet traffic ####
 pass out on $extnet proto { tcp udp icmp } all modulate state

 #### Inbound from the internet allows ####
 pass in log (all, to pflog0) on $extnet inet proto tcp from any to ($extnet) 
    port 22 flags S/SA keep state

 ############# Redirection Rules ################
 # SSH inbound from the internet example.
 pass in log on $extnet inet proto tcp from any to any port = 22 flags S/SA rdr-to 172.16.10.21
 ##END

OpenDNS Setup
If you have not heard about OpenDNS we recommend you take a look. The point is if you have a router where you can tell it to point to different DNS servers than what your ISP uses, then you can already start filtering the web for your network. You can use OpenDNS as a sort of “safety net” for anything inappropriate that DansGuardian might miss. If you don’t already have an OpenDNS account then go to www.opendns.com and sign up.

If you decide to use OpenDNS and don’t have a static IP address then you will need to download the client that they have. This client will update OpenDNS with your network’s public IP. This is important because if you want your filtering options to work for the computers on your network then it needs to know what network it is filtering.

The client can be found here: http://www.opendns.com/support/dynamicipdownloads/
You are only required to install it on a single PC that is running one of the applicable operating systems they have made a client install for.

You will need to point your Router to use following IP addresses as your DNS servers (if your OpenBSD DHCP config is Force feeding these settings you probably do not need to worry about re-configuring your ISPs device.:
• 208.67.222.222 • 208.67.220.220

For OpenBSD using a full Static IP network, you will edit the file /etc/resolv.conf to include the IP addresses of your desired DNS servers.

 bash-4.2# vi /etc/resolv.conf
 search wmfb.co
 nameserver 208.67.222.222
 nameserver 208.67.220.220
 lookup file bind

Modify your /etc/dhclient.conf :
If you are pulling DHCP from your ISP on OpenBSD, resolv.conf will be overwritten each time a lease is renewed. To ensure you keep certain options, like DNS, you must modify your /etc/dhclient.conf file to something similar:

 initial-interval 1;
 send host-name "portal";
 supersede host-name "portal";
 supersede domain-name-servers 208.67.222.222, 208.67.220.220;
 supersede domain-name "wmfb.co";
 request subnet-mask, broadcast-address, routers;

Installing Squid Proxy

 bash-4.2# export PKG_PATH=http://ftp.OpenBSD.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/
 bash-4.2# pkg_add -i squid
 Ambiguous: choose package for squid
 a  0: <None>
   1: squid-2.7.STABLEp19
   2:  squid-2.7.STABLEp19-ldap
   3:  squid-2.7.STABLEp19-ldap-snmp
   4:  squid-2.7.STABLEp19-ntlm
   5:  squid-2.7.STABLEp19-snmp

Squid Configuration
Full copy of Squid.conf can be found separately here:

Installing DansGuardian
bash-4.2# export PKGPATH=http://ftp.OpenBSD.org/pub/OpenBSD/uname -r/packages/uname -m/ bash-4.2# pkgadd -i dansguardian dansguardian-2.10.1.1:libexecinfo-0.2p0v0: ok dansguardian-2.10.1.1: ok

DansGuardian Configuration
Not a whole lot of changes are needed in the dansguardian.conf file to get you up and running. The configuration file should be located in the /etc/dansguardian directory. The only area you should need to edit is the “Network Settings” section of the configuration file. See below the example below:

 # Network Settings
 #
 # the IP that DansGuardian listens on.  If left blank DansGuardian will
 # listen on all IPs.  That would include all NICs, loopback, modem, etc.
 # Normally you would have your firewall protecting this, but if you want
 # you can limit it to a certain IP. To bind to multiple interfaces,
 # specify each IP on an individual filterip line.
 filterip = 172.16.10.1
 # the port that DansGuardian listens to.
 filterport = 8081
 # the ip of the proxy (default is the loopback - i.e. this server)
 proxyip = 172.16.10.1
 # the port DansGuardian connects to proxy on
 proxyport = 8080

Once complete you should be filtering your internet through Dansguardian. If Dansguardian isn’t started or for some reason is stopped you can type the following command:

 bash-4.2# /usr/local/share/dansguardian/scripts/bsd-init start

When you verify your internet traffic is being filtered by Dansguardian, you may want to do a few more configuration changes. We felt that some default lists needed to have a few modifications. There were websites and content Dansguardian was blocking that were what we considered appropriate. You can find these lists in /etc/dansguardian/lists.

Some examples include:
Exceptionsitelist
• In this list you can add (at the bottom of the file) websites you know that you can trust and want to be able to navigate around in. For example, Netflix was blocked for us by default. We appended the file with “Netflix.com”. You do not need to include http or www when adding sites, it just requires the domain.

Bannedextensionlist
• If you are like most, you probably still want to be able to download files that Dansguardian will block by default. You can comment out extensions such as exe, msi, msp, doc, xls, gz, tar, zip, bz2 etc… These will have to be a judgment call. You can’t protect yourself from everything so might as well make it easy for yourself to still access files from sources you have decided are safe.

Bannedmimetypelist
• Another file where some items were disabled. There are many things in this file you need to comment out if you want to use the technologies some websites utilize for video and other media. Again, this is a judgment call and you will have to decide what is worth the risk and works best for you. Weightedphraselist

• This list contains the various weighted phrases and assigns a sort of “point” system to the words. You may want to change your “naughtiness” limit if you find Dansguardian to be too strict. The default level is set to “50” which is said to be for “young children”. This setting is found in a file called dansguardianf1.conf located in /etc/dansguardian.
Below is an example of the “naughtiness limit” section of the file.

 # Naughtyness limit
 # This the limit over which the page will be blocked.  Each weighted phrase is given
 # a value either positive or negative and the values added up.  Phrases to do with
 # good subjects will have negative values, and bad subjects will have positive
 # values.  See the weightedphraselist file for examples.
 # As a guide:
 # 50 is for young children,  100 for old children,  160 for young adults.
 naughtynesslimit = 100

For the most part we found that these were the primary lists we needed to edit in order to still have the functionality we prefer while still filtering out some of the inappropriate content on the web. You may want to research and look at the other lists and change the options that were selected to suite your needs.

As a side note, DansGuardian has the capability to do some URL re-writing. This is useful if you want to control content found in Google picture searches or YouTube. For example, you can URL re-write to force “safe search” for Google Images. You can also sign up for a YouTube for Schools account and apply a URL re-write to include your “edu-filter”. This may be something we cover in another post for those who are interested.

There you have it. Centralized, un-bypassable, web-browsing control.