anonym:
> Patrick Schleizer:
>>>>>> - https://phabricator.whonix.org/T564
>>>>
>>>> Protecting cpfpy from DDOS from client applications. Not sure that
>>>> matters for Tails?
>>>
>>> We do not do much specific here. What kind of DoS are you talking about
>>> here? Eating up all RAM or crashing the filter via oom kill? Preventing
>>> the filter from serving other clients? We admittedly do not do much here
>>> except that each client is dealt with in a separate thread, and that
>>> client requests are limited to 1024 bytes.
>>
>> Yes, I meant crashing the filter or making the whole computer unusable
>> by flooding cpfpy with too much requests.
>
> So the scenario is something like this: an attacker compromises the
> workstation, and then want to crash the filter running on the gateway
> (or even crash the whole gateway)?
Yes.
> If so, IMHO DoS is the least of our
> worries since all gateway activity (= user activity) now is compromised.
> I mean, the attacker can DoS the workstation by killing all user
> processes or whatever.
>
> ... but now I get that you may run several workstations (in Qubes, I
> guess), and then this makes sense.
Yes.
> Quick solution that a determined adversary probably easily can work
> around: in the gatway's firewall rules, rate limit the traffic to the
> control filter per workstation.
I will consider this, useful, but guess it's not a priority as you
pointed out.
> Slightly more involved, slightly more efficient solution: we could add
> an option to the filter making the server forking instead of threading,
> and then adjust OOM scores and NICEness for these subprocesses so they
> are low prio for the CPU, and prone to get OOM killed if memory gets
> low. The server process itself will be configured in the opposite way
> (you can add the options via a systemd override).
>
> Any way, DoS protection is pretty hard... and I doubt it's much of a
> problem on *local* systems. Rather DoS gives away that a workstation has
> been compromised, instead of it remaining in a stealthy surveillance
> mode, which I think I must consider worse (even when limited to a single
> workstation == application).
>>> I could even imagine yet another rule-type for solving these types of
>>> issues:
>>>
>>> GETINFO:
>>> - pattern: 'net/listeners/socks'
>>> respond: '250-net/listeners/socks="127.0.0.1:9150"'
>>
>> Seems great!
>
> In the end, this was generalised into:
>
> GETINFO:
> - pattern: 'net/listeners/socks'
> response:
> - pattern: '250-net/listeners/socks=".*"'
> - replacement: '250-net/listeners/socks="127.0.0.1:9150"'
That crashes the filter for me.
config:
---
- match-exe-paths:
- '*'
match-users:
- '*'
match-hosts:
- '*'
commands:
SIGNAL:
- 'NEWNYM'
GETINFO:
- 'circuit-established'
GETINFO:
- pattern: 'net/listeners/socks'
response:
- pattern: '250-net/listeners/socks=".*"'
- replacement: '250-net/listeners/socks="127.0.0.1:9150"'
run:
user@host:~$ ./tor-controlport-filter --listen-address 0.0.0.0 --debug
Tor control port filter started, listening on 0.0.0.0:9051
10.137.11.80:49996 (filter: tor-browser) connected: loaded filter:
tor-browser
Final rules:
commands:
GETCONF:
- {pattern: ()}
GETINFO:
- pattern: net/listeners/socks
response:
- {pattern: 250-net/listeners/socks=".*"}
- {replacement: '250-net/listeners/socks="127.0.0.1:9150"'}
SIGNAL:
- {pattern: NEWNYM}
events: {}
restrict-stream-events: false
10.137.11.80:49996 (filter: tor-browser): -> GETINFO net/listeners/socks
10.137.11.80:49996 (filter: tor-browser) disconnected: client quit
----------------------------------------
Exception happened during processing of request from ('10.137.11.80', 49996)
Traceback (most recent call last):
File "/usr/lib/python3.4/socketserver.py", line 613, in
process_request_thread
self.finish_request(request, client_address)
File "/usr/lib/python3.4/socketserver.py", line 344, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.4/socketserver.py", line 669, in __init__
self.handle()
File "./tor-controlport-filter", line 550, in handle
restrict_stream_events
File "./tor-controlport-filter", line 466, in handle_controlport_session
response_rewriter=response_rewriter)
File "./tor-controlport-filter", line 302, in proxy_line
new_response = response_rewriter(response)
File "./tor-controlport-filter", line 447, in _response_rewriter
return rewrite_matched_lines(rule['response'], lines)
File "./tor-controlport-filter", line 331, in rewrite_matched_lines
for line in split_lines]) + "\r\n"
File "./tor-controlport-filter", line 331, in <listcomp>
for line in split_lines]) + "\r\n"
File "./tor-controlport-filter", line 324, in rewrite_matched_line
return rewrite_line(replacers, line)
File "./tor-controlport-filter", line 319, in rewrite_line
return r['replacement'].format(*match.groups()) + terminator
KeyError: 'replacement'
----------------------------------------
Cheers,
Patrick