Skip to content

Commit

Permalink
support multiple IP addresses for use with OutboundBindAddressExit
Browse files Browse the repository at this point in the history
before this commit we used a single IP address for all tor instances
on a server for exiting if tor_dedicatedExitIP was enabled, with this
commit multiple exit IP addresses are used. By distributing the
traffic across multiple source IP addresses this should help reduce
the negative effects of bad traffic spoiling the source IP for many
tor users.

There are two cases to consider:
- user runs one tor instance per IP (tor_ports has one entry):
"loop_idx" can be directly used as an index to the tor_available_public_ipv4/6 arrays
- user runs two tor instances per IP (tor_ports has two entries):
in this case we need to mangle "loop_idx" before we used it as an index
to the IP address arrays

This change includes also the kitchen test suites for this feature:
t-exit-6publicIPs-dedicatedExitIP-2instPerIP
t-exit-6publicIPs-dedicatedExitIP-singleInstPerIP
  • Loading branch information
nusenu committed Apr 24, 2018
1 parent ec7ba7f commit e79db1f
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 17 deletions.
22 changes: 22 additions & 0 deletions .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,25 @@ suites:
- ["private_network", {ip: "198.51.100.10"}]
provisioner:
playbook: "test/integration/default/2publicIPs-exit-node.yml"
- name: t-exit-6publicIPs-dedicatedExitIP-2instPerIP
driver:
network:
- ["private_network", {ip: "192.0.2.10"}]
- ["private_network", {ip: "198.51.100.10"}]
- ["private_network", {ip: "198.51.100.11"}]
- ["private_network", {ip: "198.51.100.12"}]
- ["private_network", {ip: "198.51.100.13"}]
- ["private_network", {ip: "198.51.100.14"}]
provisioner:
playbook: "test/integration/default/6publicIPs-dedicatedExitIP-2instPerIP-exit-node.yml"
- name: t-exit-6publicIPs-dedicatedExitIP-singleInstPerIP
driver:
network:
- ["private_network", {ip: "192.0.2.10"}]
- ["private_network", {ip: "198.51.100.10"}]
- ["private_network", {ip: "198.51.100.11"}]
- ["private_network", {ip: "198.51.100.12"}]
- ["private_network", {ip: "198.51.100.13"}]
- ["private_network", {ip: "198.51.100.14"}]
provisioner:
playbook: "test/integration/default/6publicIPs-dedicatedExitIP-singleInstPerIP-exit-node.yml"
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,14 @@ All variables mentioned here are optional.
- default: True (unlike tor's default)

* `tor_dedicatedExitIP` boolean
- this feature **requires** tor version >= v0.3.0.3-alpha
- only relevant for exit relays
- automatically configures the [OutboundBindAddressExit](https://www.torproject.org/docs/tor-manual.html.en#OutboundBindAddressExit) tor feature (does not require you to manually specify the IP address to use)
- we will use the public IPv4/IPv6 address with the highest numerical value available on the system as the `OutboundBindAddressExit`
- on exit relays only: use a distinct source IP address for traffic leaving the tor network (exit traffic)
- this means tor will establish outbound exit connections on a separate IP(v4/v6) address (different from the IP announced in the consensus)
- automatically configures the [OutboundBindAddressExit](https://www.torproject.org/docs/tor-manual.html.en#OutboundBindAddressExit) tor feature (does not require you to manually specify the IP address to use)
- we will use the public IPv4/IPv6 address(es) available directly after the IP addresses we use for tor ORPorts for `OutboundBindAddressExit`
- to make use of this feature you need more public IPv4 or IPv6 addresses than `tor_maxPublicIPs`
- if this condition is not met we will abort
- all instances on a host will use the same `OutboundBindAddressExit` address
- manually specifying the IP address used by `OutboundBindAddressExit` is not supported
- this feature **requires** tor version >= v0.3.0.3-alpha (on the target system)
- default: False

* `tor_enableControlSocket`
Expand Down
2 changes: 2 additions & 0 deletions tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@
- "{{ tor_ips }}"
- "{{ tor_ports }}"
register: tor_instances_tmp
loop_control:
index_var: loop_idx
notify:
- Ensure Tor instances are reloaded if its torrc changed (FreeBSD)
- Ensure Tor instances are reloaded if its torrc changed (Linux)
Expand Down
6 changes: 3 additions & 3 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
tags:
- always

- name: Ensure preconditions for tor_dedicatedExitIP are met (number of public IPv4 or IPv6 addresses must be bigger than tor_maxPublicIPs)
- name: Ensure preconditions for tor_dedicatedExitIP are met (enough public IP addresses on the system)
assert:
that:
- "tor_available_public_ipv4s|length > tor_maxPublicIPs or tor_available_public_ipv6s|length > tor_maxPublicIPs"
- "tor_available_public_ipv4s|length >= tor_maxPublicIPs*2 or tor_available_public_ipv6s|length >= tor_maxPublicIPs*2"
- "tor_ExitRelay == True"
- "tor_IPv6Exit == True"
- "tor_IPv6 == True"
msg: "You have to few public IPv4 or IPv6 addresses for the tor_dedicatedExitIP feature (or you did not enable exiting)"
msg: "You have to few public IPv4 and IPv6 addresses for the tor_dedicatedExitIP feature (or you did not enable exiting)"
when: tor_dedicatedExitIP == True
tags:
- always
Expand Down
26 changes: 17 additions & 9 deletions templates/torrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@ ORPort [{{item.0.ipv6}}]:{{item.1.orport}}
OutboundBindAddress {{item.0.ipv6}}
{% endif %}

{% if tor_dedicatedExitIP == True and tor_ExitRelay == True %}
{% if tor_available_public_ipv4s|length > tor_maxPublicIPs %}
OutboundBindAddressExit {{ tor_available_public_ipv4s[-1] }}
{% endif %}
{% if tor_available_public_ipv6s|length > tor_maxPublicIPs and tor_IPv6 == True and tor_IPv6Exit == True %}
OutboundBindAddressExit {{ tor_available_public_ipv6s[-1] }}
{% endif %}
{% endif %}

{% if item.1.dirport != 0 %}
DirPort {{ item.0.ipv4 }}:{{ item.1.dirport }}
{% endif %}
Expand Down Expand Up @@ -72,6 +63,23 @@ IPv6Exit 1
DirPortFrontPage {{ tor_ConfDir }}/tor-exit-notice.html
{% endif %}

{% if tor_dedicatedExitIP == True and tor_ExitRelay == True %}
{% if tor_available_public_ipv4s|length >= tor_maxPublicIPs*2 %}
{% if tor_ports|length == 2 %}
OutboundBindAddressExit {{ tor_available_public_ipv4s[(loop_idx/2)|round(0,'floor')|int + tor_maxPublicIPs]}}
{% elif tor_ports|length == 1 %}
OutboundBindAddressExit {{ tor_available_public_ipv4s[loop_idx + tor_maxPublicIPs]}}
{% endif %}
{% endif %}
{% if tor_available_public_ipv6s|length >= tor_maxPublicIPs*2 and tor_IPv6 == True and tor_IPv6Exit == True %}
{% if tor_ports|length == 2 %}
OutboundBindAddressExit {{ tor_available_public_ipv6s[(loop_idx/2)|round(0,'floor')|int + tor_maxPublicIPs]}}
{% elif tor_ports|length == 1 %}
OutboundBindAddressExit{{ tor_available_public_ipv6s[loop_idx + tor_maxPublicIPs]}}

This comment has been minimized.

Copy link
@nusenu

nusenu Jul 1, 2018

Author Owner

this bug (missing space after OutboundBindAddressExit) was avoidable if we had kitchen IPv6 test coverage #158

{% endif %}
{% endif %}
{% endif %}

{% for entry in tor_ExitPolicy %}
ExitPolicy {{entry}}
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- hosts: all
vars_files:
- vars/dry-run-vars.yml
vars:
- tor_maxPublicIPs: 3
- tor_dedicatedExitIP: True
- tor_ExitRelay: True
roles:
- ansible-relayor
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- hosts: all
vars_files:
- vars/dry-run-vars.yml
vars:
- tor_maxPublicIPs: 3
- tor_dedicatedExitIP: True
- tor_ExitRelay: True
- tor_ports:
- orport: 9000
dirport: 9001
roles:
- ansible-relayor

0 comments on commit e79db1f

Please sign in to comment.