tor_check.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. # lint: pylint
  3. """A plugin to check if the ip address of the request is a TOR exit node if the
  4. user searches for ``tor-check``. It fetches the tor exit node list from
  5. https://check.torproject.org/exit-addresses and parses all the IPs into a list,
  6. then checks if the user's IP address is in it.
  7. Enable in ``settings.yml``:
  8. .. code:: yaml
  9. enabled_plugins:
  10. ..
  11. - 'Tor check plugin'
  12. """
  13. import re
  14. from flask_babel import gettext
  15. from httpx import HTTPError
  16. from searx.network import get
  17. default_on = False
  18. name = gettext("Tor check plugin")
  19. '''Translated name of the plugin'''
  20. description = gettext(
  21. "This plugin checks if the address of the request is a TOR exit node, and"
  22. " informs the user if it is, like check.torproject.org but from searxng."
  23. )
  24. '''Translated description of the plugin.'''
  25. preference_section = 'query'
  26. '''The preference section where the plugin is shown.'''
  27. query_keywords = ['tor-check']
  28. '''Query keywords shown in the preferences.'''
  29. query_examples = ''
  30. '''Query examples shown in the preferences.'''
  31. # Regex for exit node addresses in the list.
  32. reg = re.compile(r"(?<=ExitAddress )\S+")
  33. def post_search(request, search):
  34. if search.search_query.pageno > 1:
  35. return True
  36. if search.search_query.query.lower() == "tor-check":
  37. # Request the list of tor exit nodes.
  38. try:
  39. resp = get("https://check.torproject.org/exit-addresses")
  40. node_list = re.findall(reg, resp.text)
  41. except HTTPError:
  42. # No answer, return error
  43. search.result_container.answers["tor"] = {
  44. "answer": gettext(
  45. "The TOR exit node list (https://check.torproject.org/exit-addresses) is unreachable."
  46. )
  47. }
  48. return True
  49. x_forwarded_for = request.headers.getlist("X-Forwarded-For")
  50. if x_forwarded_for:
  51. ip_address = x_forwarded_for[0]
  52. else:
  53. ip_address = request.remote_addr
  54. if ip_address in node_list:
  55. search.result_container.answers["tor"] = {
  56. "answer": gettext(
  57. "You are using TOR. Your IP address seems to be: {ip_address}.".format(ip_address=ip_address)
  58. )
  59. }
  60. else:
  61. search.result_container.answers["tor"] = {
  62. "answer": gettext(
  63. "You are not using TOR. Your IP address seems to be: {ip_address}.".format(ip_address=ip_address)
  64. )
  65. }
  66. return True