From 038fec97a6adbc354ca87363860c5b57d6fd4090 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Fri, 8 Jul 2016 23:07:37 +0530 Subject: [PATCH] tor: Ability to run regular relays - Allow users to run regular relays. In addition to that users will be able to turn them into bridge relays. Like before, by default, relaying is enabled and the relay type bridge relay. - Show obfs3/4 transport ports as needing firewall port forwarding only if bridge relay is enabled. - Remove pluggable transports configuration from configuration when bridge rely is disabled. - Improve description message for relays and bridge relays. --- actions/tor | 59 +++++++++++++++------------ plinth/modules/tor/forms.py | 13 +++++- plinth/modules/tor/templates/tor.html | 20 ++++++++- plinth/modules/tor/utils.py | 9 +++- plinth/modules/tor/views.py | 7 ++++ 5 files changed, 77 insertions(+), 31 deletions(-) diff --git a/actions/tor b/actions/tor index b41f899b7..387ac6c9b 100755 --- a/actions/tor +++ b/actions/tor @@ -55,6 +55,8 @@ def parse_arguments(): help='Configure Tor service') configure.add_argument('--relay', choices=['enable', 'disable'], help='Configure relay') + configure.add_argument('--bridge-relay', choices=['enable', 'disable'], + help='Configure bridge relay') configure.add_argument('--hidden-service', choices=['enable', 'disable'], help='Configure hidden service') configure.add_argument('--apt-transport-tor', @@ -72,17 +74,11 @@ def subcommand_setup(_): 'Run as non-exit bridge relay') aug.set(TOR_CONFIG + '/SocksPort[1]', '[::]:9050') aug.set(TOR_CONFIG + '/SocksPort[2]', '0.0.0.0:9050') - aug.set(TOR_CONFIG + '/ORPort', 'auto') aug.set(TOR_CONFIG + '/ControlPort', '9051') - aug.set(TOR_CONFIG + '/BridgeRelay', '1') + _enable_relay(relay='enable', bridge='enable', restart=False, aug=aug) aug.set(TOR_CONFIG + '/ExitPolicy[1]', 'reject *:*') aug.set(TOR_CONFIG + '/ExitPolicy[2]', 'reject6 *:*') - aug.set(TOR_CONFIG + '/#comment[last() + 1]', 'Enable obfsproxy') - aug.set(TOR_CONFIG + '/ServerTransportPlugin', - 'obfs3,obfs4 exec /usr/bin/obfs4proxy') - aug.set(TOR_CONFIG + '/ExtORPort', 'auto') - aug.set(TOR_CONFIG + '/#comment[last() + 1]', 'Enable transparent proxy') aug.set(TOR_CONFIG + '/VirtualAddrNetworkIPv4', '10.192.0.0/10') aug.set(TOR_CONFIG + '/AutomapHostsOnResolve', '1') @@ -125,11 +121,8 @@ def subcommand_configure(arguments): if arguments.service == 'disable': _disable() - restart = arguments.service == None and arguments.hidden_service == None - if arguments.relay == 'enable': - _enable_relay(restart=restart) - elif arguments.relay == 'disable': - _disable_relay(restart=restart) + restart = arguments.service is None and arguments.hidden_service is None + _enable_relay(arguments.relay, arguments.bridge_relay, restart=restart) restart = arguments.service is None if arguments.hidden_service == 'enable': @@ -150,15 +143,21 @@ def get_status(): """Return dict with Tor status.""" aug = augeas_load() return {'relay_enabled': _is_relay_enabled(aug), + 'bridge_relay_enabled': _is_bridge_relay_enabled(aug), 'ports': _get_ports(), 'hidden_service': _get_hidden_service(aug)} def _is_relay_enabled(aug): - """Return whether bridge relay is enabled.""" + """Return whether a relay is enabled.""" orport = aug.get(TOR_CONFIG + '/ORPort') + return bool(orport) and orport != '0' + + +def _is_bridge_relay_enabled(aug): + """Return whether bridge relay is enabled.""" bridge = aug.get(TOR_CONFIG + '/BridgeRelay') - return orport == 'auto' and bridge == '1' + return bridge == '1' def _get_ports(): @@ -247,23 +246,29 @@ def _disable(): action_utils.service_disable('tor') -def _enable_relay(restart=True): +def _enable_relay(relay=None, bridge=None, restart=True, aug=None): """Enable Tor bridge relay.""" - aug = augeas_load() - aug.set(TOR_CONFIG + '/ORPort', 'auto') - aug.set(TOR_CONFIG + '/BridgeRelay', '1') - aug.save() + if relay is None and bridge is None: + return - if restart: - if is_enabled() and is_running(): - action_utils.service_restart('tor') + if not aug: + aug = augeas_load() + if relay == 'enable': + aug.set(TOR_CONFIG + '/ORPort', 'auto') + elif relay == 'disable': + aug.remove(TOR_CONFIG + '/ORPort') + + if bridge == 'enable': + aug.set(TOR_CONFIG + '/BridgeRelay', '1') + aug.set(TOR_CONFIG + '/ServerTransportPlugin', + 'obfs3,obfs4 exec /usr/bin/obfs4proxy') + aug.set(TOR_CONFIG + '/ExtORPort', 'auto') + elif bridge == 'disable': + aug.remove(TOR_CONFIG + '/BridgeRelay') + aug.remove(TOR_CONFIG + '/ServerTransportPlugin') + aug.remove(TOR_CONFIG + '/ExtORPort') -def _disable_relay(restart=False): - """Disable Tor bridge relay.""" - aug = augeas_load() - aug.remove(TOR_CONFIG + '/ORPort') - aug.set(TOR_CONFIG + '/BridgeRelay', '0') aug.save() if restart: diff --git a/plinth/modules/tor/forms.py b/plinth/modules/tor/forms.py index f58fde633..4750dfdb4 100644 --- a/plinth/modules/tor/forms.py +++ b/plinth/modules/tor/forms.py @@ -32,11 +32,20 @@ class TorForm(forms.Form): # pylint: disable=W0232 label=_('Enable Tor'), required=False) relay_enabled = forms.BooleanField( + label=_('Enable Tor relay'), + required=False, + help_text=format_lazy(_( + 'When enabled, your {box_name} will run a Tor relay and donate ' + 'bandwidth to the Tor network. Do this if you have more than ' + '2 megabits/s of upload and download bandwidth.'), + box_name=_(cfg.box_name))) + bridge_relay_enabled = forms.BooleanField( label=_('Enable Tor bridge relay'), required=False, help_text=format_lazy(_( - 'When enabled, your {box_name} will run a Tor bridge relay with ' - 'obfsproxy, so it can help circumvent censorship.'), + 'When enabled, relay information is published in the Tor bridge ' + 'database instead of public Tor relay database making it harder ' + 'to censor this node. This helps others circumvent censorship.'), box_name=_(cfg.box_name))) hs_enabled = forms.BooleanField( label=_('Enable Tor Hidden Service'), diff --git a/plinth/modules/tor/templates/tor.html b/plinth/modules/tor/templates/tor.html index f07de42af..6ccc35d0a 100644 --- a/plinth/modules/tor/templates/tor.html +++ b/plinth/modules/tor/templates/tor.html @@ -94,7 +94,7 @@ {% if status.relay_enabled %} -

{% trans "Bridge Relay" %}

+

{% trans "Relay" %}

{% blocktrans trimmed %} If your {{ box_name }} is behind a router or firewall, you should @@ -136,3 +136,21 @@ {% endif %} {% endblock %} + + +{% block page_js %} + + + +{% endblock %} diff --git a/plinth/modules/tor/utils.py b/plinth/modules/tor/utils.py index 810376a5f..c21540272 100644 --- a/plinth/modules/tor/utils.py +++ b/plinth/modules/tor/utils.py @@ -56,10 +56,17 @@ def get_status(): if str(service_type[2]) in hs_virtports: hs_services.append(service_type[0]) + # Filter out obfs3/4 ports when bridge relay is disabled + ports = {service_type: port + for service_type, port in status['ports'].items() + if service_type not in ['obfs4', 'obfs3'] or + status['bridge_relay_enabled']} + return {'enabled': is_enabled(), 'is_running': is_running(), 'relay_enabled': status['relay_enabled'], - 'ports': status['ports'], + 'bridge_relay_enabled': status['bridge_relay_enabled'], + 'ports': ports, 'hs_enabled': hs_info['enabled'], 'hs_status': hs_info['status'], 'hs_hostname': hs_info['hostname'], diff --git a/plinth/modules/tor/views.py b/plinth/modules/tor/views.py index bb5ede0c6..e36ee33fe 100644 --- a/plinth/modules/tor/views.py +++ b/plinth/modules/tor/views.py @@ -84,6 +84,13 @@ def __apply_changes(request, old_status, new_status): arg_value = 'enable' if new_status['relay_enabled'] else 'disable' arguments.extend(['--relay', arg_value]) + if old_status['bridge_relay_enabled'] != \ + new_status['bridge_relay_enabled']: + arg_value = 'enable' + if not new_status['bridge_relay_enabled']: + arg_value = 'disable' + arguments.extend(['--bridge-relay', arg_value]) + if old_status['hs_enabled'] != new_status['hs_enabled']: arg_value = 'enable' if new_status['hs_enabled'] else 'disable' arguments.extend(['--hidden-service', arg_value])