Tor/Iptables Question

Ringo 2600denver at gmail.com
Sun Aug 23 04:40:54 UTC 2009


Oh man I'm getting headaches, this should not be that complex. Here's
what I want it to do.

1. Block the user "torify" from accessing anything except port 9050 and
8118 on localhost. No external connections allowed and no other internal
connections allowed.

2. Allow all other users to connect anywhere, including local ports
except port 8888. Only the user "debian-tor" should be allowed to
connect to 8888.

If we can get these taken care of, we've got a set of iptables rules for
torifying programs running under the torify user and a great way to
sandbox a virtual machine hosting a hidden service.

This ruleset works at sandboxing the torify user but unfortunately
allows them to access other ports such as 631 which contains CUPS. It
also allows any user to access the hidden service at 8888.

#block hidden service port to everybody but localhost
sudo iptables -A INPUT -p TCP --dport 8888 -j DROP
#redirect all of torify's traffic to localhost
sudo iptables -t nat -A OUTPUT -m owner --uid-owner torify -j DNAT
--to-destination 127.0.0.1

Thanks for everybody's help thus far, I think this can be figured out.

Ringo

Renato Callado Borges wrote:
> On Fri, Aug 21, 2009 at 10:29:37PM -0400, Ringo wrote:
>> "This rule will go right at the top of the iptables rules (-I = Insert),
>> and it ACCEPTS every packet that enter through your "lo" (loopback)
>> network interface, which is used for internal communications."
>>
>> Unfortunately, this is a little too permissive. Quite a few programs
>> listen on lo, including CUPS which could give an attacker with access to
>> lo quite a bit of sensitive information. We only want the user "torify"
>> to be able to access 8118 and 9050. If the other users can access other
>> ports, this is fine but the first priority if to block the torify user
>> from accessing anything aside from Tor.
> 
> Ok, I see. But I believe the problem remains that you need listen on lo on some ports, right?
> I suppose you'd prefer a "block everything but allow only these packets" approach. Then what about:
> 
> -I INPUT 1 -i lo -p tcp --dport 8118 -j ACCEPT
> -I INPUT 2 -i lo -p tcp --dport 9050 -j ACCEPT
> 
> This will allow any user to get in through lo on ports 8118 and 9050, which, together with the rules you already have, would allow any user to get a full connection on these ports through lo.
> 
> According to iptables man page,
> "owner
>        This module attempts to match various characteristics of the packet creator, for locally-generated packets.  It is only valid in the OUT-
>        PUT chain, and even this some packets (such as ICMP ping responses) may have no owner, and hence never match."
> 
> So you can't assure that other users won't get through lo, on these ports, using the owner module. Also, I have no idea if tor uses ICMP or other packets that wouldn't match the rules. There might be a caveat here.
> 
> Also, since you want only owner torify to be allowed out thorugh lo on these ports, you should change your rules, because as-is you're allowing all users through lo on ports 9050, 8118 and 8888. I'm assuming you don't need these ports (and 8888) for other users, from the description of your problem. But your rules actually allow pacjets through.
> 
> Change from:
> 
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8118 -m owner --uid-owner torify
>>>> -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 9050 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8118 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8888 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m owner --uid-owner torify -j REJECT
>>>> --reject-with icmp-port-unreachable
> 
> To:
> 
> -A OUTPUT -o lo -p tcp --dport 8118 -m owner --uid-owner torify -j ACCEPT
> -A OUTPUT -o lo -p tcp --dport 9050 -m owner --uid-owner torify -j ACCEPT
> -A OUTPUT -o lo -p tcp -m owner --uid-owner torify -j REJECT --reject-with icmp-port-unreachable
> 
> Is this getting closer?
> 
> []s
> Renato.
> 
>>>> "You're dropping all incoming TCP traffic! This must be switched.
>>>> And you should use conntrack (it replaces state)."
>>>>
>>>> Good point! I gave the following config a test. Here's what --list-rules
>>>> gave me.
>>>>
>>>> -P INPUT ACCEPT
>>>> -P FORWARD ACCEPT
>>>> -P OUTPUT ACCEPT
>>>> -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
>>>> -A INPUT -p tcp -j DROP
>>>> -A INPUT -p udp -j DROP
>>>> -A INPUT -p icmp -j DROP
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8118 -m owner --uid-owner torify
>>>> -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 9050 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8118 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8888 -j ACCEPT
>>>> -A OUTPUT -o lo -p tcp -m owner --uid-owner torify -j REJECT
>>>> --reject-with icmp-port-unreachable
>>>>
>>>> The main user "user" can browse the internet just fine (yay!) and
>>>> "torify" can't connect to anything (yay!), even privoxy on localhost
>>>> (sad). Unfortunately, no user on the computer can reach privoxy. I
>>>> confirmed it was up and running, and that tor was. A wget using it as a
>>>> proxy just says "connecting" and never gets past that. I also tried
>>>> restarting privoxy/tor just to be sure they weren't flaking and that
>>>> didn't seem to be it.
>>>>
>>>> Any ideas?
>>> I know this thread has being going on for some time, but I haven't read it before, too busy. If I'm repeating something already said, or ignoring some constraint not present in this latest message, I apologise.
>>>
>>> AFAIK, you need to be able to create connections from your machine to itself. You can check this need by running "netstat -tc" on a working torrified browsing session. You should see some "localhost" to "localhost" connections.
>>>
>>> Proto Recv-Q Send-Q Local Address           Foreign Address         State      
>>> tcp        0      0 localhost:33435         localhost:8118          ESTABLISHED
>>>
>>> These connections, to my knowledge, are done via the loopback interface. So you need this rule:
>>>
>>> /sbin/iptables -I INPUT 1 -i lo -j ACCEPT
>>>
>>> This rule will go right at the top of the iptables rules (-I = Insert), and it ACCEPTS every packet that enter through your "lo" (loopback) network interface, which is used for internal communications.
>>>>>> Ok so I added this one (which seemed like the only one that would open
>>>>>> things up) and still no luck:
>>>>>> iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
>>>>>>
>>>>>> Here's a export of my current rules:
>>>>>>
>>>>>> # Generated by iptables-save v1.4.1.1 on Thu Aug 20 09:28:22 2009
>>>>>> *filter
>>>>>> :INPUT ACCEPT [9850:7346270]
>>>>>> :FORWARD ACCEPT [0:0]
>>>>>> :OUTPUT ACCEPT [10373:5920044]
>>>>>> -A INPUT -p tcp -j DROP
>>>>>> -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
>>>>>> -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
>>>>> You're dropping all incoming TCP traffic! This must be switched.
>>>>> And you should use conntrack (it replaces state).
>>>>>
>>>>>     -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
>>>>>     -A INPUT -j DROP
>>>>>
>>>>> But I'm not sure if this is necessary at all. You could accept
>>>>> all incoming traffic.
>>>>>
>>>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8118 -m owner --uid-owner torify -j ACCEPT
>>>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 9050 -j ACCEPT
>>>>>> -A OUTPUT -o lo -p tcp -m owner --uid-owner torify -j REJECT --reject-with icmp-port-unreachable
>>>>>> -A OUTPUT -o lo -p tcp -m tcp --dport 8888 -j ACCEPT
>>>>>> COMMIT
>>>>>>
>>>>>> [snip]
>>>>> I haven't tested it so I'm not sure it will work.
> 



More information about the tor-talk mailing list