creatorrc.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. from guard_country_resolver import guards_close_to_home, FOUR_EYES_I
  2. def download_descriptors():
  3. from stem.descriptor.remote import DescriptorDownloader
  4. print( "Fetching server descriptors..." )
  5. return DescriptorDownloader().get_server_descriptors().run()
  6. def questionable_relays(relays=None):
  7. # Questionable relays are those that:
  8. # - Don't run a recent version of Tor.
  9. # - Run on win. xp.
  10. if relays == None:
  11. relays = download_descriptors()
  12. old = [ r.fingerprint for r in relays if r.tor_version and r.tor_version.micro < 4 and r.tor_version.minor < 3 ]
  13. winxp = [ r.fingerprint for r in relays if r.operating_system and 'Windows XP' in r.operating_system ]
  14. return set(old + winxp)
  15. def sector():
  16. # This option is designed for security.
  17. # Use nearby guards and try to avoid certain territories.
  18. guards, client_country = guards_close_to_home()
  19. questionables = questionable_relays()
  20. torrc = "\n\n# Strictly exclude all circuits that do not match our preferences.\n"
  21. torrc += "# This WILL prevent connectivity to some hidden services.\n"
  22. torrc += "# Turning off StrictNodes wouldn't be terrible,\n"
  23. torrc += "# mostly used when connecting to hidden services\n"
  24. torrc += "# If you prefer not to be strict, change following line to 'StrictNodes 0'\n"
  25. torrc += "StrictNodes 1\n\n"
  26. torrc += "# Exclude 4 eyes countries + Israel.\n"
  27. torrc += "# Also exclude questionable relays.\n"
  28. torrc += "ExcludeNodes BadExit"
  29. for country in set(FOUR_EYES_I) - set(guards):
  30. torrc += ", {" + country + "}"
  31. for fp in questionables:
  32. torrc += ", " + fp
  33. torrc += "\n\n# Only use entry nodes from your region.\n"
  34. torrc += "# Your own region can already see you connecting.\n"
  35. torrc += "# No reason for a Rio client to connect to a Moskow guard.\n"
  36. torrc += "EntryNodes {" + guards.pop() + "}"
  37. for country in guards:
  38. torrc += ", {" + country + "}"
  39. if client_country in FOUR_EYES_I:
  40. exit_exclude = set(FOUR_EYES_I).intersection(set(guards))
  41. torrc += "\n\n# Your country is specifically excluded for exits, but guards are still allowed.\n"
  42. torrc += "# Other five eyes and israel are already excluded.\n"
  43. torrc += "ExcludeExitNodes {" + exit_exclude.pop() + "}"
  44. for country in exit_exclude:
  45. torrc += ", {" + country + "}"
  46. torrc += "\n\n# Avoid disk writes, are there any drawbacks to this?\n"
  47. torrc += "AvoidDiskWrites 1\n\n"
  48. return torrc
  49. def evator():
  50. # This option is designed to avoid captcha's
  51. relays = download_descriptors()
  52. # Select all exits:
  53. relays = [ relay for relay in relays if relay.exit_policy and relay.exit_policy.is_exiting_allowed() ]
  54. # Define speed limits in bytes per second.
  55. # This corresponds to a 100 - 300 kB/s range.
  56. # The minimum is just set to exclude nodes that are horribly slow.
  57. kb = 1000
  58. min_speed = 100 * kb
  59. max_speed = 300 * kb
  60. # Select relays with the appropriate speed range
  61. relays = [ r for r in relays if r.average_bandwidth > min_speed and r.average_bandwidth < max_speed ]
  62. # Finally retrieve fingerprints of selected relays.
  63. fingerprints = [ relay.fingerprint for relay in relays ]
  64. # Create the torrc for this configuration
  65. torrc = "\n\n# Select these nodes as exits\n"
  66. torrc += "ExitNodes " + fingerprints.pop()
  67. for exit in fingerprints:
  68. torrc += ", " + exit
  69. torrc += "\n\n"
  70. return torrc
  71. def speetor():
  72. # This one should select only relays in one country, e.g. US.
  73. # Torrc to have high throughput.
  74. # This is something that the project advises against.
  75. # It is advised against because high throughput is bad for anonymity and also hurts the network.
  76. relays = download_descriptors()
  77. # The sort that we use in this function, returns only the fingerprints
  78. sort = lambda x : [ y[1] for y in sorted(x, key = lambda x : x[0], reverse=True) ]
  79. # Fortran style, where are the exits?
  80. exit_or_not = [r.exit_policy.is_exiting_allowed() for r in relays]
  81. # Select 1000 fastest non-exits as guards
  82. guards = sort([ (r[0].average_bandwidth, r[0].fingerprint) for r in zip(relays, exit_or_not) if not r[1]] )[:1000]
  83. # Select 1000 fastest exits as exits
  84. exits = sort([ (r[0].average_bandwidth, r[0].fingerprint) for r in zip(relays, exit_or_not) if r[1]] )[:1000]
  85. # Select 4000 slowest relays to exclode from everywhere in the circuit. (selects middle relay)
  86. excludes = sort([ (r.average_bandwidth, r.fingerprint) for r in relays ])[-4000:]
  87. assert len(exits) == 1000, "Error selecting exits"
  88. assert len(guards) == 1000, "Error selecting guards"
  89. assert len(excludes) == 4000, "Error selecting relays to exclude"
  90. torrc = "\n\n# Only use the 1000 fastest guards\n"
  91. torrc += "EntryNodes " + guards.pop()
  92. for guard in guards:
  93. torrc += ", " + guard
  94. torrc += "\n\n# Exclude the 4000 slowest relays\n"
  95. torrc += "ExcludeNodes " + excludes.pop()
  96. for exclude in excludes:
  97. torrc += ", " + exclude
  98. torrc += "\n\n# Only use the 1000 fastest exits\n"
  99. torrc += "ExitNodes " + exits.pop()
  100. for exit in exits:
  101. torrc += ", " + exit
  102. torrc += "\n\n"
  103. return torrc
  104. def help():
  105. end = '\033[0m'
  106. ul = lambda x : '\033[4m' + x + end # underline text
  107. red = lambda x : '\033[91m' + x + end # red text
  108. print( "\nCreate a tor configuration that reflects your preference." )
  109. print( "Select one of the following options:\n")
  110. print( "--sector\tSecure tor configuration." )
  111. print( "--speetor\tIf speed is what you need." )
  112. print( "--evator\tFor evading captchas on traditional websites." )
  113. print( "--help\t\tShow this helpful message.\n" )
  114. msg = ul("SecTor") + " is " + red("NOT RECOMMENDED") + " by the torproject (torproject.org)."
  115. msg += " It is designed to improve upon the default tor configuration in terms of security.\n"
  116. msg += "SecTor does three things:\n"
  117. msg += "1. Select guards that are in your region, so that not the entire world sees you taking a first hop.\n"
  118. msg += "2. As much as possible it avoids routing through the five eyes countries (us, ca, gb, au, nz) and Israel.\n"
  119. msg += "3. It excludes questionable relays, which run Windows XP or an outdated version of tor.\n"
  120. print( msg )
  121. msg = ul("SpeeTor") + " configures tor to only use fast nodes."
  122. msg += " This can be usefull for sharing large files quickly over tor, but is bad for anonymity and the tor network.\n"
  123. print( msg )
  124. msg = ul("EvaTor") + " selects slow nodes, which are used by less users."
  125. msg += " This means that the chance of having to fill out a captcha is significantly reduced.\n"
  126. print( msg )
  127. print( ul("Warnings:") )
  128. msg = "1. Using speeTor and evaTor instead of the tor defaults " + red("REDUCES YOUR ANONYMITY")
  129. msg += ", but you might prefer it if you are not concerned with strong adversaries."
  130. msg += " In particular, notor is very vulnerable."
  131. msg += " However, if you expect no strong adversaries or merely use Tor for circumvention, you should be fine.\n"
  132. msg += "2. SecTor is designed to be more secure than default tor, especially against powerful adversaries."
  133. msg += " However, secTor is " + red(ul("POTENTIALLY LESS SECURE")) + " than using tor defaults.\n"
  134. msg += "3. Use is at YOUR own risk.\n"
  135. print( msg )
  136. import sys
  137. sys.exit(0)
  138. if __name__=="__main__":
  139. import sys
  140. args = sys.argv[1:]
  141. # Check if all command line arguments are understood
  142. if len(args) == 0:
  143. help()
  144. if len(args) > 1:
  145. print("\nCan only handle one argument at a time.")
  146. help()
  147. arg = args[0]
  148. if arg not in set(['-h','--help','--sector','--speetor','--evator','--notor']):
  149. print("\nOption not understood, showing help instead:")
  150. help()
  151. if arg in ['-h','--help']:
  152. help()
  153. arg_resolver = dict([ ('--sector', sector), ('--speetor', speetor), ('--evator', evator) ])
  154. torrc = arg_resolver[arg]()
  155. f = open("tor_config.txt", "w")
  156. f.write(torrc)
  157. f.close()
  158. print( "Done!" )
  159. print( "Torrc saved in tor_config.txt" )