Jump to: navigation, search

Dev/Control Port Filter Proxy

< Dev(Redirected from Dev/CPFP)

Introduction[edit]

https://github.com/Whonix/control-port-filter-python
https://phabricator.whonix.org/tag/control-port-filter-python

Tor's control port has in context of Whonix, dangerous features. The answer to the Tor control command GETINFO address will be the real external IP of the Tor client. Other dangerous commands include SETCONF, LOADCONF and GETCONF. This can not be limited any other way, since the feature request Option to limit information Tor's control port discloses against Tor has not been implemented. By the way, this Tor control port feature makes also a Bridge Firewall impossible. Therefore before Whonix 6, Whonix-Workstation had no access to Tor's control port. This was because, Whonix-Workstation is not supposed to have an way of finding out its own external IP address.

Before Whonix 6, this also broke Tor Button's New Identity feature, which essentially sends SIGNAL NEWNYM to Tor's control port. While Tor Button's New Identity is still the only feature that was not available when using Tor Browser in Whonix, Tor Button in future will get more and more dependent on Tor's control port.

Tor Browser by default performs its own control port verification. It checks using Tor's control port(!), that the socks port Tor reports, is the same one as Tor Browser is configured to use. If it fails, and it would fail in Whonix 0.5.6, Tor Button would look like disabled and show a failure message. (To see how this would look like, see this screenshot.) (To see how this generates user confusion, see this forum thread.) Since Whonix 6 this check is disabled using environment variable to skip TorButton control port verification (export TOR_SKIP_CONTROLPORTTEST=1) by package anon-ws-disable-stacked-tor. [1]

In future, Tor Button will likely also use something like GETINFO clockskew. Tor Browser developer rejected the idea of not adding the statement require no access to Tor's control port to Tor Browser's design.

Therefore all requirements, Whonix-Workstation having no way of finding its own external IP address, joining Tor Browser's fingerprint for Whonix users, having no access for Whonix-Workstation to Tor's control port with Tor Buttons new requirement to have access to Tor's control port contradicted itself.

Control Port Filter Proxy (cpfpy) has been implemented as a solution. It gives Whonix-Workstation access to a limited selection of Tor's control port commands, using white listing (not blacklisting). For example, it allows SIGNAL NEWNYM to make Tor Buttons New Identity feature available for users who use Tor Browser in Whonix-Workstation.

Therefore when cpfpy gets asked GETINFO net/listeners/socks, it lies, and answers '250-net/listeners/socks="127.0.0.1:9150"'. This makes Tor Button happy and therefore it shows a "Congratulations!" (success) welcome page on its default homepage about:tor and not the failure page, which would confuse users. Since bug TorButton about:tor fails when using additional socks listeners has been fixed by Tor Tor Project, it that lie wouldn't be necessary anymore. We're keeping it, because it is not necessary for Tor Button get a full list of all ports Tor is listening on. If an attacker compromised Whonix-Workstation, hiding that list has an advantage. The attacker can probe what ports are available to that Whonix-Workstation, but if the user added extra ports not available to the compromised Whonix-Workstation (only available to another Whonix-Workstation listening on another IP), at least those remain secret. (This is a bit theoretical, because a compromised Whonix-Workstation can spoof its LAN IP and most likely very few users are using ARP spoofing defenses. Should we add ARP spoofing defenses by default at some point, we at least don't have to worry about this point.)

For eventual further Tor control port access requirements by Tor Button, the configuration file of accepted commands has to be extended. If Tor Button would ever ask for anything which violates Whonix's design (Whonix-Workstation has no way of finding out its own external IP address in particular), such as GETINFO address, for example if Tor Button wanted to ensure, that the user is not using its own external IP address, a new lie would have to be added to the cpfpy script. In case many more lies are required, lies should go into the config file as well, for now, hard coding is sufficient.

whonixcheck asks cpfpy status/bootstrap-phase [2] as well as status/circuit-established [3] in Tor Bootstrap Status Check [4] (usability feature).

cpfpy limits maximum accepted command string length to 128 (configurable) (credits: [5] [6]) for better security.

Advanced users who do not wish to use cpfpy can disable it, see Advanced Security Guide#Disable Control Port Filter Proxy.

TODO: expand - required for onionshare https://www.whonix.org/wiki/Next#onionshare / ricochet

Whonix-Workstation[edit]

Whonix sets appropriate environment variables for control port (9151), control port ip (127.0.0.1) and control port password "password". The latter is not really in use, its just to make Tor Button happy, because it doesn't default to some password. Tor Button sends it, but its ignored by Control Port Filter Proxy.

rinetd[7] socat redirects 127.0.0.1:9151 to Whonix-Gateway IP: 10.152.152.10

  • Whonix 13 port: 9052
  • Whonix 14 port: 9051

This functionality is implemented by the anon-ws-disable-stacked-tor package.

Tor Browser (running in Whonix-Workstation) is configured by default (not changes by Whonix) to connect to Tor control port 127.0.0.1:9151.

Whonix-Gateway[edit]

Control Port Filter proxy listens on 0.0.0.0 port 9052, filters (white list) incoming control port messages and forwards them to the real Tor Control Port listening in 127.0.0.1:9051. Control Port Filter Proxy itself uses cookies authentication to authenticate Tor's control port. The latter is not important, since Whonix-Gateway's only purpose is running Tor, its not a multi user operating system, and if it were compromised, cookie authentication wouldn't be of help anymore either.

Attack Scenarios[edit]

Once Whonix-Workstation has been compromised, the adversary could continuously and/or using a pattern, send white listed commands to Tor. At the moment, only NEWNYM would be of interest. When the adversary is also an ISP level adversary, the adversary might be able to see the pattern being produced. This however is not a big risk, since once Whonix-Workstation is compromised, more powerful attacks are available - An adversary could also use "Morse Code", i.e. limit the victims traffic for a few seconds to zero or close to zero, then push the traffic to its maximum.

More worrying is the extended attack surface.

Imitating real Tor Control Connection[edit]

Should Tor close the connection, cpfpy will also close client connection. (Same for a real Tor control connection.)

Both real Tor control connection and cpfpy close the connection if commands are sent when the client is not yet authenticated. (With the exception of authenticate, authchallenge and protocolinfo so there is parity.)

Should Tor authentication fail, this is logged and cpfpy closes client connection.

Debugging Inspiration[edit]

Whonix 13[edit]

Introduction[edit]

Quickly install files from package to system.

sudo make install

Restart cpfpy after making changes to it.

sudo service control-port-filter-python restart

Watch cpfpy's log on Whonix-Gateway while using it.

tail -f /var/log/control-port-filter-python.log

To get a list of Tor ControlPort commands, that TorButton uses, get into TorButton source code, extract TorButton, then run.

grep -r -i torbutton_send_ctrl_cmd *
grep -r -i sendCommand *

To get a list of Tor ControlPort commands, that TorLauncher uses, get into TorLauncher source code, extract TorLauncher, then run.

grep -r -i getconf

Watch kern.log for eventual iptables log messages, run this on Whonix-Gateway.

tail -f /var/log/kern.log

To see what's being send to cpfpy's port, run this on Whonix-Gateway.

sudo tcpdump -i eth1 -l -s0 -w - tcp dst port 9052 | strings

Connect to cpfpy from Whonix-Workstation to simulate using it.

telnet 127.0.0.1 9051

Command.

authenticate                                                                                                                                                                        

Output.

250 OK

Command.

GETINFO net/listeners/socks

Output.

250-net/listeners/socks="127.0.0.1:9150"

Command.

GETINFO address

Output.

510 Prohibited command "GETINFO address"

Command.

QUIT

cpfpy[edit]

Debugging start command.

sudo service control-port-filter-python start

Debugging stop command.

sudo service control-port-filter-python stop

To find any eventual leftovers, stale processes, try this.

ps aux | grep cpfpd

or

ps aux | grep python

On the gateway, talk to cpfpy directly.

telnet 10.152.152.10 9052

To check if the port is free, if cpfpy really has shut down.

sudo lsof -i :9052
COMMAND   PID       USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
cpfpd 27653 debian-tor    4u  IPv4  73153      0t0  TCP 10.152.152.10:9052 (LISTEN)

Talking to the real Tor Control Port[edit]

On Whonix-Gateway. (test is the example password being used. Feel free to use a different/stronger one.

tor --hash-password test

Will show something like this.

16:1CEAF6E6A08E0CF460AFD71772461C5F56BD9738FA8824B882FCA4A785

Add to /etc/tor/torrc.

HashedControlPassword 16:1CEAF6E6A08E0CF460AFD71772461C5F56BD9738FA8824B882FCA4A785

Reload Tor.

sudo service tor reload

Connect to Tor's ControlPort.

telnet 127.0.0.1 9051

Authenticate.

authenticate "test"

Should reply.

250 OK

Test your commands. For example.

setevents stream

Will do nothing after this, but when you start using Tor (i.e. by running Tor Browser, apt-get or so), it will show something like this (events).

650 STREAM 211 NEW 0 pop.riseup.net:995 SOURCE_ADDR=10.152.152.11:47036 PURPOSE=USER
...

Whonix 14[edit]

TODO: document

TorButton Network Settings[edit]

TorButton -> Open Network Settings...

Is using.

   "GETCONF Socks4Proxy"
   "GETCONF Socks5Proxy"
   "GETCONF HTTPSProxy"
   "GETCONF ReachableAddresses"
   "GETCONF ReachableAddresses"
   "GETCONF UseBridges"
   "GETCONF Bridge"

As the next logical step by the way, they are likely going to add.

   "GETCONF HTTPProxy"

We are setting environment variable export TOR_NO_DISPLAY_NETWORK_SETTINGS=1 to disable the "TorButton" -> "Open Network Settings..." menu item. It is not useful and confusing to have on a workstation, because Tor must be configured on the gateway, which is for security reasons forbidden from the workstation.

Indicator for current Circuit Status and Exit IP[edit]

UI for ExitNode country selection in tor-launcher[edit]

https://trac.torproject.org/projects/tor/ticket/11406

feedback mechanism for clock-skew and other bad problems[edit]

https://trac.torproject.org/projects/tor/ticket/9675

Whonix Forum Discussion[edit]

new Tor ControlPort commands wanted by TBB 4.5 and above

Comparison of Control Port Filters[edit]

roflcoptor by subgraph os[edit]

roflcoptor by subgraph os

  • Many golang dependencies that are not packaged for Debian.
  • Event support.
  • Wildcard support.
  • TODO: expand

surrogate.go by Yawning Angel[edit]

surrogate.go (tor project gitweb) by Yawning Angel

  • golang (build dep, not run dep)
  • AGPL (Achtung!)
  • Part of new/upcoming Sandboxed Tor Browser
  • "Tor control/socks port surrogates." (quoting top comment) Intended to proxy/filter both ControlPort and SOCKSPort of tor process in one bubblewrapped sandbox, while actual Tor Browser runs in another bubblewrapped sandbox.
  • Observed version: 6ff4802
  • So, official TPO Tor Browser variant also has this problem. Oops!

onion-grater by Tails[edit]

onion-grater by Tails [8] (config folder)

  • Written in python3.
  • All dependencies already inside Debian.
  • Wildcard / regex support.
  • Supports rewriting client requests.
  • Supports rewriting Tor replies.
  • Parallel connections support.
  • Can reply to getinfo net/listeners/socks with the lie '250-net/listeners/socks="127.0.0.1:9150"'.
  • Logs to journal.
  • Honors signals sigterm, sigint.
  • Supports subscribing Tor ControlPort events (setevent).

onion-grater by Tails forked by Whonix[edit]

onion-grater (config folder) (additional onion-grater-merger example profiles) (issue tracker)


legacy control-port-filter-python by Whonix[edit]

legacy control-port-filter-python (main script) [Whonix 10 to Whonix 13 (version 1.7-1] (last git commit up to 99e8395fbafcb7789c7d1b5cbf7410ed65192e9a) (issue tracker) [deprecated]

  • A fork of (very early) tor-controlport-filter by Tails. (See above.)
  • Written in python2.7.
  • Configurable by dropping .d-style[9] configuration snippets into /etc/cpfpy.d.
  • Support to answer getinfo net/listeners/socks with the lie '250-net/listeners/socks="127.0.0.1:9150"'.
  • Supports logging.
  • Honors signals sigterm, sigint, keyboard interrupt.
  • Supports parallel connections.
  • Supports wildcards, which is for tools such as onionshare that are using add_onion *.
  • Injects workstation IP into add_onion. For example will transform from / to:
    • add_onion new:best port=80,17600
    • add_onion new:best port=80,10.137.6.41:17600
  • Support subscribing Tor ControlPort events (setevent). (Whonix 14 and above.) [10]
  • Complete systemd unit file.
  • Lintian clean /debian packaging folder.
  • Will be deprecated when Whonix 14 get released.

legacy2 control-port-filter by Whonix[edit]

legacy^2 control-port-filter [up to Whonix 9.x] [deprecated]

  • Supports parallel connections.
  • Written in bash. (github) (archive only)
  • White lists multiple useful Tor ControlPort commands.
  • Configurable using /etc/controlportfilt.d drop-in files.
  • Support to answer getinfo net/listeners/socks with the lie '250-net/listeners/socks="127.0.0.1:9150"'.
  • Supports logging.
  • Honors signals sigterm, sigint.
  • Does not support wildcards.
  • Does not support subscribing Tor ControlPort events (setevent).
  • Complete sysvinit script.
  • Lintian clean /debian packaging folder.
  • Deprecated since the release of Whonix 10.

tor-controlport-filter by Tails[edit]

How to get it running in Whonix 13[edit]

(...or how to upgrade to the work in progress Whonix-14-developers-only.)

Upgrading_Whonix_13_to_Whonix_14


Then tor-controlport-filter by Tails should be ready. On the gateway you should be able to run:

Whonix-Gateway (for Non-Qubes-Whonix)

nc 10.152.152.10 9051

On the workstation you should be able to run:

nc 127.0.0.1 9151

Type "something". Enter. Should reply "510 Command filtered". On the gateway you should see some tor-controlport-filter by Tails debug output.

Debugging[edit]

sudo journalctl -f -u tor-controlport-filter
sudo service tor-controlport-filter restart

See Also[edit]

Footnotes[edit]

  1. https://github.com/Whonix/anon-ws-disable-stacked-tor/blob/master/usr/lib/anon-ws-disable-stacked-tor/torbrowser.sh
  2. Find out what status/bootstrap-phase answers yourself in Whonix-Gateway.
    /usr/lib/anon-shared-helper-scripts/tor_bootstrap_check.py 127.0.0.1 9051 1
    

    Example answer.

    NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"
    
  3. Find out what status/circuit-established answers yourself in Whonix-Gateway.
    /usr/lib/anon-shared-helper-scripts/tor_circuit_established_check.py 127.0.0.1 9051 1
    

    Example answer.

    1
    
  4. https://github.com/Whonix/whonixcheck/blob/master/usr/lib/whonixcheck/check_tor_bootstrap
    whonixcheck --function check_tor_bootstrap
    
    whonixcheck --function check_tor_bootstrap --verbose --debug
    
  5. As done by Tails.
  6. Thanks to HulaHoop for suggesting this.
  7. No longer rinetd since anon-ws-disable-stacked-tor version 2.4-1 (Whonix 13 stable upgrade).
  8. tor-controlport-filter by Tails
  9. Whonix_Configuration_Files#.d_Style_Configuration_Folders
  10. https://phabricator.whonix.org/T448

Random News:

Join us in testing our new AppArmor profiles for improved security! (forum discussion)


Impressum | Datenschutz | Haftungsausschluss

https | (forcing) onion
Share: Twitter | Facebook | Google+

This is a wiki. Want to improve this page? Help is welcome and volunteer contributions are happily considered! See Conditions for Contributions to Whonix, then Edit! IP addresses are scrubbed, but editing over Tor is recommended. Edits are held for moderation.

Whonix (g+) is a licensee of the Open Invention Network. Unless otherwise noted, the content of this page is copyrighted and licensed under the same Libre Software license as Whonix itself. (Why?)