tor_check.py 2.6 KB

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