防止SSH字典攻击与DenyHosts
版本1.0
作者:Falko Timme
最后编辑:02/07/2006
在本教程中,我将展示如何安装和配置DenyHosts。 DenyHosts是一种观察登录尝试SSH的工具,如果从同一个IP地址重复发现失败的登录尝试,DenyHosts会将该IP地址的进一步登录尝试放入/etc/hosts.deny中 。 DenyHosts可以由cron或守护进程运行。 在本教程中,我将运行DenyHosts作为守护进程。
从DenyHosts网站 :
“DenyHosts是一个旨在由Linux系统管理员运行的脚本,用于帮助阻止ssh服务器攻击。
如果您曾经看过您的ssh日志(/ var / log / secure on Redhat,/var/log/auth.log on Mandrake等等),您可能会惊讶地看到有多少黑客尝试访问你的服务器 希望他们没有成功(但是再一次,你怎么知道的)。 自动防止该攻击者继续进入您的系统不是更好吗?
DenyHosts试图解决上述...“
本教程基于Debian Sarge系统,但它应该适用于其他发行版,几乎没有任何修改。
我想先说说这不是建立这样一个系统的唯一途径。 实现这一目标有很多方法,但这是我所采取的方式。 我不会保证这将为您工作!
1安装
DenyHosts是用Python编写的,因此我们必须首先安装Python和Python开发文件:
apt-get install python python2.3-dev python2.3
然后我们下载并安装DenyHosts,如下所示:
cd / tmp
wget http://mesh.dl.sourceforge.net/sourceforge/denyhosts/DenyHosts-2.0.tar.gz
tar xvfz DenyHosts-2.0.tar.gz
cd DenyHosts-2.0
python setup.py安装
这将DenyHosts安装到/ usr / share / denyhosts 。
2配置
现在我们必须创建DenusHosts配置文件/usr/share/denyhosts/denyhosts.cfg 。 我们可以使用示例配置文件/usr/share/denyhosts/denyhosts.cfg-dist来进行下列操作:
cd / usr / share / denyhosts
cp denyhosts.cfg-dist denyhosts.cfg
然后,我们必须 使用我们喜欢的编辑器(例如 vi) 编辑 denyhosts.cfg 。 我看起来像这样:
############ THESE SETTINGS ARE REQUIRED ############
######################################################################## # # SECURE_LOG: the log file that contains sshd logging info # if you are not sure, grep "sshd:" /var/log/* # # The file to process can be overridden with the --file command line # argument # # Redhat or Fedora Core: #SECURE_LOG = /var/log/secure # # Mandrake, FreeBSD or OpenBSD: SECURE_LOG = /var/log/auth.log # # SuSE: #SECURE_LOG = /var/log/messages # ########################################################################
######################################################################## # HOSTS_DENY: the file which contains restricted host access information # # Most operating systems: HOSTS_DENY = /etc/hosts.deny # # Some BSD (FreeBSD) Unixes: #HOSTS_DENY = /etc/hosts.allow # # Another possibility (also see the next option): #HOSTS_DENY = /etc/hosts.evil #######################################################################
######################################################################## # PURGE_DENY: removed HOSTS_DENY entries that are older than this time # when DenyHosts is invoked with the --purge flag # # format is: i[dhwmy] # Where 'i' is an integer (eg. 7) # 'm' = minutes # 'h' = hours # 'd' = days # 'w' = weeks # 'y' = years # # never purge: PURGE_DENY = # # purge entries older than 1 week #PURGE_DENY = 1w # # purge entries older than 5 days #PURGE_DENY = 5d #######################################################################
####################################################################### # BLOCK_SERVICE: the service name that should be blocked in HOSTS_DENY # # man 5 hosts_access for details # # eg. sshd: 127.0.0.1 # will block sshd logins from 127.0.0.1 # # To block all services for the offending host: #BLOCK_SERVICE = ALL # To block only sshd: BLOCK_SERVICE = sshd # To only record the offending host and nothing else (if using # an auxilary file to list the hosts). Refer to: # http://denyhosts.sourceforge.net/faq.html#aux #BLOCK_SERVICE = # #######################################################################
####################################################################### # # DENY_THRESHOLD_INVALID: block each host after the number of failed login # attempts has exceeded this value. This value applies to invalid # user login attempts (eg. non-existent user accounts) # DENY_THRESHOLD_INVALID = 5 # #######################################################################
####################################################################### # # DENY_THRESHOLD_VALID: block each host after the number of failed # login attempts has exceeded this value. This value applies to valid # user login attempts (eg. user accounts that exist in /etc/passwd) except # for the "root" user # DENY_THRESHOLD_VALID = 10 # #######################################################################
####################################################################### # # DENY_THRESHOLD_ROOT: block each host after the number of failed # login attempts has exceeded this value. This value applies to # "root" user login attempts only. # DENY_THRESHOLD_ROOT = 5 # #######################################################################
####################################################################### # # WORK_DIR: the path that DenyHosts will use for writing data to # (it will be created if it does not already exist). # # Note: it is recommended that you use an absolute pathname # for this value (eg. /home/foo/denyhosts/data) # WORK_DIR = /usr/share/denyhosts/data # #######################################################################
####################################################################### # # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS # # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES|NO # If set to YES, if a suspicious login attempt results from an allowed-host # then it is considered suspicious. If this is NO, then suspicious logins # from allowed-hosts will not be reported. All suspicious logins from # ip addresses that are not in allowed-hosts will always be reported. # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES ######################################################################
###################################################################### # # HOSTNAME_LOOKUP # # HOSTNAME_LOOKUP=YES|NO # If set to YES, for each IP address that is reported by Denyhosts, # the corresponding hostname will be looked up and reported as well # (if available). # HOSTNAME_LOOKUP=YES # ######################################################################
###################################################################### # # LOCK_FILE # # LOCK_FILE=/path/denyhosts # If this file exists when DenyHosts is run, then DenyHosts will exit # immediately. Otherwise, this file will be created upon invocation # and deleted upon exit. This ensures that only one instance is # running at a time. # # Redhat/Fedora: #LOCK_FILE = /var/lock/subsys/denyhosts # # Debian LOCK_FILE = /var/run/denyhosts.pid # # Misc #LOCK_FILE = /tmp/denyhosts.lock # ######################################################################
############ THESE SETTINGS ARE OPTIONAL ############
####################################################################### # # ADMIN_EMAIL: if you would like to receive emails regarding newly # restricted hosts and suspicious logins, set this address to # match your email address. If you do not want to receive these reports # leave this field blank (or run with the --noemail option) # ADMIN_EMAIL = # #######################################################################
####################################################################### # SMTP_HOST = localhost SMTP_PORT = 25 SMTP_FROM = DenyHosts <nobody@localhost> SMTP_SUBJECT = DenyHosts Report #SMTP_USERNAME=foo #SMTP_PASSWORD=bar # #######################################################################
###################################################################### # # ALLOWED_HOSTS_HOSTNAME_LOOKUP # # ALLOWED_HOSTS_HOSTNAME_LOOKUP=YES|NO # If set to YES, for each entry in the WORK_DIR/allowed-hosts file, # the hostname will be looked up. If your versions of tcp_wrappers # and sshd sometimes log hostnames in addition to ip addresses # then you may wish to specify this option. # #ALLOWED_HOSTS_HOSTNAME_LOOKUP=NO # ######################################################################
###################################################################### # # AGE_RESET_VALID: Specifies the period of time between failed login # attempts that, when exceeded will result in the failed count for # this host to be reset to 0. This value applies to login attempts # to all valid users (those within /etc/passwd) with the # exception of root. If not defined, this count will never # be reset. # # See the comments in the PURGE_DENY section (above) # for details on specifying this value or for complete details # refer to: http://denyhosts.sourceforge.net/faq.html#timespec # AGE_RESET_VALID=5d # ######################################################################
###################################################################### # # AGE_RESET_ROOT: Specifies the period of time between failed login # attempts that, when exceeded will result in the failed count for # this host to be reset to 0. This value applies to all login # attempts to the "root" user account. If not defined, # this count will never be reset. # # See the comments in the PURGE_DENY section (above) # for details on specifying this value or for complete details # refer to: http://denyhosts.sourceforge.net/faq.html#timespec # AGE_RESET_ROOT=25d # ######################################################################
###################################################################### # # AGE_RESET_INVALID: Specifies the period of time between failed login # attempts that, when exceeded will result in the failed count for # this host to be reset to 0. This value applies to login attempts # made to any invalid username (those that do not appear # in /etc/passwd). If not defined, count will never be reset. # # See the comments in the PURGE_DENY section (above) # for details on specifying this value or for complete details # refer to: http://denyhosts.sourceforge.net/faq.html#timespec # AGE_RESET_INVALID=10d # ######################################################################
###################################################################### # # PLUGIN_DENY: If set, this value should point to an executable # program that will be invoked when a host is added to the # HOSTS_DENY file. This executable will be passed the host # that will be added as it's only argument. # #PLUGIN_DENY=/usr/bin/true # ######################################################################
###################################################################### # # PLUGIN_PURGE: If set, this value should point to an executable # program that will be invoked when a host is removed from the # HOSTS_DENY file. This executable will be passed the host # that is to be purged as it's only argument. # #PLUGIN_PURGE=/usr/bin/true # ######################################################################
###################################################################### # # USERDEF_FAILED_ENTRY_REGEX: if set, this value should contain # a regular expression that can be used to identify additional # hackers for your particular ssh configuration. This functionality # extends the built-in regular expressions that DenyHosts uses. # This parameter can be specified multiple times. # See this faq entry for more details: # http://denyhosts.sf.net/faq.html#userdef_regex # #USERDEF_FAILED_ENTRY_REGEX= # # ######################################################################
######### THESE SETTINGS ARE SPECIFIC TO DAEMON MODE ##########
####################################################################### # # DAEMON_LOG: when DenyHosts is run in daemon mode (--daemon flag) # this is the logfile that DenyHosts uses to report it's status. # To disable logging, leave blank. (default is: /var/log/denyhosts) # DAEMON_LOG = /var/log/denyhosts # # disable logging: #DAEMON_LOG = # ######################################################################
####################################################################### # # DAEMON_LOG_TIME_FORMAT: when DenyHosts is run in daemon mode # (--daemon flag) this specifies the timestamp format of # the DAEMON_LOG messages (default is the ISO8061 format: # ie. 2005-07-22 10:38:01,745) # # for possible values for this parameter refer to: man strftime # # Jan 1 13:05:59 #DAEMON_LOG_TIME_FORMAT = %b %d %H:%M:%S # # Jan 1 01:05:59 #DAEMON_LOG_TIME_FORMAT = %b %d %I:%M:%S # ######################################################################
####################################################################### # # DAEMON_LOG_MESSAGE_FORMAT: when DenyHosts is run in daemon mode # (--daemon flag) this specifies the message format of each logged # entry. By default the following format is used: # # %(asctime)s - %(name)-12s: %(levelname)-8s %(message)s # # Where the "%(asctime)s" portion is expanded to the format # defined by DAEMON_LOG_TIME_FORMAT # # This string is passed to python's logging.Formatter contstuctor. # For details on the possible format types please refer to: # http://docs.python.org/lib/node357.html # # This is the default: #DAEMON_LOG_MESSAGE_FORMAT = %(asctime)s - %(name)-12s: %(levelname)-8s %(message)s # # ######################################################################
####################################################################### # # DAEMON_SLEEP: when DenyHosts is run in daemon mode (--daemon flag) # this is the amount of time DenyHosts will sleep between polling # the SECURE_LOG. See the comments in the PURGE_DENY section (above) # for details on specifying this value or for complete details # refer to: http://denyhosts.sourceforge.net/faq.html#timespec # # DAEMON_SLEEP = 30s # #######################################################################
####################################################################### # # DAEMON_PURGE: How often should DenyHosts, when run in daemon mode, # run the purge mechanism to expire old entries in HOSTS_DENY # This has no effect if PURGE_DENY is blank. # DAEMON_PURGE = 1h # #######################################################################
######### THESE SETTINGS ARE SPECIFIC TO ########## ######### DAEMON SYNCHRONIZATION ##########
####################################################################### # # Synchronization mode allows the DenyHosts daemon the ability # to periodically send and receive denied host data such that # DenyHosts daemons worldwide can automatically inform one # another regarding banned hosts. This mode is disabled by # default, you must uncomment SYNC_SERVER to enable this mode. # # for more information, please refer to: # http:/denyhosts.sourceforge.net/faq.html#sync # #######################################################################
####################################################################### # # SYNC_SERVER: The central server that communicates with DenyHost # daemons. Currently, denyhosts.net is the only available server # however, in the future, it may be possible for organizations to # install their own server for internal network synchronization # # To disable synchronization (the default), do nothing. # # To enable synchronization, you must uncomment the following line: #SYNC_SERVER = http://xmlrpc.denyhosts.net:9911 # #######################################################################
####################################################################### # # SYNC_INTERVAL: the interval of time to perform synchronizations if # SYNC_SERVER has been uncommented. The default is 1 hour. # #SYNC_INTERVAL = 1h # #######################################################################
####################################################################### # # SYNC_UPLOAD: allow your DenyHosts daemon to transmit hosts that have # been denied? This option only applies if SYNC_SERVER has # been uncommented. # #SYNC_UPLOAD = no # # the default: #SYNC_UPLOAD = yes # #######################################################################
####################################################################### # # SYNC_DOWNLOAD: allow your DenyHosts daemon to receive hosts that have # been denied by others? This option only applies if SYNC_SERVER has # been uncommented. # #SYNC_DOWNLOAD = no # # the default: #SYNC_DOWNLOAD = yes # #######################################################################
####################################################################### # # SYNC_DOWNLOAD_THRESHOLD: If SYNC_DOWNLOAD is enabled this paramter # filters the returned hosts to those that have been blocked this many # times by others. That is, if set to 1, then if a single DenyHosts # server has denied an ip address then you will receive the denied host. # #SYNC_DOWNLOAD_THRESHOLD = 10 # # the default: #SYNC_DOWNLOAD_THRESHOLD = 3 # ####################################################################### |
确保将SECURE_LOG和LOCK_FILE设置为正确的分发值! 对于Debian,这些是:
SECURE_LOG = /var/log/auth.log
LOCK_FILE = /var/run/denyhosts.pid
因为我们要作为守护进程运行DenyHosts,所以我们需要守护进程控制脚本/ usr / share / denyhosts / daemon-control 。 再次,我们可以使用示例脚本/ usr / share / denyhosts / daemon-control-dist创建所需的文件:
cp daemon-control-dist守护进程控制
编辑/ usr / share / denyhosts /守护进程控制 ,并确保为 DENYHOSTS_BIN , DENYHOSTS_LOCK 和 DENYHOSTS_CFG 设置正确的值 。 对于Debian,这些是:
DENYHOSTS_BIN =“/usr/bin/denyhosts.py”
DENYHOSTS_LOCK =“/var/run/denyhosts.pid”
DENYHOSTS_CFG =“/usr/share/denyhosts/denyhosts.cfg”
所以我的 / usr / share / denyhosts / daemon-control 文件如下所示:
#!/usr/bin/env python # denyhosts Bring up/down the DenyHosts daemon # # chkconfig: 2345 98 02 # description: Activates/Deactivates the # DenyHosts daemon to block ssh attempts # ###############################################
############################################### #### Edit these to suit your configuration #### ###############################################
DENYHOSTS_BIN = "/usr/bin/denyhosts.py" DENYHOSTS_LOCK = "/var/run/denyhosts.pid" DENYHOSTS_CFG = "/usr/share/denyhosts/denyhosts.cfg"
############################################### #### Do not edit below #### ###############################################
import os, sys, signal, time
STATE_NOT_RUNNING = -1 STATE_LOCK_EXISTS = -2
def usage(): print "Usage: %s {start [args...] | stop | restart [args...] | status | debug | condrestart [args...] }" % sys.argv[0] print print "For a list of valid 'args' refer to:" print "$ denyhosts.py --help" print sys.exit(0)
def getpid(): try: fp = open(DENYHOSTS_LOCK, "r") pid = int(fp.readline().rstrip()) fp.close() except Exception, e: return STATE_NOT_RUNNING
if os.access(os.path.join("/proc", str(pid)), os.F_OK): return pid else: return STATE_LOCK_EXISTS
def start(*args): cmd = "%s --daemon " % DENYHOSTS_BIN if args: cmd += ' '.join(args)
print "starting DenyHosts: ", cmd
os.system(cmd)
def stop(): pid = getpid() if pid >= 0: os.kill(pid, signal.SIGTERM) print "sent DenyHosts SIGTERM" else: print "DenyHosts is not running"
def debug(): pid = getpid() if pid >= 0: os.kill(pid, signal.SIGUSR1) print "sent DenyHosts SIGUSR1" else: print "DenyHosts is not running"
def status(): pid = getpid() if pid == STATE_LOCK_EXISTS: print "%s exists but DenyHosts is not running" % DENYHOSTS_LOCK elif pid == STATE_NOT_RUNNING: print "Denyhosts is not running" else: print "DenyHosts is running with pid = %d" % pid
def condrestart(*args): pid = getpid() if pid >= 0: restart(*args)
def restart(*args): stop() time.sleep(1) start(*args)
if __name__ == '__main__': cases = {'start': start, 'stop': stop, 'debug': debug, 'status': status, 'condrestart': condrestart, 'restart': restart}
try: args = sys.argv[2:] except: args = []
try: option = sys.argv[1]
if option in ('start', 'restart', 'condrestart'): if '--config' not in args and '-c' not in args: args.append("--config=%s" % DENYHOSTS_CFG)
cmd = cases[option] apply(cmd, args) except: usage()
|
接下来我们必须使该文件可执行:
chown root守护进程控制
chmod 700守护进程
之后,我们为DenyHosts创建系统启动链接,系统启动时自动启动:
cd /etc/init.d
ln -s / usr / share / denyhosts / daemon-control denyhosts
update-rc.d denyhosts默认值
最后,我们开始DenyHosts:
/etc/init.d/denyhosts开始
如果您对日志 感兴趣 , DenyHosts将登录到 / var / log / denyhosts 。 SSH守护进程 在Debian上 登录到 /var/log/auth.log 。 您可以通过SSH查看这两个日志并尝试使用无效用户或有效用户登录,密码不正确等等,并查看会发生什么。 超过不正确登录尝试的阈值后,您尝试连接的IP地址应该列在 /etc/hosts.deny中 ,如下所示:
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system. # See the manual pages hosts_access(5), hosts_options(5) # and /usr/doc/netbase/portmapper.txt.gz # # Example: ALL: some.host.name, .some.domain # ALL EXCEPT in.fingerd: other.host.name, .other.domain # # If you're going to protect the portmapper use the name "portmap" for the # daemon name. Remember that you can only use the keyword "ALL" and IP # addresses (NOT host or domain names) for the portmapper. See portmap(8) # and /usr/doc/portmap/portmapper.txt.gz for further information. # # The PARANOID wildcard matches any host whose name does not match its # address.
# You may wish to enable this to ensure any programs that don't # validate looked up hostnames still leave understandable logs. In past # versions of Debian this has been the default. # ALL: PARANOID sshd: 192.168.0.203 |
这意味着使用SSH的IP地址为192.168.0.203的系统无法连接。
您可以指定是否/何时从/etc/hosts.deny再次删除IP地址 - 请查看/usr/share/denyhosts/denyhosts.cfg中的PURGE_DENY变量。 您必须使用--purge选项启动DenyHosts,使PURGE_DENY变量有效,如下所示:
/etc/init.d/denyhosts start --purge
但是,您也可以从那里手动删除IP地址,一旦删除,这些IP地址可以尝试通过SSH重新登录。
链接