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次失败呢)复位掉。不知为啥竟然能登录?