tor_check.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. "Could not download the list of Tor exit-nodes from: https://check.torproject.org/exit-addresses"
  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 and it looks like you have this external IP address: {ip_address}".format(
  58. ip_address=ip_address
  59. )
  60. )
  61. }
  62. else:
  63. search.result_container.answers["tor"] = {
  64. "answer": gettext(
  65. "You are not using Tor and you have this external IP address: {ip_address}".format(
  66. ip_address=ip_address
  67. )
  68. )
  69. }
  70. return True