[tor-commits] [doctor/master] One week suppression when relays return
atagar at torproject.org
atagar at torproject.org
Thu Mar 10 16:40:16 UTC 2016
commit 8db5d5e14b98ff003d783f46da8ec31ea49aea77
Author: Damian Johnson <atagar at torproject.org>
Date: Thu Mar 10 08:42:58 2016 -0800
One week suppression when relays return
When a previously malicious relay returns notifications for it are suppressed
for a week. This was requested by dgoulet. This also fixes a bug where we
only notified about one relay for each config entry, and a wording tweak
requeste by Roger.
---
track_relays.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 53 insertions(+), 10 deletions(-)
diff --git a/track_relays.py b/track_relays.py
index deee467..91b5c2e 100755
--- a/track_relays.py
+++ b/track_relays.py
@@ -7,6 +7,8 @@ Notifies if specific relays reappear in the network.
"""
import datetime
+import os
+import time
import traceback
import stem.descriptor.remote
@@ -18,9 +20,11 @@ import util
log = util.get_logger('track_relays')
EMAIL_SUBJECT = 'Relays Returned'
+ONE_WEEK = 7 * 24 * 60 * 60
EMAIL_BODY = """\
-The following previously BadExited relays have returned to the network...
+The following previously relays flagged as being malicious have returned to the
+network...
"""
@@ -102,6 +106,14 @@ def get_tracked_relays():
def main():
+ last_notified_config = stem.util.conf.get_config('last_notified')
+ last_notified_path = util.get_path('data', 'track_relays_last_notified.cfg')
+
+ if os.path.exists(last_notified_path):
+ last_notified_config.load(last_notified_path)
+ else:
+ last_notified_config._path = last_notified_path
+
# Map addresses and fingerprints to relays for constant time lookups. Address
# ranges are handled separately cuz... well, they're a pita.
@@ -122,30 +134,61 @@ def main():
for fingerprint in relay.fingerprints:
tracked_fingerprints[fingerprint] = relay
- downloader = stem.descriptor.remote.DescriptorDownloader()
found_relays = {} # mapping of TrackedRelay => RouterStatusEntry
- for desc in downloader.get_consensus():
+ for desc in stem.descriptor.remote.get_consensus():
if desc.address in tracked_addresses:
- found_relays[tracked_addresses[desc.address]] = desc
+ found_relays.setdefault(tracked_addresses[desc.address], []).append(desc)
elif desc.fingerprint in tracked_fingerprints:
- found_relays[tracked_fingerprints[desc.fingerprint]] = desc
+ found_relays.setdefault(tracked_fingerprints[desc.fingerprint], []).append(desc)
else:
for addr_entry, relay in tracked_address_ranges.items():
if addr_entry.is_match(desc.address):
- found_relays[relay] = desc
+ found_relays.setdefault(relay, []).append(desc)
+
+ all_descriptors = []
+
+ for relays in found_relays.values():
+ all_descriptors += relays
- if found_relays:
+ if found_relays and not is_notification_suppressed(all_descriptors):
log.debug("Sending a notification for %i relay entries..." % len(found_relays))
+ current_time = str(int(time.time()))
body = EMAIL_BODY
- for tracked_relay, desc in found_relays.items():
+ for tracked_relay, relays in found_relays.items():
log.debug('* %s' % tracked_relay)
body += '* %s (%s)\n' % (tracked_relay.identifier, tracked_relay.description)
- body += ' address: %s\n' % desc.address
- body += ' fingerprint: %s\n\n' % desc.fingerprint
+
+ for desc in relays:
+ body += ' address: %s:%s, fingerprint: %s\n' % (desc.address, desc.or_port, desc.fingerprint)
+ last_notified_config.set('%s:%s' % (desc.address, desc.or_port), current_time)
util.send(EMAIL_SUBJECT, body = body, to = ['bad-relays at lists.torproject.org', 'atagar at torproject.org'])
+ last_notified_config.save()
+
+
+def is_notification_suppressed(relays):
+ """
+ Check to see if we've already notified for all these relays today. No
+ point in causing too much noise.
+ """
+
+ is_all_suppressed = True
+ log.debug("Checking if notification should be suppressed...")
+ last_notified_config = stem.util.conf.get_config('last_notified')
+
+ for desc in relays:
+ key = '%s:%s' % (desc.address, desc.or_port)
+ suppression_time = ONE_WEEK - (int(time.time()) - last_notified_config.get(key, 0))
+
+ if suppression_time < 0:
+ log.debug("* notification for %s isn't suppressed" % key)
+ is_all_suppressed = False
+ else:
+ log.debug("* we already notified for %s recently, suppressed for %i hours" % (key, suppression_time / 3600))
+
+ return is_all_suppressed
if __name__ == '__main__':
More information about the tor-commits
mailing list