2011-01-19 84 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