-   Slackware (
-   -   Squid and iptables---transparent proxying (

Woodsman 09-29-2006 04:22 AM

Squid and iptables---transparent proxying
On my second box I have squid configured as a transparent proxy and my iptables rules are set to redirect outgoing traffic to port 80 to the squid port 3128. With my primary box I need only configure my underlying network configuration to use the second box as my LAN gateway. I need not configure my browser on that box to use any proxy. On my second box the iptables rule looks like this:

$IPT -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-ports 3128

This rule intercepts web browsing requests from my first box and routes the request to squid. From the perspective of my primary box, all of this works great and I benefit by using the squid cache.

My challenge is that my second box is also a workstation and I want to cache browser sessions from that box too. Yes, I can manually configure the browser to proxy through port 3128, but I prefer to have iptables intercept the local browser session. That way additional users cannot bypass the cache simply by undoing the browser proxy.

I'm not savvy with iptables syntax, although I understand the basic concepts. Still learning! I've tried my hand at writing a rule to no avail and I keep searching for clues but I must be using the wrong keywords. I want a rule similar to above that says "any outgoing request originating from this local box heading outward to port 80, redirect to port 3128."

Is this possible? :confused: If so, would somebody please post a rule?

Thanks again.

Alien Bob 09-29-2006 05:08 AM

I think you will be much helped by this article which I wrote some time ago. It deals with "parental control" for Linux desktops.
I don't think you want that level of control :-) but it contains a sample iptables script that you can apply to your case.


onebuck 09-29-2006 10:27 AM


Eric, I don't mean to hijack this thread. I just read your parental control article. Great reference!

You stated that squid could be used but that Tinyproxy for a small network would be the best choice in the article transparent proxy. My question is what is the difficulty with squid that you implied? I've been working to setup my proxy for SOHO network. Tinyproxy does look like the easiest choice for this type of network.

What about DansGuardian 2.9 as the filter?

edit: correct LQ spell check misses

Alien Bob 09-29-2006 01:11 PM


Originally Posted by gwsandvik
You stated that squid could be used but that Tinyproxy for a small network would be the best choice. My question is what is the difficulty with squid that you implied?

Well simply squid eats a lot of resources, and IMHO that is better justifiable when the number of PC's you're serving is larger. Also I think squid is a bitch to patch and compile. On the other hand, tinyproxy seems rather unmaintained but I never had any problems with it.


What about DansGuardian 2.9 as the filter?
You'll notice that my article mentions dansguardian 2.9. In fact newer releases came out after I wrote the article, one of them has my updated dutch translation added :-)


onebuck 09-29-2006 03:58 PM


Thanks! I think that tinyproxy will be the way to go. Using dansguardian 2.9. I've been working with Squid and I think it is a bit much for a small network.

BTW, thanks for the script samples.

Woodsman 09-29-2006 07:27 PM

I appreciate your effort Eric, but I remain stumped!

In pursuit of redirecting all network and local web traffic through the squid proxy, I tried the following rules:

$IPT -t nat -A PREROUTING -p tcp -s $LO_IP --dport 80 -j REDIRECT --to-ports $PROXY_PORT
$IPT -t nat -A PREROUTING -p tcp -s $LAN_IP --dport 80 -j REDIRECT --to-ports $PROXY_PORT
$IPT -t nat -A PREROUTING -p tcp -s $INET_IP --dport 80 -j REDIRECT --to-ports $PROXY_PORT

Seems to me that if the source is localhost, the LAN IP or the intertnet IP, these rules should redirect, but they don't.

I watch the squid logs increase in size when my primary workstation hits a web page through Box 2. I watch the logs increase in size if I manually configure the browser to use the squid proxy. But I cannot seem to find the correct rule to redirect the local browser through the squid proxy.

To summarize, Box 2 is my LAN gateway but also is a workstation. I want to redirect all web traffic initiated locally at Box 2 through the squid caching proxy. I do not want to redirect through the browser settings, which can be defeated manually.

My rule to redirect all incoming LAN traffic to squid, which works fine:

$IPT -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-ports $PROXY_PORT

Any help from all of you iptables gurus is much welcomed!

acummings 09-30-2006 01:13 AM


Any help from all of you iptables gurus is much welcomed!
Well, that excludes me. :-)

(just a guess, I know rather little) I wonder if you need to specify an interface?

-i eth0

-i eth1 etc. etc. etc.

that's howto for on same box (what you want, right?) that squid runs on (though I didn't see mention if that box also is gateway box but likely would be as in what else would you run squid on besides a gateway box)

hit the next button to see howto on a lan box that is not the box that squid runs on.

How many NIC in your gateway box versus how many NIC in the other non-gateway box?


Woodsman 09-30-2006 03:01 AM


Well, that excludes me. :)
Me too! :)

I finally solved my problem. However, this was not one of those problems that when finally solved provides a good warm fuzzy feeling. I racked my brain over this and I'm ready to shut down the computers for a week!

For those who are interested, my fundamental stumbling block was understanding that NAT works differently for those boxes being routed through the gateway box than from those people using the box directly. The former group of people is regulated by PREROUTING directives in the firewall rules, but local users are not routed---they are direct users. Thus, although I was on the right track as can be seen by my previous post with trying to create rules based upon localhost, local IP address, etc, I nonetheless was doing so through the PREROUTING directive and that is why nothing worked. To redirect local users the OUTPUT table is the target, not the PREROUTING table.

Most articles and How-Tos addressing the topic of proxies and NAT are written from the perspective of dedicated servers and hence, the writers did not address the issue I was facing. I am sure many other people have struggled with this issue---perhaps a mini How-To is slated for my web site. After I understood this distinction I found a few clues online and then finally stumbled across a How-To that provided the exact rules I needed (my mind is sufficiently whipped that I do not remember the link). But once again, the author never really addressed this distinction of trying to proxy through a gateway that happens also to be a workstation. What helped me see the light was a reader's comment about providing a filter and proxy on only one workstation. That caught my eye and then I reviewed the article more closely and saw the trick.

This particular topic of trying to redirect local users through a proxy installed on that same box is a classic example of writers assuming that this small distinction is obvious and needs no explanation.

Anyway, here are the rules I finally used to make this work. Bear in mind that these rules are only a subset of my overall firewall rule set. Understand too that I long ago generated my original rule set at I think Eric (Alien Bob) uses the same generator scripts at his wiki. I also liberally modify my /etc/rc.d/rc.inet1.conf file with additional variables, such as TRANS_PROXY and PROXY_PORT. Yes, one of these days I would like to post a How-To at my web site explaining how I use my firewall because my rule set grew out of a dialup environment with a two-box network, of which one box is multi-boot and either box could connect to the web, leaving the other box needing gateway services. Most people would have simply installed a dedicated server. {Shrug} Thus my rule set has several variables I added to help determine whether the box is acting as a stand-alone, LAN participant, or a LAN gateway.


# Redirect HTTP through a transparent proxy
if [ "$TRANS_PROXY" = "yes" ] ; then
echo "Forcing gateway services to transparent proxy."

# first provide prerouting exception rules from the LAN
#echo "Providing transparent proxy rerouting exception for address 192.168.1.xx"
#$IPT -t nat -A PREROUTING -p tcp -s 192.168.1.xx --dport 80 -j RETURN
#$IPT -t nat -A PREROUTING -p tcp -s 192.168.1.xx --dport 443 -j RETURN

# next define what from the LAN is routed through the proxy
#$IPT -t nat -A PREROUTING -p tcp --dport 21 -j REDIRECT --to-ports $PROXY_PORT
$IPT -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports $PROXY_PORT
#$IPT -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports $PROXY_PORT

# don't forget to route local users through the proxy
$IPT -t nat -A OUTPUT -p tcp -m owner --dport 80 --uid-owner squid -j ACCEPT
$IPT -t nat -A OUTPUT -p tcp -m owner --dport $PROXY_PORT --uid-owner squid -j ACCEPT

# exempt certain local users
#$IPT -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner x_user_name_x -j ACCEPT

# now set final rule for the proxy
$IPT -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports $PROXY_PORT


The key rules that I needed to redirect web traffic from local users are bolded. Notice that many of the rules are commented. I inserted them for my future reference should my needs change and I wanted the rules later.

Notice the user/owner name of squid. If you have your squid currently configured to use the default user:group of nobody:nogroup, then those labels would be appropriate in the above rules. This was the way I was running since installing squid several days ago. However, once I found these firewall rules I thought prudent that reassigning ownership of the squid files to squid:squid more appropriate. So I had to 1) create that user and group, 2) modify the cache-effective_user and cache-effective_group directives in /etc/squid.conf, 3) shut down squid, 4) chown all log and cache files to the new user and group, and then 5) restart squid.

One caveat, this trick requires that all the iptables modules be supported by the kernel. Fortunately for Slackers, this is already the case, but future visitors to this thread using other distros will need to verify further.

To Eric's credit, his wiki How-To linked above does create similar rules, but from my perspective of wanting only to create a caching proxy, and not caring about filtering, I did not see the rules applying to me when I reviewed the page earlier. This problem was classic in that I knew what I wanted to do---exactly---but I did not understand the subject matter sufficiently (iptables) to recognize the solution. :scratch: But I don't feel like celebrating because the solution took a lot of time and a lot of head beating---my mind is whipped. :confused:

Anyway, I hope this update helps somebody else!

Alien Bob 09-30-2006 06:57 AM

I added a short note about using the OUTPUT chain as opposed to the PREROUTING chain (which is commonly associated with NAT rules) to my Wiki article.


Woodsman 09-30-2006 03:49 PM


I added a short note about using the OUTPUT chain as opposed to the PREROUTING chain (which is commonly associated with NAT rules) to my Wiki article.
You're a good person Eric and I appreciate all of your help in this forum and with Slackware in general! :) I sincerely hope you realize that none of my frustrations embedded within my previous post were directed toward you. They were not and that was why I added my reference to your wiki. In hindsight I realize your How-To contained the requisite information, but my inexperience with iptables kept me from seeing the solution. :confused:

Regarding your recently added note. How about the following revision (or something similar that suits your tastes and writing style):

"Please know that unlike a dedicated server that is not used as a workstation, in our case we are using a workstation to share our internet connection. A dedicated server needs only to re-route incoming LAN packets whereas a workstation also must redirect locally generated traffic through our proxy system. Therefore to catch the internet traffic generated locally from users at the workstation where we are sharing our internet connection, the NAT rules are not used to change the source or destination IP address (masquerading). This box is connected directly to the ISP and the PREROUTING rules do not apply. There is nothing to masquerade because of the direct connection. For local users, as opposed to incoming LAN traffic, we instead modify the iptables rules in the OUTPUT chain. We redirect the destination of the locally generated network packets, not re-route through the NAT chain. Please understand this distinction."

Also, consider placing the note prior to the code snippet. Placing notes before the information tends to subconsciously alert readers. Placing notes after instructions often are not absorbed correctly.

I know just enough about iptables to understand some basic concepts and to realize that if I dedicated several hours to studying the topic I would be better prepared to handle iptables. But iptables is complicated, and I am going to invest time looking for some (KDE) front-ends that help configure iptables. There just has to be an easier way to deal with iptables. :)

Not to open a hornet's nest, but this is one specific topic where Windows shines. To share an internet connection within a Windows workstation requires a few mouse clicks and the process is done. And as fun and challenging as tinkering might be, sometimes I too just want to point and click and move on to other things on my projects list. :)

Thanks for all your help Eric. I appreciate your time and knowledge. :cool:


Eric, could the firewall rule generator you offer at your wiki be modified to provide appropriate check boxes such that when users select the proxy option, that the script also provides a check box asking the user whether the box is a dedicated server or a shared workstation? If the user selects the workstation option then the script would request the additional information such that the OUPUT chain would be modified for local users. This approach would help people avoid the issue described in this thread.

All times are GMT -5. The time now is 11:05 AM.