Welcome to the new location of Alien's Wiki, sharing a single dokuwiki install with the SlackDocs Wiki.
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
slackware:proxy [2006/06/07 10:42] – alien | slackware:proxy [2006/06/08 14:40] – alien | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Transparent Proxy with contentfilter ====== | ====== Transparent Proxy with contentfilter ====== | ||
- | |||
- | **FIXME** UNDER CONSTRUCTION **FIXME** | ||
===== Introduction ===== | ===== Introduction ===== | ||
Line 7: | Line 5: | ||
This article describes the setup of a http proxy chained to a content filter (think " | This article describes the setup of a http proxy chained to a content filter (think " | ||
- | There are many cases, where is not desirable to grant unlimited Internet access to certain groups of people. The most obvious group are children, either at home, or in schools, whom you want to protect from hitting upon too explicit imagery or language. Or perhaps you just want to block certain sites from them.\\ | + | There are many cases, where is not desirable to grant unlimited Internet access to certain groups of people. The most obvious group are children, either at home, in schools |
Other uses for a content-filtering web proxy would be companies that want to limit the accessibility of the Internet facility they allow their employees. Content filtering does not stop at blocking undesirable content - blocking viruses in downloaded materials and malicious HTML code is another form of filtering incoming web traffic.\\ | Other uses for a content-filtering web proxy would be companies that want to limit the accessibility of the Internet facility they allow their employees. Content filtering does not stop at blocking undesirable content - blocking viruses in downloaded materials and malicious HTML code is another form of filtering incoming web traffic.\\ | ||
A web proxy is what you need in this case. The proxy server intercepts all browser requests for web pages, and in co-operation with one or more filtering programs, decides whether the browser will or won't be able to retrieve the full content it was requesting. | A web proxy is what you need in this case. The proxy server intercepts all browser requests for web pages, and in co-operation with one or more filtering programs, decides whether the browser will or won't be able to retrieve the full content it was requesting. | ||
Line 15: | Line 13: | ||
Ideally, you would want a solution where such a filtering proxy server is installed on the Internet Gateway Server, and the desktop computers would not have to be be reconfigured to make use of the proxy. This is called // | Ideally, you would want a solution where such a filtering proxy server is installed on the Internet Gateway Server, and the desktop computers would not have to be be reconfigured to make use of the proxy. This is called // | ||
- | I will show you how you can use [[http:// | + | I will show you how you can use [[http:// |
< | < | ||
+ | |||
+ | <note tip>This article focuses on the configuration of a transparent proxy on a gateway/ | ||
+ | |||
+ | ===== How it works ===== | ||
+ | |||
+ | The usual flow of traffic in a network without proxies of any kind is like this:\\ | ||
+ | browser -> (gateway) -> (internet) -> webserver | ||
+ | |||
+ | The client browser' | ||
+ | |||
+ | With a proxy/ | ||
+ | browser -> (contentfilter -> proxy on gateway) -> internet -> webserver | ||
+ | |||
+ | The browser talks to the address/ | ||
+ | |||
+ | Now, when the gateway is configured for transparent proxying, the browser does not (have to) know this. The flow is like this: | ||
+ | browser -> (gateway eth1)....(gateway eth0) -> internet -> webserver | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | The browser request is again routed through the default gateway as in the first picture, only now we have an '' | ||
+ | |||
+ | < | ||
===== Network layout ===== | ===== Network layout ===== | ||
Line 25: | Line 48: | ||
//Table 1.// __Server:__ | //Table 1.// __Server:__ | ||
- | ^ Interface | + | ^ Interface |
- | | eth0 | 10.111.111.129 | + | | eth0 | dynamic |
- | | eth1 | 192.168.0.1 | + | | eth1 | static |
//Table 2.// __Internal Network:__ | //Table 2.// __Internal Network:__ | ||
^ Network | ^ Network | ||
- | | 192.168.0.0 | 255.255.255.0 | + | | 192.168.2.0 | 255.255.255.0 |
+ | |||
+ | //Table 3.// __Listen ports:__ | ||
+ | ^ Program | ||
+ | | dansguardian | ||
+ | | tinyproxy | ||
The server' | The server' | ||
Line 47: | Line 75: | ||
# Config information for eth1: | # Config information for eth1: | ||
- | IPADDR[1]=" | + | IPADDR[1]=" |
NETMASK[1]=" | NETMASK[1]=" | ||
USE_DHCP[1]="" | USE_DHCP[1]="" | ||
Line 56: | Line 84: | ||
</ | </ | ||
- | **FIXME** UNDER CONSTRUCTION **FIXME** | ||
===== Getting and building the software ===== | ===== Getting and building the software ===== | ||
+ | ==== Building tinyproxy ==== | ||
+ | |||
+ | The [[http:// | ||
+ | Tinyproxy must explicitly be build for transparent proxy support. If you want to compile and install the software manually, this is what you would do: < | ||
+ | tar -zxvf tinyproxy-1.7.0.tar.gz | ||
+ | cd tinyproxy-1.7.0 | ||
+ | ./configure --prefix=/ | ||
+ | --localstatedir=/ | ||
+ | --sysconfdir=/ | ||
+ | --enable-xtinyproxy \ | ||
+ | --enable-filter \ | ||
+ | --enable-upstream \ | ||
+ | --enable-reverse \ | ||
+ | --enable-transparent-proxy \ | ||
+ | --program-prefix="" | ||
+ | --program-suffix="" | ||
+ | make | ||
+ | make install | ||
+ | </ | ||
+ | |||
+ | ==== Building dansguardian ==== | ||
+ | |||
+ | The dansguardian software is actively maintained. You will need the basic software package you can download from the [[http:// | ||
+ | Although the most current release is in the //ALPHA// download section, it's actually quite stable. I used that for my install. For the manually compiling people: < | ||
+ | tar -zxvf dansguardian-2.9.7.0.tar.gz | ||
+ | cd dansguardian-2.9.7.0 | ||
+ | ./configure --prefix=/ | ||
+ | --localstatedir=/ | ||
+ | --sysconfdir=/ | ||
+ | --enable-pcre \ | ||
+ | --enable-clamd \ | ||
+ | --enable-email \ | ||
+ | --with-proxyuser=nobody \ | ||
+ | --with-proxygroup=nobody | ||
+ | make | ||
+ | make install | ||
+ | </ | ||
+ | I configured dansguardian to run as user //nobody// - because that is an existing account without provileges, and Apache uses it too. If you want another account change the '' | ||
+ | |||
+ | |||
+ | ===== Configuration ===== | ||
+ | |||
+ | That was it! Now, it is time to start configuring our proxying service. | ||
+ | |||
+ | ==== tinyproxy config ==== | ||
+ | |||
+ | The content of the tinyproxy configuration file ''/ | ||
+ | I entered the domain name for my internal lan //my.net// in this configuration file. If yours is different, please change accordingly.\\ To show you where this differs from the tinyproxy defaults, here is a diff from the original file: <code diff> | ||
+ | diff / | ||
+ | 20c20 | ||
+ | < Port 8888 | ||
+ | --- | ||
+ | > Port 3128 | ||
+ | 27c27 | ||
+ | < #Listen 192.168.0.1 | ||
+ | --- | ||
+ | > Listen 127.0.0.1 | ||
+ | 34c34 | ||
+ | < #Bind 192.168.0.1 | ||
+ | --- | ||
+ | > Bind 10.111.111.1 | ||
+ | 112c112 | ||
+ | < #XTinyproxy mydomain.com | ||
+ | --- | ||
+ | > XTinyproxy my.net | ||
+ | 192c192 | ||
+ | < Allow 192.168.1.0/ | ||
+ | --- | ||
+ | > Allow 192.168.2.0/ | ||
+ | </ | ||
+ | Port 3128 | ||
+ | Listen 127.0.0.1 | ||
+ | Bind 10.111.111.1 | ||
+ | Allow 127.0.0.1 | ||
+ | Allow 192.168.2.0/ | ||
+ | These achieve the following: | ||
+ | * make tinyproxy listen on '' | ||
+ | * bind to the external interface (IP address '' | ||
+ | * allow the localhost (IP address 127.0.0.1, for dansguardian) as well as all the computers in your internal LAN (IP address range 192.168.2.0-192.168.2.255) access -implicitly denying access attempts from any other IP address but those. | ||
+ | |||
+ | |||
+ | ==== dansguardian config ==== | ||
+ | |||
+ | You will find the content of the dansguardian configuration file ''/ | ||
+ | diff / | ||
+ | 48a50 | ||
+ | > anonymizelogs = off | ||
+ | 74c76 | ||
+ | < filterip = | ||
+ | --- | ||
+ | > filterip = 192.168.2.1 | ||
+ | 97c99 | ||
+ | < accessdeniedaddress = ' | ||
+ | --- | ||
+ | > accessdeniedaddress = ' | ||
+ | </ | ||
+ | filterip = 192.168.2.1 | ||
+ | filterport = 8080 | ||
+ | proxyip = 127.0.0.1 | ||
+ | proxyport = 3128 | ||
+ | They show that dansguardian | ||
+ | * will listen at the // | ||
+ | * will look for a compatible proxy at IP address: | ||
+ | |||
+ | The line | ||
+ | accessdeniedaddress = ' | ||
+ | does not really matter, because in dansguardian' | ||
- | ===== Configuration | + | Of course, there is a lot of fine-tuning possibilities in this configuration file, as well as many others in the ''/ |
===== The iptables firewall ===== | ===== The iptables firewall ===== | ||
+ | For a transparent proxy setup, you will need to be running a __//NAT// or // | ||
+ | |||
+ | So, back to our server... You will either have to setup an iptables firewall script on your Internet Gateway, or modifiy an existing iptables firewall ruleset.\\ | ||
+ | The Slackware boot scripts expect your firewall script to be named < | ||
+ | |||
+ | * If you are in the process of setting up a router/ | ||
+ | # Redirect HTTPS for a transparent proxy - commented by default | ||
+ | $IPT -t nat -A PREROUTING -p tcp --destination-port 443 \ | ||
+ | -j REDIRECT --to-ports 8080 | ||
+ | </ | ||
+ | # This is a sample that will exempt a specific host from the transparent proxy | ||
+ | #$IPT -t nat -A PREROUTING -p tcp -s 192.168.1.50 --destination-port 80 \ | ||
+ | # -j RETURN | ||
+ | #$IPT -t nat -A PREROUTING -p tcp -s 192.168.1.50 --destination-port 443 \ | ||
+ | # -j RETURN | ||
+ | </ | ||
+ | |||
+ | * For those who already have an iptables firewall script in place and want to know what they have to add in order to enable the transparent proxying; these are the important lines. Add them somewhere in your script. < | ||
+ | # Redirect HTTP for a transparent proxy | ||
+ | / | ||
+ | -j REDIRECT --to-ports 8080 | ||
+ | # Redirect HTTPS for a transparent proxy - commented by default | ||
+ | / | ||
+ | -j REDIRECT --to-ports 8080 | ||
+ | </ | ||
+ | |||
+ | ===== Starting the programs ===== | ||
+ | |||
+ | If you configured your firewall rules in the file ''/ | ||
+ | if [ -x / | ||
+ | / | ||
+ | fi | ||
+ | </ | ||
+ | if [ -x / | ||
+ | / | ||
+ | fi | ||
+ | |||
+ | # Start dansguardian | ||
+ | if [ -x / | ||
+ | / | ||
+ | fi | ||
+ | </ | ||
+ | Both programs log their actions; to respectively ''/ | ||
+ | |||
+ | That is all there is to it! Now, test your rig by booting a client computer in your LAN and trying out a couple of URLs. I will leave it to your own imagination as to what URLs will be considered // | ||
+ | |||
+ | To stop these programs if you need to, you run < | ||
+ | / | ||
+ | killall -TERM tinyproxy | ||
+ | </ | ||
+ | |||
+ | ===== Adding virus scanning ===== | ||
+ | |||
+ | |||
+ | **FIXME** UNDER CONSTRUCTION **FIXME** | ||
===== Pitfalls ===== | ===== Pitfalls ===== | ||
+ | |||
+ | There might be cases where you don't want transparent proxying. For instance, some applications will not correctly connect through a transparent proxy. The (client side) user agent does not know it passes a proxy, so it possibly will not send correct HTTP headers to the remote server. Most modern browsers are standards-compliant however and will work fine. If your users need Internet Explorer, it must be newer than 5.5_SP1. For those cases where transparent proxying is impossible, you must configure your browsers explicitly to use the proxy. How to do this in a semi-centralized way is described in [[# | ||
+ | |||
+ | ===== Manual proxy configuration ===== | ||
+ | |||
+ | A handy way of browser configuration is the //Proxy Auto-Configuration// | ||
+ | You can read more about PAC on the [[http:// | ||
+ | |||
+ | To give an example, create a file on your Gateway server' | ||
+ | function FindProxyForURL(url, | ||
+ | { | ||
+ | //Traffic to the localhost should go directly; | ||
+ | //If they have only specified a hostname, go directly. | ||
+ | if (isInNet(host, | ||
+ | return " | ||
+ | //So the error message "no such host" will appear through the | ||
+ | //normal browser dialog box - less support queries :) | ||
+ | if (!isResolvable(host)) | ||
+ | return " | ||
+ | // Don't use a proxy inside our own LAN | ||
+ | else if (isInNet(host, | ||
+ | return " | ||
+ | //We only cache https and http | ||
+ | else if (url.substring(0, | ||
+ | url.substring(0, | ||
+ | return "PROXY 192.168.2.1: | ||
+ | // Catch-all | ||
+ | else | ||
+ | return " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | If your webserver is Apache, and your browsers spits out an error on the " | ||
+ | # | ||
+ | # MIME type for proxy autoconfiguration: | ||
+ | # | ||
+ | AddType application/ | ||
+ | </ | ||
===== Example configuration files ===== | ===== Example configuration files ===== | ||
+ | ''/ | ||
+ | < | ||
+ | User nobody | ||
+ | Group nogroup | ||
+ | Port 3128 | ||
+ | Listen 127.0.0.1 | ||
+ | Bind 10.111.111.1 | ||
+ | Timeout 600 | ||
+ | DefaultErrorFile "/ | ||
+ | StatFile "/ | ||
+ | Logfile "/ | ||
+ | LogLevel Info | ||
+ | PidFile "/ | ||
+ | XTinyproxy my.net | ||
+ | MaxClients 100 | ||
+ | MinSpareServers 5 | ||
+ | MaxSpareServers 20 | ||
+ | StartServers 10 | ||
+ | MaxRequestsPerChild 0 | ||
+ | Allow 127.0.0.1 | ||
+ | Allow 192.168.2.0/ | ||
+ | ViaProxyName " | ||
+ | ConnectPort 443 | ||
+ | ConnectPort 563 | ||
+ | </ | ||
+ | |||
+ | ''/ | ||
+ | < | ||
+ | reportinglevel = 3 | ||
+ | languagedir = '/ | ||
+ | language = ' | ||
+ | loglevel = 2 | ||
+ | logexceptionhits = on | ||
+ | logfileformat = 1 | ||
+ | anonymizelogs = off | ||
+ | filterip = 192.168.2.1 | ||
+ | filterport = 8080 | ||
+ | proxyip = 127.0.0.1 | ||
+ | proxyport = 3128 | ||
+ | accessdeniedaddress = ' | ||
+ | nonstandarddelimiter = on | ||
+ | usecustombannedimage = 1 | ||
+ | custombannedimagefile = '/ | ||
+ | filtergroups = 1 | ||
+ | filtergroupslist = '/ | ||
+ | bannediplist = '/ | ||
+ | exceptioniplist = '/ | ||
+ | showweightedfound = on | ||
+ | weightedphrasemode = 2 | ||
+ | urlcachenumber = 1000 | ||
+ | urlcacheage = 900 | ||
+ | scancleancache = on | ||
+ | phrasefiltermode = 2 | ||
+ | preservecase = 0 | ||
+ | hexdecodecontent = 0 | ||
+ | forcequicksearch = 0 | ||
+ | reverseaddresslookups = off | ||
+ | reverseclientiplookups = off | ||
+ | logclienthostnames = off | ||
+ | createlistcachefiles = on | ||
+ | maxuploadsize = -1 | ||
+ | maxcontentfiltersize = 256 | ||
+ | maxcontentramcachescansize = 2000 | ||
+ | maxcontentfilecachescansize = 20000 | ||
+ | filecachedir = '/ | ||
+ | deletedownloadedtempfiles = on | ||
+ | initialtrickledelay = 20 | ||
+ | trickledelay = 10 | ||
+ | downloadmanager = '/ | ||
+ | downloadmanager = '/ | ||
+ | contentscannertimeout = 60 | ||
+ | contentscanexceptions = off | ||
+ | recheckreplacedurls = off | ||
+ | forwardedfor = off | ||
+ | usexforwardedfor = off | ||
+ | logconnectionhandlingerrors = on | ||
+ | logchildprocesshandling = off | ||
+ | maxchildren = 120 | ||
+ | minchildren = 8 | ||
+ | minsparechildren = 4 | ||
+ | preforkchildren = 6 | ||
+ | maxsparechildren = 32 | ||
+ | maxagechildren = 500 | ||
+ | maxips = 0 | ||
+ | ipcfilename = '/ | ||
+ | urlipcfilename = '/ | ||
+ | ipipcfilename = '/ | ||
+ | nodaemon = off | ||
+ | nologger = off | ||
+ | logadblocks = off | ||
+ | softrestart = off | ||
+ | mailer = '/ | ||
+ | </ | ||
+ | |||
+ | ''/ | ||
+ | < | ||
+ | #!/bin/sh | ||
+ | # | ||
+ | # Startup script for dansguardian | ||
+ | # | ||
+ | # processname: | ||
+ | # pidfile: / | ||
+ | # config: / | ||
+ | |||
+ | # File includes changes by Thomas Jarosch | ||
+ | function wait_for_pid() | ||
+ | { | ||
+ | local PID=$1 | ||
+ | local RET=0 | ||
+ | | ||
+ | if [ $PID -eq 0 ] ; then | ||
+ | return $RET | ||
+ | fi | ||
+ | | ||
+ | # give 60 secs then KILL | ||
+ | local COUNTDOWN=60 | ||
+ | |||
+ | while [ -d / | ||
+ | sleep 1 | ||
+ | COUNTDOWN=$[$COUNTDOWN-1] | ||
+ | done | ||
+ | |||
+ | if [ -d / | ||
+ | COMMAND=`ps h -o command ${PID}` | ||
+ | logger " | ||
+ | kill -KILL $PID >/ | ||
+ | RET=1 | ||
+ | fi | ||
+ | | ||
+ | return $RET | ||
+ | } | ||
+ | |||
+ | # See how we were called. | ||
+ | |||
+ | case " | ||
+ | start) | ||
+ | if [ -f / | ||
+ | [ -f / | ||
+ | echo -n " | ||
+ | if / | ||
+ | echo " OK" | ||
+ | else | ||
+ | echo " FAILED" | ||
+ | fi | ||
+ | fi | ||
+ | ;; | ||
+ | stop) | ||
+ | echo -n " | ||
+ | WAITPID=0 | ||
+ | if [ -f / | ||
+ | WAITPID=`cat / | ||
+ | fi | ||
+ | if / | ||
+ | if wait_for_pid $WAITPID ; then | ||
+ | echo " OK" | ||
+ | else | ||
+ | echo " FAILED" | ||
+ | fi | ||
+ | /bin/rm -f / | ||
+ | /bin/rm -f / | ||
+ | else | ||
+ | echo " FAILED" | ||
+ | fi | ||
+ | ;; | ||
+ | restart) | ||
+ | $0 stop | ||
+ | $0 start | ||
+ | ;; | ||
+ | status) | ||
+ | if [ -x / | ||
+ | / | ||
+ | else | ||
+ | echo " | ||
+ | fi | ||
+ | ;; | ||
+ | *) | ||
+ | echo " | ||
+ | ;; | ||
+ | esac | ||
+ | |||
+ | exit 0 | ||
+ | </ | ||
+ | |||
+ | ''/ | ||
+ | < | ||
+ | / | ||
+ | rotate 4 | ||
+ | weekly | ||
+ | sharedscripts | ||
+ | prerotate | ||
+ | / | ||
+ | sleep 5 | ||
+ | endscript | ||
+ | |||
+ | postrotate | ||
+ | / | ||
+ | endscript | ||
+ | } | ||
+ | </ |