DenyHost简介:

DenyHosts是用Python编写的脚本程序用来分析ssh登录日志信息以确定哪些主机在尝试攻入我们的服务器。它还能对指定的用户账号进行监控,通常DenyHost将用户账号分成3类,合法用户、root用户和非合法用户,它会对使用ssh方式连接时使用的账号信息与当前系统上存在的系统账号进行对比并分类至合法还是非法用户以及root用户,如果用户名在系统中不存在,就会被归类到非法用户中,这种方式实现更细致的对尝试破解攻入系统的远程主机进行记录,并根据设定的密码尝试频次来追踪每个远程主机。另外,一旦发现远程主机有重复***服务器的行为,会将该主机的IP地址加入到/etc/hosts.deny文件中以实现拒绝对应IP的远程主机登录,从而保护当前服务器,避免被***攻入。

DenyHosts适用场景:

Linux操作系统或者是运行了sshd服务的服务器。

SSH服务的安全性配置:

在sshd配置文件中启用以下参数并调整参数值,(测试机的IP地址为172.16.100.2)。

1、禁用root登录,PermitRootLogin选项并将其参数值改为no。

# vim /etc/ssh/sshd_config

wKiom1SjZeLzy2D1AABbqSdLfGM464.jpg

2、禁用密码登录,使用公钥的方式登录服务器。

wKiom1SjZ03glj6LAABwelwVN2w073.jpg

3、更改ssh服务监听的端口,默认适用22,调整为其他非常用端口号。

wKioL1SjcwLQl3pLAABNuZLPVJU200.jpg

重启ssh服务,测试登录的效果,:

Xshell:\> ssh 172.16.100.2 

wKiom1SjczvCGsTPAADHU9arkH0362.jpg

默认适用22端口连接主机已经不允许了,适用9922端口连接的话,效果如下图:

wKioL1SjdHGwe6IAAAGAMAeKSis626.jpg

选择Accept&Save之后,出现下图:

wKiom1SjdBfQhKayAAImEOTKSbQ544.jpg

截图中可以看到我们的登录方式中适用Password的方式已经变成灰色了,即不能使用输入密码的方式来登录了,这个时候如果我们要使用公钥的方式来登录这台服务器,当然即使是有公钥,因为我们使用的是root登录的,默认也会被禁止。

要使用公钥的方式连接这台服务器,有两种应用场景,一种是Linux客户端服务器使用ssh公钥的方式来连接,一种是在windows系统中使用xshell生成的用户公钥的方式来登录,这两种方式生成公钥之后都需要将公钥导入到我们要连接的服务器端当中,这样我们在客户端主机上连接服务器就不再需要密码。

注意,是客户端主机也即我们使用的主机要生成公钥,然后将公钥导入到服务器端对应的账户的.ssh目录下的authorized_keys文件中。另外,需要先将客户端的公钥生成之后导入到服务器端的authorized_keys文件中然后再调整服务器端禁止root登陆等选项,否则公钥文件的导入会麻烦。

场景一:Linux客户端主机连接服务器:

1、首先在Linux客户端主机上生成其公钥,(示例中使用的客户端主机IP为172.16.100.3)

# ssh-keygen -t rsa -P ''

wKiom1Sjeo3iJnHKAAEYH9Dj8ro794.jpg

wKiom1SjetLw54YOAABBGrc9Cdw026.jpg

截图中id_rsa.pub就是生成的公钥文件。

2、将这个公钥文件导入到服务器端(172.16.100.2)当中

# ssh-copy-id -i /root/.ssh/id_rsa.pub 172.16.100.2

wKioL1SjfJOywqU-AACuA965zZk753.jpg

在服务器端(172.16.100.2)查看导入的公钥信息:

wKioL1SjfXygk7zMAABN29OUrNI789.jpg

其中authorized_keys是生成的用于保存公钥信息的文件,我们导入的公钥信息被保存在这个文件中了,可以使用cat命令来查看其内容:

wKiom1SjfSDDiuDnAADwhw_BcWg437.jpg

可以看到这行内容的末尾是对应的主机以及使用的连接账号信息。

在客户端172.16.100.3主机上连接172.16.100.2服务器:

wKioL1SjfkTi8TVVAABMu4_7d1E074.jpg

截图中可以看到在172.16.100.3主机上直接连接172.16.100.2服务器端成功了。

场景二:Windows系统中使用Xshell连接服务器端:

1、生成公钥,按如下步骤操作:

wKiom1Sjfr-D9eL7AAHSebJDeM0014.jpg

wKioL1Sjf5PAiLSMAAHKSFbwBjY638.jpg

选择哪种加密类型都是可以的,截图中使用的是RSA

wKiom1SjfxTQrPZyAAG3SuBaxKc801.jpg

wKioL1Sjf_KgV7WIAAF1WrtZkJQ702.jpg

后面的这些就选择Next就可以。

wKioL1SjgFjyLAnCAAH-vAf8SjM081.jpg

在点选Finish之前选择将公钥保存成文件,放在系统的某个目录下,以备之后导入服务器端使用。

wKioL1SjgM2yrruLAADB-pJH5DU743.jpg

2、将这个公钥文件导入到服务器中,并执行下面命令:

# cat id_rsa_1024.pub >> /root/.ssh/authorized_keys 

wKioL1SjgVKwP6kiAABdDlEHbxM184.jpg

现在客户端的公钥已经导入到服务器端,测试使用公钥的方式来连接服务器端:

wKiom1SjiUiSA-K9AAImUvGA6k0281.jpg

注意,这个时候服务器端的ssh配置,是修改了ssh连接的端口和禁止使用密码登录,还未禁止root登陆,所以截图中看到登录的用户还是root,因为前面做的公钥是注入到了root账户的.ssh目录下的authorized_keys文件中了,如果要使用普通用户登录,需要将生成的公钥信息注入到对应的用户家目录下的authorized_keys文件中,按下回车之后我们就可以登录到服务器端了:

wKioL1SjitDwxDFqAAD0XXQm__4374.jpg

现在客户端的公钥都已经导入到服务器端了,这个时候可以将ssh的配置全部调整到我们需要的状态,比如禁用root登录,不允许使用密码登录等,修改端口等等,要记得将生成的公钥信息注入到我们希望使用的用户的家目录下authorized_keys文件中。

# useradd fedora
# passwd fedora
# cat id_rsa_1024.pub >> /home/fedora/.ssh/authorized_keys

现在用Xshell连接服务器,其效果如下:

wKioL1Sji9bxunZEAAFMpzXLIq4789.jpg

wKiom1Sji0GhDrHwAAFKX-4snMo359.jpg

wKiom1Sji1qhMKp6AAI9VcjPzpo914.jpg

至此,直接回车就可以登录到远程服务器了,而且是使用的普通用户身份登录。

wKioL1SjjEXibAXYAAD8M4WAqM4710.jpg

写了很多SSH安全的设置以及如何使用公钥来登录服务器,现在回到主题,来配置我们要用的DenyHosts以进一步增强我们的服务器的安全,(现在假设使用DenyHosts的前提是允许使用密码登录,ssh配置文件中未禁用密码登录)。

1、下载DenyHosts,项目官方站点:http://denyhosts.sourceforge.net/

2、安装DenyHosts

# tar xf DenyHosts-2.6.tar.gz
# cd DenyHosts-2.6
# python setup.py install

安装过程输出的信息中显示DenyHosts程序安装的路径是/usr/share/denyhosts目录下。

3、配置DenyHosts,为程序提供配置文件以及服务启动的脚本

# cd /usr/share/denyhosts
# cp denyhosts.cfg-dist denyhosts.cfg
# cp daemon-control-dist /etc/rc.d/init.d/denyhosts
# chkconfig --add denyhosts
# chkconfig denyhosts on
# vim denyhosts.cfg

配置文件中需要注意的配置参数说明:

SECURE_LOG = /var/log/secure

DenyHosts支持不同的操作系统,而不同的系统使用的登录日志文件不同,这个指令就是用来指定当前系统要使用的登录日志文件的。

HOSTS_DENY = /etc/hosts.deny

用来指定当有远程主机尝试暴力破解当前服务器密码时,将其IP地址写入/etc/hosts.deny文件中以实现禁止对方登录的目的,保证服务器的安全。

PURGE_DENY =

这个选项是用来删除/etc/hosts.deny文件中记录的条目的,不过其生效的时间要依赖于配置文件中后面的DAEMON_PURGE选项,因为PURGE_DENY选项清除的条目是DenyHosts标记为过期的条目,如果条目没有过期,即使PURGE_DENY设定的时间到了也不会清除,而DAEMON_PURGE是用来设定条目过期的时间的,所以PURGE_DENY是在DAEMON_PURGE设定的时间到达之后再根据其定义的时间点,如果条目到达了应该清除的时间,条目才会被清除,如果DAEMON_PURGE设定的时间很长,那么就意味着条目过期的时间很长,等到了过期的时间,再加上PURGE_DENY的时间之后,对应的条目才会在hosts.deny文件中删除。建议这个选项设置的时间稍微短一些,可以很快的看到过期的数据被清除的效果,比如设置为PURGE_DENY = 1m

BLOCK_SERVICE  = sshd

DenyHosts默认阻止的服务为sshd,可以添加其他的服务。

DENY_THRESHOLD_INVALID = 5
DENY_THRESHOLD_VALID = 10
DENY_THRESHOLD_ROOT = 1
DENY_THRESHOLD_RESTRICTED = 1

 默认允许的账户连接尝试的次数,可以根据需要调整数值,第四条设置的是对应的文件WORK_DIR/restricted-usernames中定义的用户允许的尝试次数,这些条目比较容易理解。

HOSTNAME_LOOKUP=YES

反解尝试登陆的IP地址对应的主机名称,在用于报告信息时会使用对应的主机名来显示,而不是IP地址,建议设置为NO。

ADMIN_EMAIL =

设置管理员邮件地址。

AGE_RESET_VALID=5d
AGE_RESET_ROOT=25d
AGE_RESET_RESTRICTED=25d
AGE_RESET_INVALID=10d

这几个条目是用来设置登陆失败次数的计数器归零时间的,如果一个主机尝试登陆多次,会被计数器记录失败登陆的次数,这几个条目设定的时间用于将这些技术清零。但这几个条目设置的时间长短于用户能否在短时间内再次登陆没有关系,可以不用改动,允许被封的IP重新登陆的条目取决于PURGE_DENY与DAEMON_PURGE两个选项的设置。

DAEMON_SLEEP = 30s

这个参数选项的设置是用来设定DenyHosts每隔多久去读取/var/log/secure文件以获取用户登录次数信息的,这个参数很重要,可以根据需要修改,默认是30s,即如果一个主机连续多次登录失败后,超出设定的尝试次数,那么会在30s之后无法再次连接。

DAEMON_PURGE = 1h

这个选项用来配置DENY_PURGE使用,其用途是用来标记hosts.deny文件中的条目的过期时间的,过期之后再根据PURGE_DENY选项设定的时间来清除过期的条目,这个条目可以根据需要来修改,默认是1小时,即1小时候被封的IP在hosts.deny文件中的条目会被标记为过期。

其他的选项可以根据需要调整,不过调整的话,上面的条目设定已经能满足我们的应用需要了。

启动DenyHosts服务:

# service denyhosts start

模拟使用账号密码的方式来登录,即使对方使用了正确的端口,使用了系统中存在的账号,如果输入错误达到设置的值,默认会被禁止登陆1小时,1小时之后才可以再次尝试登录,DenyHosts配合ssh的安全策略可以更好的保护服务器系统的安全。

wKioL1SjmgCzeDGJAAB_HHfCg2A377.jpg

注:DenyHost很轻量级,对系统的资源占用率很低,支持以守护进程的方式运行,也支持使用任务计划的方式运行,这样消耗的系统资源更低,而且DenyHosts会在启动时检查sshd log文件大小的变化来判断身份有新的登录数据,如果这个文件大小一直不发生变化,它不会做任何处理而自动退出,而且检查文件变化时也只处理改变的数据部分。设置周期性任务计划可以使用下面的方式,例如:

*/10 * * * * /usr/bin/env python /usr/bin/denyhosts.py --daemon --config=/usr/share/denyhosts/denyhosts.cfg