diff --git a/ChangeLog b/ChangeLog index 47f26fa0..2cbbba93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,10 @@ ver. 1.1.2-dev-1 (20??/??/??) - development nightly edition ----------- ### Fixes +* backend `pyinotify`: fixes monitoring on systems with native inotify other than Linux (e. g. FreeBSD 15+), + where the parent directory of the log could not be watched (`EINVAL` for output-only flag `IN_ISDIR` in the mask), + so log rotation was not detected and the jail silently stopped to find failures; also removal of a log file + is detected now without relying on `IN_IGNORED` (not sent there for a watched file) (gh-4250) * `filter.d/postfix.conf` - monitor all Postfix instances in `system-postfix.slice` with the systemd backend (gh-4008) * `filter.d/nginx-botsearch.conf` - error-log regex extended with support of journal format (gh-3732) * `filter.d/apache-noscript.conf` - match a request for the `cgi-bin` directory itself (no script name after it), diff --git a/fail2ban/server/filterpyinotify.py b/fail2ban/server/filterpyinotify.py index 319314b7..99943973 100644 --- a/fail2ban/server/filterpyinotify.py +++ b/fail2ban/server/filterpyinotify.py @@ -243,10 +243,16 @@ class FilterPyinotify(FileFilter): def _addDirWatcher(self, path_dir): # Add watch for the directory: if path_dir not in self.__watchDirs: + # note: IN_ISDIR is an output flag only (set in events by kernel), it must not be + # specified in the mask, since some systems reject it with EINVAL (e. g. FreeBSD 15+, + # with native inotify), so the directory would be not monitored at all (gh-4250); + # IN_ONLYDIR (input flag) to watch the path only if it is a directory; + # IN_DELETE and IN_MOVED_FROM to notice removal of watched files in the directory, since + # not all systems send IN_IGNORED for the watch of a removed file (e. g. FreeBSD): self.__watchDirs.update( - self.__monitor.add_watch(path_dir, pyinotify.IN_CREATE | - pyinotify.IN_MOVED_TO | pyinotify.IN_MOVE_SELF | - pyinotify.IN_DELETE_SELF | pyinotify.IN_ISDIR)) + self.__monitor.add_watch(path_dir, pyinotify.IN_CREATE | + pyinotify.IN_MOVED_TO | pyinotify.IN_DELETE | pyinotify.IN_MOVED_FROM | + pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF | pyinotify.IN_ONLYDIR)) logSys.debug("Added monitor for the parent directory %s", path_dir) def _delDirWatcher(self, path_dir):