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.
This commit is contained in:
Sunil Mohan Adapa 2016-07-08 23:07:37 +05:30 committed by James Valleroy
parent 70001c841f
commit 038fec97a6
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 77 additions and 31 deletions

View File

@ -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:

View File

@ -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'),

View File

@ -94,7 +94,7 @@
</form>
{% if status.relay_enabled %}
<h3>{% trans "Bridge Relay" %}</h3>
<h3>{% trans "Relay" %}</h3>
<p>
{% blocktrans trimmed %}
If your {{ box_name }} is behind a router or firewall, you should
@ -136,3 +136,21 @@
{% endif %}
{% endblock %}
{% block page_js %}
<script type="text/javascript">
(function($) {
$('#id_tor-relay_enabled').change(function() {
var bridge = $('#id_tor-bridge_relay_enabled');
var disable = ! $('#id_tor-relay_enabled').prop('checked');
bridge.prop('disabled', disable);
if (disable) {
$('#id_tor-bridge_relay_enabled').prop('checked', false);
}
}).change();
})(jQuery);
</script>
{% endblock %}

View File

@ -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'],

View File

@ -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])