2.7 (Nov 11, 2008)

- bug fix: smtp_password is output to denyhosts log (bug #2477552) reported by rogper.

- bug fix: name "info" not defined (reported by Jason L Tibbitts III)
  syncing from command line was broken but is now fixed.

- PLUGIN_SYNC: optional configuration parameter added.

- security fix: a couple of regex changes to prevent malicious entries 
  being added.

- regex fix for AllowUsers regex missing 'host' group

- added patch from Nelson Howell (patch #2006779) which adds a command line option to  
  immediately purge a specific IP address (--purgeip).

- added patch from Designing Patterns (patch #1965587) which adds SSL/TLS support
  for DenyHosts' email reports.

- added patch from David Sowder (patch #1940279) which fixes FAILED_ENTRY_REGEX on RHEL5.

- bug fix: allowed-hosts range inclusion (eg. 192.168.1.[1-5]) inadvertently omitted the 
  last address (thanks to  Dave Shield for the bug fix)

2.6 (Dec 7, 2006)

- security fix: malicious users can cause a DoS of ssh.
  for more info:

- fixed bug in 2 failed entry regexes weren't included properly in the hash

- fixed bug in attribute error: self.__sync_download

2.5 (June 21, 2006)

- ADMIN_EMAIL pref can now contain multiple email addresses delimited by a comma (white space 
  is optional).  eg.,,

- fixed bug in denyfileutil: 'timestamp' is now initialized properly

- daemon-control-dist: modified to work w/ non-default python versions.  You must change
  the PYTHON_BIN and #!/bin/env/python references if appropriate.

- added a debug message when loading allowed-hosts fails.

- fixed bug when reporting suspicious login activity.

2.4b (April 9, 2006)

- fixed missing "self." in

2.4 (April 9, 2006)

- added: PURGE_THRESHOLD setting (defaults to 0, or "none")
  defines the maximum times a host will be purged.  Once this amount
  has been exceeded then this host will not be purged. 

- added: SYSLOG_REPORT option which, if enabled, will send the
  denied hosts report to syslog (in addition to -or- instead of
  email, depending on your other settings).  Based on patch
  submission by Michael Still.

- fix: restricted usernames were being added to wrong file

2.3 (April 4, 2006)

- fix: denied hosts weren't being re-added after purge unless daemon was restarted 
  after the purge.  Thanks to Steven Finnegan for recognizing the problem.

- fix: daemon-control-dist should now behave correctly on FreeBSD systems

2.2 (March 13, 2006)

- added environment variable substitution of preference values.  Each value
  that contains $[SOME_NAME] will have $[SOME_NAME] substituted with the 
  value of the environment variable SOME_NAME.  eg.
      SMTP_SUBJECT = DenyHosts Report - $[HOSTNAME] 
  will result in the following expansion:
      SMTP_SUBJECT = DenyHosts Report - foo
  on a host that is named "foo"

- added configuaration option SMTP_DATE_FORMAT which allows you to override
  the DenyHosts "Date:" field when sending reports via email    

- fixed bug in AGE_RESET_RESTRICTED was not being converted to seconds

- fixed bug in exceptions raised by smtp.quit() are now handled

- fixed bug in missing import of "sync" line

2.1 (February 9, 2006)

- added command line flag --sync which runs DenyHosts (command line/cron version) in
  synchronization mode.  

- added SYNC_DOWNLOAD_RESILIENCY setting to limit download synchronization data to
  attacks that have lasted longer than this value.  That is, if the centralized server records an attack at 2 PM and then again at 5 PM,
  specifying a SYNC_DOWNLOAD_RESILIENCY = 4h will not download this ip address.
  However, if the attacker is recorded again at 6:15 PM then the ip address
  will be downloaded by your DenyHosts instance.  This value is used in
  conjunction with the SYNC_DOWNLOAD_THRESHOLD and only hosts that
  satisfy both values will be downloaded.  This value has no effect if
  SYNC_DOWNLOAD_THRESHOLD = 1 and refers to the timespan between the
  attackers first known attack and their most recent attack.
  Refer to

- added RESET_ON_SUCCESS option which, when set to "yes" will automatically reset
  the counter for the connecting ip address to 0 if the login was successful.  The
  default is "no".  This may be helpful in the event that a user occassionally mistypes
  their password.  See also the AGE_RESET_* options.
  Refer to

- bug fix: if synchronization mode is disabled (default) then denied hosts will not be
  added to the SYNC_HOSTS staging file.

- modified daemon-control-dist to use the 'ps' command (in the event
  that the /proc directory does not exist) to determine whether
  the DenyHosts process is still running.  

- modified daemon-control-dist to infer 'start' and 'stop' from
  symbolically linked programs in the event that the script
  is launched w/o arguments.  The linked filenames must begin
  with either an "S" (start) or a "K" (kill).

- added "restricted" user concept and functionality such that usernames defined
  as restricted (such as "mysql", "lpd", etc...) which are not intended for
  login purposes will be denied after DENY_THRESHOLD_RESTRICTED failed attempts.
  This option is based on ideas & suggestions from Ken Key and Dave Ingram.  
  Refer to

- added DENY_THRESHOLD_RESTRICTED (for users such as apache, mysql, etc...).  Defaults

- added AGE_RESET_RESTRICTED parameter

- added scripts/ which is suitable for generating a list
  of restricted users based on /etc/passwd's login shells (such as /sbin/nologin).

- added scripts/ which is suitable for generating a list
  of restricted users based on WORK_DIR/users-invalid contents.

- if synchronization fails, a stacktrace will be printed to the log file (or console)
  which may be useful for isolating the problem.

2.0 (February 5, 2006)

- DenyHosts has a new address:

- Added synchronization mode capability which allows all DenyHosts daemons the
  ability to seemlessly share denied host data.
  See this faq entry for more information:

- Added the configuration option USERDEF_FAILED_ENTRY_REGEX which allows the DenyHost
  user the ability to add custom regular expressions in order to block potential hackers.
  See this faq entry for more information:

- FAILED_ENTRY_REGEX5 now handles more login failures such as AllowGroups and AllowUsers.
  previously applied only to AllowGroups.

- Added FAILED_ENTRY_REGEX6 to handle "Did not receive identification string from ..." 

- Fixed issue when a purged host was re-added.

- fixed file permissions issue when creating some temp files

- Log format message can be customized using the new DAEMON_LOG_MESSAGE_FORMAT in addition to
  the existing DAEMON_LOG_TIME_FORMAT option.

- added 1 second sleep between stop & start in daemon-control-dist for "restart" command.

- Added ShoreWall plugins (thanks to Stéphane LeDauphin for the contribution).

- Fixed licensing ambiguity (DenyHosts is GPL v2).

- Removed from plugins.

1.1.4 (January 9, 2006)

- Added AllowedGroups patch from Marlon Paulse. DenyHosts will now:
    "detect login attempts to user accounts that are not members of
    groups listed as 'AllowedGroups' in the sshd configuration file."

- Updated denyhosts.cfg-sample such that WORK_DIR parameter points to an
  absolute pathname rather than a relative one.  

- Fixed email bug: failure to connect to smtp server is now handled properly.

- Fixed plugin bug: PLUGIN_DENY is now only invoked when new hosts are denied.


- Bug fix: duplicate entries were being added to allowed-warned-hosts file as well as 
  sending out duplicate email messages.

- If the prefs parameter DENY_THRESHOLD_INVALID isn't found but the deprecated DENY_THRESHOLD is
  found then the user is alerted of this.  Additionally, the latter value will be used for
  the missing DENY_THRESHOLD_INVALID parameter such that DenyHosts will continue to run
  without intervention.


- Fixed offset issue when running in daemon mode, the first pass of data discovered was 
  processed twice.

- All values that are converted to seconds in the module when the denyhosts.cfg
  file is processed.  Previously, these values were inefficiently converted each time 
  that they were used.

- Migrated some internal data structures to sets rather than tuples for performance 

- Better handling of illegal values in denyhosts.cfg.

- Fixed a bug in non-daemon mode when --purge flag was used.


- Daemon mode now closed standard file descriptors and detaches from tty based on
  patch from James Abbatiello.

- lock file is now created with 0644 permissions based on patch from James 

- added optional SMTP_USERNAME and SMTP_PASSWORD parameters and support for authenticating
  SMTP connections (when these parameters are defined).

- fixed bug when checking for required configuration parameters.


- configuration parameter DENY_THRESHOLD has been renamed DENY_THRESHOLD_INVALID
- added configuration parameters AGE_RESET_ROOT, AGE_RESET_INVALID and AGE_RESET_VALID

- added the ability to automatically reset host login attempts after a given 
  time period (age_reset) has elapsed.  See the FAQ entry:

- most WORK_DIR data files will be automatically migrated to the new
  data format to support the above functionality.  A timestamp field
  has been appended to each line, such that the new format is:
  key:# of attempts:timestamp

- added chkconfig compatibility to the daemon-control-dist script.  Thanks to
  Simon Amor for the contribution.

- added optional configuration parameters PLUGIN_DENY and PLUGIN_PURGE  

- added plugin support.  See the FAQ entry:  


- hostnames can now be specified in allowed-hosts file based 
  on a contribution from Mathias Wagner.

- hostnames specified in allowed-hosts are looked 
  up to determine ip addresses

- added optional pref: ALLOWED_HOSTS_HOSTNAME_LOOKUP

- if ALLOWED_HOSTS_HOSTNAME_LOOKUP is true, then each
  ip address in allowed-hosts is looked up to determine
  it's hostname


- fixed issue where multiple instances of the same host were added
  to /etc/hosts.deny (due to exceeding multiple DENY_THRESHOLD* settings

- bz2 support is disabled if "import bz2" fails

- displays more useful error message if Python version
  is incompatible with DenyHosts.

- changed format of timestamp in email messages sent by DenyHosts
  based on patch submitted by Rick Holbert 
  (now uses %z instead of %Z)


- fixed bug relating to empty hosts-root file

- added optional configuration parameter: DAEMON_LOG_TIME_FORMAT
  for specifying the timestamp in the DAEMON_LOG file

- now uses SIGTERM to stop daemon (rather than SIHGUP) based on
  the suggestion of Xavier Le Vourch

- daemon-control-dist has been updated to send SIGTERM on stop()


- added new configuration option, DENY_THRESHOLD_VALID 

- added new configuration option, DENY_THRESHOLD_ROOT 

- added "hosts-valid" output file (relative to WORK_DIR)

- added "hosts-root" output file (relative to WORK_DIR)

- modified to handle valid/invalid login hosts

- added 'condrestart' option to daemon-control-dist as per patch from Jason L Tibbitts III

- fixed double usage() method from being displayed by daemon-control-dist


- if upgrading DenyHosts to this version and PURGE_DENY is set then you must invoke with
  the --upgrade099 flag before using. eg.  $ --upgrade099
  For further details, refer to:    

- fixed bug: missing "import socket" in

- fixed bug: invalid comment format in /etc/hosts.deny for timestamping entries

- /etc/hosts.deny entries are timestamped immediately before the entry now (rather than inline, in 
  earlier versions).  The timestamped lines also contain the entry data for verification.  If 
  DenyHosts determines that a purge is necessary than the verification info is compared to 
  the actual entry line (ie. the next line).  If the two entries match, the lines are purged.  
  Otherwise a warning is output.  The verification algorithm was based on a suggestion from Jim 

- sshd related regex patterns can now be configured within the DenyHosts configuration file in the event
  that the default (eg. DenyHosts/ patterns do not successfully parse the end user's tcp_wrappers, 
  operating system and/or logging implementation.  For details refer to:


- fixed purge bug in daemon mode (using the wrong purge value to determine which records should be 


- fixed bug wrt handling of rotated files.  DenyHosts now compares the inodes to determine if a file 
  was rotated.  If detected, the previous file is closed and the new file opened. 

- restructred daemon code block (added additional methods)


- Command line that invoked --daemon is now recorded in the output log (useful for debugging)

- The daemon-control-dist script now optionally accepts command line args to be passed to the start and restart
  functions.  eg.  daemon-control start --config=test.cfg --debug


- If no denied hosts or suspicious logins are found, then there is no output in normal mode (only in debug mode).  
This limits the amount of data added to the log when in --daemon mode.  See:


- Fixed duplicate email report bug in --daemon mode.


- Fixed --daemon mode bug which occurred during purging entries

- Added more useful exception reporting for daemon mode


- Daemon configuration params DAEMON_SLEEP and DAEMON_PURGE can now be given in the same format accepted by 
PURGE_DENY (eg. 1d, 5h, 1y, etc...).  If no unit qualifier (eg. s, m, d, h, w, y) is given then 's' (seconds) is 


- Running in daemon mode now dumps preferences to log file

- Added AbusiveHosts class

- Added additional parameter to Purge constructor

- Purged entries from HOSTS_DENY are also removed from WORK_DIR/hosts
  SF bug:


- Added daemon mode 

- Added several optional parameters to the configuration file for daemon mode use


- Maintenance release

- Moved most classes to new modules

- Now uses the python logging package for some output


- Revised LockFile class to do perform exclusive locking -- deprecated the --unlock flag since it is no longer 


- Added LOCK_FILE configuration parameter and support such that only one instance of DenyHosts can be running at any 
given time

- Added PURGE_DENY configuration parameter and support for purging entries from the HOSTS_DENY file that have
exceeded the PURGE_DENY value

-- Added the ability to migrate HOSTS_DENY file such that all entries are suitable for purging.

-- Added --purge, --migrate and --unlock command line arguments


- Prefs change (reqd fields can be blank)


- Added support for using an alternate deny file with FreeBSD based on feed back from Alesha Oparin


- fixed blank BLOCK_SERVICE bug


- Added support for the metalog logger based on a patch contributed by Mike Kelly.

- Added support for FreeBSD based on input from Francesca Smith

- Added support for catching hostname entries (in addition to IP addresses) based on a patch from Christian Smyth

- Added support for using an alternative hosts deny file where only the offending ip address is listed.  This feature
is based on a patch contributed by John Meinel Jr.

- Added support for processing gzip'ed logfiles based on feature request by Brian McGraw.


- Modified email message date/time format to be RFC-2822 compliant.  Incorporated patch contributed by Rick 

- Added reverse dns lookups and the HOSTNAME_LOOKUP for enabling/disabling them.  Incorporated feature 
request of Ron Joffe.

- Added additional config option (SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS) for reporting (or not) 
suspicious login activity.  This feature is based on feedback from Ron Joffe.  

- Updated regex for matching non-existent user break-ins.  Previously, "invalid" was matched against.  
Now, both "invalid" and "illegal" should match.  This fix is based on email from Scott Hunziker.