This extends the functionality of the Tor CGI in order to be able to select multiple countries for possible Exit relays, which is - in terms of anonymity - less worse than limiting all Tor circuits to a single country.
For example, a user might want to avoid Exit relays in more than one country, and permit Tor to use Exit relays elesewhere, and vice versa.
Signed-off-by: Peter Müller peter.mueller@ipfire.org --- html/cgi-bin/tor.cgi | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/html/cgi-bin/tor.cgi b/html/cgi-bin/tor.cgi index 7447bd791..3db4bc22c 100644 --- a/html/cgi-bin/tor.cgi +++ b/html/cgi-bin/tor.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2013-2019 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2020 IPFire Team info@ipfire.org # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -319,9 +319,16 @@ END </tr> <tr> <td width='50%' colspan='2'> - <select name='TOR_EXIT_COUNTRY'> + <select name='TOR_EXIT_COUNTRY' multiple='multiple'> <option value=''>- $Lang::tr{'tor exit country any'} -</option> END + + # Convert Exit/Guard country strings into lists to make comparison easier + my @exit_countries; + if ($settings{'TOR_EXIT_COUNTRY'} ne '') { + @exit_countries = split(/|/, $settings{'TOR_EXIT_COUNTRY'}); + } + my @country_codes = &Location::database_countries($db_handle); foreach my $country_code (@country_codes) { # Convert country code into upper case format. @@ -332,8 +339,8 @@ END
print "<option value='$country_code'";
- if ($settings{'TOR_EXIT_COUNTRY'} eq $country_code) { - print " selected"; + if ($settings{'TOR_EXIT_COUNTRY'} ne '') { + print " selected" if grep /$country_code/, @exit_countries; }
print ">$country_name ($country_code)</option>\n"; @@ -678,8 +685,17 @@ sub BuildConfiguration() {
if ($settings{'TOR_EXIT_COUNTRY'} ne '') { $strict_nodes = 1; + my $countrylist; + + for my $singlecountry (split(/|/, $settings{'TOR_EXIT_COUNTRY'})) { + if ($countrylist eq '') { + $countrylist = "{" . lc $singlecountry . "}"; + } else { + $countrylist = $countrylist . "," . "{" . lc $singlecountry . "}"; + } + }
- print FILE "ExitNodes {$settings{'TOR_EXIT_COUNTRY'}}\n"; + print FILE "ExitNodes $countrylist\n"; }
if ($settings{'TOR_USE_EXIT_NODES'} ne '') {
In order to make deanonymisation harder, especially high-risk Tor users might want to use certain Guard relays only (for example operated by people they trust), enforce Tor to use Guard relays in certain countries only (for example countries with very strict data protection laws or poor diplomatic relations), or avoid Guard relays in certain countries entirely.
Since Tor sticks to sampled Guards for a long time (usually within the range of months), restricting those is believed to cause less harm to a users' anonymity than restricting Exit relays, since their diversity of a generic Tor user is significantly higher.
This patch extends the Tor CGI for restricting Guard nodes to certain countries or relays matching certain fingerprints.
Signed-off-by: Peter Müller peter.mueller@ipfire.org --- html/cgi-bin/tor.cgi | 93 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-)
diff --git a/html/cgi-bin/tor.cgi b/html/cgi-bin/tor.cgi index 3db4bc22c..74fa36247 100644 --- a/html/cgi-bin/tor.cgi +++ b/html/cgi-bin/tor.cgi @@ -99,6 +99,8 @@ $settings{'TOR_ENABLED'} = 'off'; $settings{'TOR_SOCKS_PORT'} = 9050; $settings{'TOR_EXIT_COUNTRY'} = ''; $settings{'TOR_USE_EXIT_NODES'} = ''; +$settings{'TOR_GUARD_COUNTRY'} = ''; +$settings{'TOR_USE_GUARD_NODES'} = ''; $settings{'TOR_ALLOWED_SUBNETS'} = "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}"; if (&Header::blue_used()) { $settings{'TOR_ALLOWED_SUBNETS'} .= ",$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}"; @@ -181,6 +183,15 @@ if ($settings{'ACTION'} eq $Lang::tr{'save'}) { } }
+ @temp = split(/[\n,]/,$settings{'TOR_USE_GUARD_NODES'}); + $settings{'TOR_USE_GUARD_NODES'} = ""; + foreach (@temp) { + s/^\s+//g; s/\s+$//g; + if ($_) { + $settings{'TOR_USE_GUARD_NODES'} .= $_.","; + } + } + # Burst bandwidth must be less or equal to bandwidth rate. if ($settings{'TOR_RELAY_BANDWIDTH_RATE'} == 0) { $settings{'TOR_RELAY_BANDWIDTH_BURST'} = 0; @@ -284,6 +295,9 @@ END @temp = split(",", $settings{'TOR_USE_EXIT_NODES'}); $settings{'TOR_USE_EXIT_NODES'} = join("\n", @temp);
+ @temp = split(",", $settings{'TOR_USE_GUARD_NODES'}); + $settings{'TOR_USE_GUARD_NODES'} = join("\n", @temp); + print <<END; <br> <br> @@ -306,8 +320,57 @@ END </tr> </table>
- <br> - <br> + <br /> + <br /> + + <table width='95%'> + <tr> + <td colspan='4' class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'tor guard nodes'}</b></td> + </tr> + <tr> + <td colspan='2' class='base' width='55%'></td> + <td colspan='2' class='base' width='45%'>$Lang::tr{'tor use guard nodes'}:</td> + </tr> + <tr> + <td width='50%' colspan='2'> + <select name='TOR_GUARD_COUNTRY' multiple='multiple'> + <option value=''>- $Lang::tr{'tor guard country any'} -</option> +END + + # Convert Guard country strings into lists to make comparison easier + my @guard_countries; + if ($settings{'TOR_GUARD_COUNTRY'} ne '') { + @guard_countries = split(/|/, $settings{'TOR_GUARD_COUNTRY'}); + } + + my @country_codes = &Location::database_countries($db_handle); + foreach my $country_code (@country_codes) { + # Convert country code into upper case format. + $country_code = uc($country_code); + + # Get country name. + my $country_name = &Location::Functions::get_full_country_name($country_code); + + print "<option value='$country_code'"; + + if ($settings{'TOR_GUARD_COUNTRY'} ne '') { + print " selected" if grep /$country_code/, @guard_countries; + } + + print ">$country_name ($country_code)</option>\n"; + } + + print <<END; + </select> + </td> + <td width='50%' colspan='2'> + <textarea name='TOR_USE_GUARD_NODES' cols='32' rows='3' wrap='off'>$settings{'TOR_USE_GUARD_NODES'}</textarea> + </td> + </tr> + </table> + + <br /> + <br />
<table width='95%'> <tr> @@ -323,7 +386,7 @@ END <option value=''>- $Lang::tr{'tor exit country any'} -</option> END
- # Convert Exit/Guard country strings into lists to make comparison easier + # Convert Exit country strings into lists to make comparison easier my @exit_countries; if ($settings{'TOR_EXIT_COUNTRY'} ne '') { @exit_countries = split(/|/, $settings{'TOR_EXIT_COUNTRY'}); @@ -683,6 +746,30 @@ sub BuildConfiguration() { } print FILE "SocksPolicy reject *\n" if (@subnets);
+ if ($settings{'TOR_GUARD_COUNTRY'} ne '') { + $strict_nodes = 1; + my $countrylist; + + for my $singlecountry (split(/|/, $settings{'TOR_GUARD_COUNTRY'})) { + if ($countrylist eq '') { + $countrylist = "{" . lc $singlecountry . "}"; + } else { + $countrylist = $countrylist . "," . "{" . lc $singlecountry . "}"; + } + } + + print FILE "EntryNodes $countrylist\n"; + } + + if ($settings{'TOR_USE_GUARD_NODES'} ne '') { + $strict_nodes = 1; + + my @nodes = split(",", $settings{'TOR_USE_GUARD_NODES'}); + foreach (@nodes) { + print FILE "EntryNode $_\n"; + } + } + if ($settings{'TOR_EXIT_COUNTRY'} ne '') { $strict_nodes = 1; my $countrylist;
Signed-off-by: Peter Müller peter.mueller@ipfire.org --- langs/de/cgi-bin/de.pl | 6 +++++- langs/en/cgi-bin/en.pl | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 6ad0e02c5..6988aa0ba 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -2406,6 +2406,9 @@ 'tor exit country' => 'Exit-Land', 'tor exit country any' => 'Beliebig', 'tor exit nodes' => 'Exitknoten', +'tor guard country' => 'Guard-Land', +'tor guard country any' => 'Beliebig', +'tor guard nodes' => 'Guardknoten', 'tor relay address' => 'Relais-Adresse', 'tor relay configuration' => 'Tor-Relais-Konfiguration', 'tor relay enabled' => 'Tor-Relais einschalten', @@ -2424,7 +2427,8 @@ 'tor traffic limit hard' => 'Das Übertragungslimit wurde erreicht.', 'tor traffic limit soft' => 'Das Übertragungslimit wurde fast erreicht. Es werden keine neuen Verbindungen akzeptiert.', 'tor traffic read written' => 'Gesamter Traffic (empfangen/gesendet)', -'tor use exit nodes' => 'Nur diese Exitknoten benutzen (einer pro Zeile)', +'tor use exit nodes' => 'Nur diese Exitknoten benutzen (ein Fingerabdruck pro Zeile)', +'tor use guard nodes' => 'Nur diese Guardknoten benutzen (ein Fingerabdruck pro Zeile)', 'total connection time' => 'Gesammte Verbindungszeit', 'total hits for log section' => 'Gesamte Treffer für Protokollsektion', 'traffic back' => 'Zurück', diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index d00de3d03..275f78207 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -2446,6 +2446,9 @@ 'tor exit country' => 'Exit country', 'tor exit country any' => 'Any country', 'tor exit nodes' => 'Exit Nodes', +'tor guard country' => 'Guard country', +'tor guard country any' => 'Any country', +'tor guard nodes' => 'Guard Nodes', 'tor relay address' => 'Relay address', 'tor relay configuration' => 'Tor Relay Configuration', 'tor relay enabled' => 'Enable Tor Relay', @@ -2464,7 +2467,8 @@ 'tor traffic limit hard' => 'Traffic limit has been reached.', 'tor traffic limit soft' => 'Traffic limit almost reached. Not accepting any new connections.', 'tor traffic read written' => 'Total traffic (read/written)', -'tor use exit nodes' => 'Use only these exit nodes (one per line)', +'tor use exit nodes' => 'Use only these exit nodes (one fingerprint per line)', +'tor use guard nodes' => 'Use only these guard nodes (one fingerprint per line)', 'total connection time' => 'Total Connection Time', 'total hits for log section' => 'Total hits for log section', 'traffic back' => 'Back',
Signed-off-by: Peter Müller peter.mueller@ipfire.org --- lfs/tor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lfs/tor b/lfs/tor index 956458407..5610c17d1 100644 --- a/lfs/tor +++ b/lfs/tor @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = tor -PAK_VER = 53 +PAK_VER = 54
DEPS = libseccomp
Hello,
Great idea to extend the Tor add-on.
I believe we could have a brief blog article about this, too. Please do not forget to update the Wiki.
Before I merge this, I would like to have some feedback from someone who has tested this. I would like to have more people touching a patch before it is actually being merged, so that we can iron out problems earlier.
There must be some Tor users here :) Please test :)
-Michael
On 4 Nov 2020, at 21:28, Peter Müller peter.mueller@ipfire.org wrote:
This extends the functionality of the Tor CGI in order to be able to select multiple countries for possible Exit relays, which is - in terms of anonymity - less worse than limiting all Tor circuits to a single country.
For example, a user might want to avoid Exit relays in more than one country, and permit Tor to use Exit relays elesewhere, and vice versa.
Signed-off-by: Peter Müller peter.mueller@ipfire.org
html/cgi-bin/tor.cgi | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/html/cgi-bin/tor.cgi b/html/cgi-bin/tor.cgi index 7447bd791..3db4bc22c 100644 --- a/html/cgi-bin/tor.cgi +++ b/html/cgi-bin/tor.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2013-2019 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2020 IPFire Team info@ipfire.org # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -319,9 +319,16 @@ END </tr> <tr> <td width='50%' colspan='2'>
<select name='TOR_EXIT_COUNTRY'>
<select name='TOR_EXIT_COUNTRY' multiple='multiple'> <option value=''>- $Lang::tr{'tor exit country any'} -</option>
END
# Convert Exit/Guard country strings into lists to make comparison easier
my @exit_countries;
if ($settings{'TOR_EXIT_COUNTRY'} ne '') {
@exit_countries = split(/\|/, $settings{'TOR_EXIT_COUNTRY'});
}
- my @country_codes = &Location::database_countries($db_handle); foreach my $country_code (@country_codes) { # Convert country code into upper case format.
@@ -332,8 +339,8 @@ END
print "<option value='$country_code'";
if ($settings{'TOR_EXIT_COUNTRY'} eq $country_code) {
print " selected";
if ($settings{'TOR_EXIT_COUNTRY'} ne '') {
print " selected" if grep /$country_code/, @exit_countries; } print ">$country_name ($country_code)</option>\n";
@@ -678,8 +685,17 @@ sub BuildConfiguration() {
if ($settings{'TOR_EXIT_COUNTRY'} ne '') { $strict_nodes = 1;
my $countrylist;
for my $singlecountry (split(/\|/, $settings{'TOR_EXIT_COUNTRY'})) {
if ($countrylist eq '') {
$countrylist = "{" . lc $singlecountry . "}";
} else {
$countrylist = $countrylist . "," . "{" . lc $singlecountry . "}";
}
}
print FILE "ExitNodes {$settings{'TOR_EXIT_COUNTRY'}}\n";
print FILE "ExitNodes $countrylist\n";
}
if ($settings{'TOR_USE_EXIT_NODES'} ne '') {
-- 2.26.2