Iptables to redirect outgoing traffic to loopback

I'm using squid and need to redirect outgoing port 80 traffic to the loopback 3128 port.  I used

 iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner *username* -j REDIRECT --to-ports 3128

and setting the browser proxy to worked fine.  However, several apps I have work through port 80 and can't be set to "proxy", and they fail.  If I tell my web server to just use port 80 directly I get an error that the host "/" canot be found.

Obviously the above rule is redirecting the hosts request to squid, and thinks my local computer is google.com or whatever.  Squid chokes on just a page name coming in and the whole thing fails.  What I need to do is redirect the request that is going out to a port 80 so the whole request filters through as if it were a proxy.

Is there any way to do this?
LVL 11
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gabriel OrozcoSolution ArchitectCommented:
hello KurtVon

You cannot redirect a port in the OUTPUT table. if you want to rewrite destination BEFORE packet is processed, you should use PREROUTING. so, rule is as follow:

iptables -t nat -A PREROUTING -i $LAN -p tcp --dport 80 -j REDIRECT --to-port 3128
($LAN is eth0 or eth1, your internal LAN device)

that's the rule I have on my iptables.

however, you should also configure squid for transparent mode, this is, to review in the headers for the site it should get, since the real ip address has been rewrited to be by your iptables.

So, to run Squid in a transparent mode, enable the following directives in Squid.conf.

httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
KurtVonAuthor Commented:
I only have an eth0 on this machine, but the rule doesn't seem to be doing anything.  I checked the iptables list and it is there, but setting the web browser to direct internet connection allows all website through.

Even if the prerouting worked, though, it filters all traffic.  I was hoping to use the owner filter to limit the redirection to just my daughter's whitelisted sites (she's five, I don't think ip filtering at that age is evil).  Now it's not like I want the sixteen year old visiting naked-people-doing-scary-things.com, but I was hoping he was old enough to trust with looser constraints than just visiting noggin.com.
Gabriel OrozcoSolution ArchitectCommented:
Hello KurtVon

this rule is exactly for setting the browser to direct internet connection. it's because of that is called "transparent proxy" because it should behave transparent.

if you do not see the rule doing anything, it should be because you have another rule that match before the one I posted. please change the rule to be
iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

you should be able to see if packets are matching and transversing that rule if you issue
iptables -L -vn -t nat
and you should see some packets at the left of the rule (once you browsed, that is)

This said, I feel I didn't understand the whole picture here. Maybe you are trying to setup squid on the same computer you are using for browsing? (Rules I posted where for the case of some machines going to internet thru a linux gateway con squid in transparent mode)

if so, you cannot make transparent proxy unless you enable some extended rules to "NAT" anything from localhost...
in such case I would do this:

setup squid, go to the browser and enable proxy for the browser (your daughter is 5, so no problem she can hack your rules)
and then disable any transaction from localhost to web pages. then yes, your rule makes more sense to me, but the rule should match only direct access:
iptables  -A OUTPUT -p tcp --dport 80 -m owner --uid-owner *username* -j DROP

with this, she will be unable to browse directly, but will need squid to access web. squid should be configured to enable only the whitelists you told.
but your own user will not match the rule thus being able to access anything, of course, no squid for you.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

KurtVonAuthor Commented:
Aha, that is the issue.  Since I don't have a machine I keep on all the time, I'm running squid on the machine that is also doing the browsing.  So I set my browser proxy to

And my rule was working fine for blocking non-proxied web browsing.  The problem is she has a weather applet (she's studying weather in school) and an RSS feed from the my little pony website.  Neither of these applets have proxy settings that I can see, so I have to do the redirect in iptables unless there is another trick.  Not that I'm mourning the loss of a live feed from my little pony.

I'd love to rely on just the fact that she doesn't know how to change the proxy settings, but some playdates are with kids that have older brothers, and I'd like to stay on speaking terms with their parents if the kid messes with the settings.
Gabriel OrozcoSolution ArchitectCommented:

could you open only the ip address of the weather site?
KurtVonAuthor Commented:
I'm not sure what you mean.  The app seems to work by doing an http request to the national weather bureau, and then parsing the response page.  Without a way to make it use a proxy I'm not sure what to do.  

If there was some way to control routing on a per-user basis at the interface I could set the routing table itself, but I was given the impression that only iptables can filter like that.  If it can't be done then it can't be done, I guess.
KurtVonAuthor Commented:
Hmph.  Answered my own question.  I have a script set the network to a proxy when she logs in.  Given that, blocking port 80 for her by user will ensure that even editing the proxy settings will not bypass the filter.

Gabriel OrozcoSolution ArchitectCommented:
Thank you
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Linux Networking

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.