PAM
为了提高安全性,想在VPS上实现封禁登录失败用户的功能。这种常见问题网上一搜就有,但是nixCraft上的这篇教程有我在后面两条评论中说的问题,pam_tally.so要在其它auth语句前才有效,其次不支持ssh。
其实在CentOS 5.5上是支持ssh登录的封禁的,而在我的VPS(AWS EC2)上不支持。经研究原因如下。教程修改的是/etc/pam.d/system-auth文件,在CentOS 5.5上/etc/pam.d/sshd内容如下:
#%PAM-1.0
auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
session optional pam_keyinit.so force revoke
session include system-auth
session required pam_loginuid.so
auth用的是system-auth文件,所以改了system-auth后sshd也用到了pam_tally。
而AWS EC2上sshd内容如下:
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
session include password-auth
这里用的是password-auth,所以改system-auth自然无效了。
AWS EC2上需要在password-auth文件(前提是sshd文件include了password-auth)里面加入:
auth required pam_tally2.so onerr=fail deny=5 unlock_time=60
account required pam_tally2.so
这两条要分别放在其它auth和account的前面,以确保其生效。
如果只有auth一句,那么pam_tally2会记录登录失败,但是不会在超时且用户登录成功后情况计数器。account一条是为了在过了unlock_time且用户登录成功后清空计数器,这是必须要的。
此外,在/etc/ssh/sshd_config中,要有以下设置
PasswordAuthentication yes
UsePam Yes
ChallengeResponseAuthentication yes
sshd_config里面有这样的话(对UsePAM):
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
所以为了安全其见,最好有:
PermitRootLogin no
以禁止Root从ssh登录。
在CentOS 5.5上用的pam_tally.so,ChallengeResponseAuthentication是no,而且也不需要account行,pam_tally.so可以正常记录和封禁。后来研究发现这是不可靠的,时而工作时而不工作。要可靠地记录失败登录和可靠地清空计数器,必须要把ChallengeResponseAuthentication设置为yes,且必须有account行才能清空计数器。
另外发现一点有趣的东西。ChallengeResponseAuthentication设置为yes和no,sshd的PasswordAuthentication的提示符会不同:
$ ssh test@centos
Password:
Password:
Password:
test@centos's password:
Permission denied, please try again.
test@centos's password:
Received disconnect from 192.168.2.18: 2: Too many authentication failures for test
前3行Password是PAM auth的提示符,这3次失败都被pam_tally记录了。后面两个test@centos's password:是sshd的提示符,这两次失败在我的设置下是不会被pam_tally记录的。这也应证了要让pam_tally可靠工作,ChallengeResponseAuthentication要设置为yes。
如果给ssh加上-v参数,就能看到是keyboard-interactive认证(即ChallengeResponseAuthentication)失败后,尝试password认证的原因。把sshd_config里面的PasswordAuthentication设置为no就只有PAM认证的提示符了。
在一台电脑上公钥移除,然后脚本自动尝试密码登录,多次输错密码后账户被禁用。但是在另一台电脑上,竟然用另一个公钥登录进去了。然后用pam_tally2命令把计数器(30次失败呢)复位掉。不知为啥竟然能登录?