diff --git a/fail2ban/helpers.py b/fail2ban/helpers.py index c6da8f30..8d981ed6 100644 --- a/fail2ban/helpers.py +++ b/fail2ban/helpers.py @@ -32,6 +32,13 @@ from threading import Lock from .server.mytime import MyTime +try: + import ctypes + _libcap = ctypes.CDLL('libcap.so.2') +except: + _libcap = None + + PREFER_ENC = locale.getpreferredencoding() # correct preferred encoding if lang not set in environment: if PREFER_ENC.startswith('ANSI_'): # pragma: no cover @@ -451,6 +458,23 @@ def substituteRecursiveTags(inptags, conditional='', return tags +if _libcap: + def prctl_set_th_name(name): + """Helper to set real thread name (used for identification and diagnostic purposes). + """ + try: + if sys.version_info >= (3,): # pragma: 2.x no cover + name = name.encode() + else: # pragma: 3.x no cover + name = bytes(name) + _libcap.prctl(15, name[0:15]) # PR_SET_NAME = 15, name can be up to 15 bytes long (16 bytes with NTS zero) + except: + pass +else: # pragma: no cover + def prctl_set_th_name(name): + pass + + class BgService(object): """Background servicing diff --git a/fail2ban/server/actions.py b/fail2ban/server/actions.py index e42f663c..86c39e00 100644 --- a/fail2ban/server/actions.py +++ b/fail2ban/server/actions.py @@ -76,7 +76,7 @@ class Actions(JailThread, Mapping): """ def __init__(self, jail): - JailThread.__init__(self) + JailThread.__init__(self, name="f2b/a."+jail.name) ## The jail which contains this action. self._jail = jail self._actions = OrderedDict() diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index ad9014c7..d654fe9e 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -110,6 +110,8 @@ class Filter(JailThread): self.checkFindTime = True ## Ticks counter self.ticks = 0 + ## Thread name: + self.name="f2b/f."+self.jailName self.dateDetector = DateDetector() logSys.debug("Created %s", self) diff --git a/fail2ban/server/jailthread.py b/fail2ban/server/jailthread.py index 5c7afd38..d0430367 100644 --- a/fail2ban/server/jailthread.py +++ b/fail2ban/server/jailthread.py @@ -29,7 +29,7 @@ from threading import Thread from abc import abstractmethod from .utils import Utils -from ..helpers import excepthook +from ..helpers import excepthook, prctl_set_th_name class JailThread(Thread): @@ -76,6 +76,15 @@ class JailThread(Thread): print(e) self.run = run_with_except_hook + if sys.version_info >= (3,): # pragma: 2.x no cover + def _bootstrap(self): + prctl_set_th_name(self.name) + return super(JailThread, self)._bootstrap(); + else: # pragma: 3.x no cover + def __bootstrap(self): + prctl_set_th_name(self.name) + return Thread._Thread__bootstrap(self) + @abstractmethod def status(self, flavor="basic"): # pragma: no cover - abstract """Abstract - Should provide status information. @@ -108,4 +117,6 @@ class JailThread(Thread): if self.active is not None: super(JailThread, self).join() - +## python 2.x replace binding of private __bootstrap method: +if sys.version_info < (3,): # pragma: 3.x no cover + JailThread._Thread__bootstrap = JailThread._JailThread__bootstrap diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py index 853eb75c..15265822 100644 --- a/fail2ban/server/server.py +++ b/fail2ban/server/server.py @@ -39,7 +39,7 @@ from .transmitter import Transmitter from .asyncserver import AsyncServer, AsyncServerException from .. import version from ..helpers import getLogger, _as_bool, extractOptions, str2LogLevel, \ - getVerbosityFormat, excepthook + getVerbosityFormat, excepthook, prctl_set_th_name # Gets the instance of the logger. logSys = getLogger(__name__) @@ -81,6 +81,8 @@ class Server: 'Linux': '/dev/log', } self.__prev_signals = {} + # replace real thread name with short process name (for top/ps/pstree or diagnostic): + prctl_set_th_name('f2b/server') def __sigTERMhandler(self, signum, frame): # pragma: no cover - indirect tested logSys.debug("Caught signal %d. Exiting", signum) diff --git a/fail2ban/tests/filtertestcase.py b/fail2ban/tests/filtertestcase.py index d46d4cf1..38ae1812 100644 --- a/fail2ban/tests/filtertestcase.py +++ b/fail2ban/tests/filtertestcase.py @@ -266,7 +266,7 @@ class BasicFilter(unittest.TestCase): def setUp(self): super(BasicFilter, self).setUp() - self.filter = Filter('name') + self.filter = Filter(None) def testGetSetUseDNS(self): # default is warn