DoS hardening.
authorEric S. Raymond <esr@thyrsus.com>
Sun, 30 Sep 2012 05:01:17 +0000 (01:01 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Sun, 30 Sep 2012 05:01:17 +0000 (01:01 -0400)
Makefile
NEWS
irkerd
security.txt

index 722724df96df714ad6db9075f6812c9ac7de532b..c1ef880d0b351b55b320b37b65f7c267389afe0d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ clean:
        rm -f irkerd.1 irker-*.tar.gz *~
        rm -f SHIPPER.* *.html
 
-PYLINTOPTS = --rcfile=/dev/null --reports=n --include-ids=y --disable="C0103,C0111,C0301,R0201,R0902,R0903,E1101,W0201,W0621,W0702"
+PYLINTOPTS = --rcfile=/dev/null --reports=n --include-ids=y --disable="C0103,C0111,C0301,R0201,R0902,R0903,R0912,E1101,W0201,W0621,W0702"
 pylint:
        @pylint --output-format=parseable $(PYLINTOPTS) irkerd
        @pylint --output-format=parseable $(PYLINTOPTS) irkerhook.py
diff --git a/NEWS b/NEWS
index d17cbfdf13492144b4320a18d7b32f42c53ec44a..c6f31702736eced6615199bc883863ec92e87e08 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,8 @@
 
 1.2 @
   All segments of a message with embedded newlines are now transmitted.
-  Message reduction - irkerhook driops the filelist on execessively long ones.
-  Shell quote hardening in irkerhook.py.
+  Message reduction - irkerhook drips the filelist on execessively long ones.
+  Shell quote hardening in irkerhook.py and some anti-DoS logic.
 
 
 
diff --git a/irkerd b/irkerd
index bdcd54e3a50d56a519824327e6c1b8bbb1365f0b..bc53d5e9d938ef3d9bc922d3b500be5ad621e461 100755 (executable)
--- a/irkerd
+++ b/irkerd
@@ -35,6 +35,7 @@ UNSEEN_TTL = 60                       # Time to live, seconds since first request
 CHANNEL_MAX = 18               # Max channels open per socket (default)
 ANTI_FLOOD_DELAY = 0.125       # Anti-flood delay after transmissions, seconds
 ANTI_BUZZ_DELAY = 0.09         # Anti-buzz delay after queue-empty check
+CONNECTION_MAX = 200           # Avoid pushing per-process thread or fd limits
 
 # No user-serviceable parts below this line
 
@@ -340,6 +341,26 @@ class Irker:
                             for servername in servernames:
                                 if not self.servers[servername].live():
                                     del self.servers[servername]
+                            # If we might be pushing a resource limit
+                            # even after garbage collection, remove a
+                            # session.  The goal here is to head off
+                            # DoS attacks that aim at exhausting
+                            # thread space or file descriptors.  The
+                            # cost is that attempts to DoS this
+                            # service will cause lots of join/leave
+                            # spam as we scavenge old channels after
+                            # connecting to new ones. The particular
+                            # method used for selecting a session to
+                            # be terminated doesn't matter much; we
+                            # choose the one longest idle on the
+                            # assumption that message activity is likely
+                            # to be clumpy.
+                            oldest = None
+                            if len(self.servers) >= CONNECTION_MAX:
+                                for (name, server) in self.servers.items():
+                                    if not oldest or server.last_xmit < self.servers[oldest].last_xmit:
+                                        oldest = name
+                                del self.servers[oldest]
         except ValueError:
             self.logerr("can't recognize JSON on input: %s" % repr(line))
 
index 1dd53a30e176990278b07654a06a32ea51786c99..9a72dafc3c8ff8da766c218e766e7bde0b059b4a 100644 (file)
@@ -152,13 +152,10 @@ with legitimate high-volume use by a very active repo site.
 After this we appear to have run out of easy options, as source IP address
 is the only thing irkerd can see that an attacker can't spoof.
 
-=== Future directions ===
-
-One way we could mitigate some availability risks is by reaping old
-sessions when we're near resource limits.  An ordinary DoS attack
-would then be prevented from completely blocking all message traffic;
-the cost would be a whole lot of join/leave spam due to connection
-churn.
+We mitigate some availability risks by reaping old sessions when we're
+near resource limits.  An ordinary DoS attack would then be prevented
+from completely blocking all message traffic; the cost would be a
+whole lot of join/leave spam due to connection churn.
 
 = Authentication/Integrity =