2011-01-19 86 views
8

我的问题很简单。Apache htpasswd安全密码更改

如何允许用户更改他们的密码存储在linux的一些htpasswd文件中而不泄露文件内容或允许用户修改其他密码?

我试图编写一个脚本来使用ssh和specialy设计的用户来完成那项工作,但它现在已经成为现实。

请帮忙。 我正在使用Debian服务器“Lenny”。

+0

你确定要坚持htpasswd吗? Apache中的mod_auth可以使用其他后端,LDAP数据库(mod_authnz_ldap),SQL数据库(mod_authn_dbd)等。 – regilero 2011-01-19 23:34:56

回答

16

Apache htpasswd文件不支持任何影子功能。因此,您必须防止用户访问您的Web服务器,以使其远离密码文件。所以唯一的解决方案是基于SSH的方法或任何其他远程解决方案。下面的描述将解释如何编写一个SSH命令脚本来改变密码,只有当用户知道他的旧密码。主要的问题是,Apache不提供一个命令行工具来验证htpasswd文件中的密码。但这可以通过手工完成。

以下描述假定网络服务器用户为www-data,并且用户的主目录为/var/www

首先,你必须创建一个htpasswd的文件,这是由Web服务器用户可写的:

# ls -la .htpasswd 
-rw-r--r-- 1 www-data root 18 10. Mai 16:30 .htpasswd 

然后,你必须把所有的用户的密钥添加到authorized_keys文件的Web服务器的用户。您必须在每行前加上command选项。

# cat .ssh/authorized_keys 
command="/var/www/.htpasswd.sh" ssh-rsa AAAA... [email protected] 

只要用户用他的钥匙只有.htpasswd.sh被执行连接。用户没有任何对Web服务器的shell访问权限。

这是更改密码的脚本:

#! /bin/bash 

HTPASSWD=/var/www/.htpasswd 

die() { echo "$*" >&2 ; exit 1 ; } 

read -p 'Enter user name: ' USER 
read -s -p 'Old password: ' OLDPW ; echo 
read -s -p 'New password: ' NEWPW0 ; echo 
read -s -p 'Re-type new password: ' NEWPW1 ; echo 

if LINE=$(grep ^"$USER": "$HTPASSWD") 
then 
    echo "$LINE" | sed 's/.*:\(..\)\(.\+\)/\1 \2/' | { 
     read SALT CRYPT 
     if [[ "$SALT$CRYPT" = $(echo "$OLDPW" | mkpasswd -sS "$SALT") ]] ; then 
      if [ "$NEWPW0" != "$NEWPW1" ] ; then 
       die "Password verification error!" 
      fi 
      PWS=$(grep -v ^"$USER:" "$HTPASSWD") 
      { 
       echo "$PWS" 
       echo -n "$USER:" 
       echo "$NEWPW0" | mkpasswd -s 
      } > "$HTPASSWD" 
      echo "Updating password for user $USER." 
     else 
      die "Password verification error!" 
     fi 
    } 
else 
    die "Password verification error!" 
fi 

棘手的部分是密码验证。它是通过阅读旧盐并用旧盐加密旧密码来完成的。将结果与htpasswd文件中的旧加密密码进行比较。

现在,用户可以连接到Web服务器以更改密码:

$ ssh [email protected] 
Enter user name: szi 
Old password: 
New password: 
Re-type new password: 
Updating password for user szi. 
Connection to localhost closed. 

大家只能更改自己的密码,没有人可以访问其他用户的加密密码。此解决方案在shell脚本中使用原始htpasswd程序具有额外的好处,因为密码永远不会用作命令行参数。这对于htpasswd来说是不可能的,因为它不能从stdin中读取密码,如mkpasswd