Apache htpasswd 安全密码更改

发布于 2024-10-13 03:29:25 字数 165 浏览 1 评论 0原文

我的问题很简单。

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

我尝试编写一个脚本来使用 ssh 和专门设计的用户来完成这项工作,但它没有成功。

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

My question is simple.

How to allow users to change their passwords stored in some htpasswd file in linux without revealing the files content or allow users to modify other passwords?

I tried to write a script to do that job using ssh and specialy-designed user but it leads noway.

Please help.
I am using Debian server "Lenny".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一梦等七年七年为一梦 2024-10-20 03:29:25

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

以下描述假设 Web 服务器用户为 www-data,用户的主目录为 /var/www

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

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

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

# cat .ssh/authorized_keys 
command="/var/www/.htpasswd.sh" ssh-rsa AAAA... user@host

每当用户使用他的密钥连接时,只会执行 .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 www-data@localhost
Enter user name: szi
Old password: 
New password: 
Re-type new password: 
Updating password for user szi.
Connection to localhost closed.

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

The Apache htpasswd file does not support any shadow functionality. Therefor you have to prevent the users accessing your web server in order to keep them away from the password file. So the only solution is your SSH based approach or any other remote solution. The following description will explain how to write a SSH command script to change the password only if the user knows his old password. The major problem is, that Apache does not provide a command line tool to verify a password in a htpasswd file. But this can be done by hand.

The following description assumes that the web server user is www-data and that the home directory of the user is /var/www.

First you have to create a htpasswd file, that is writable by the web server user:

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

Then you have to add the keys of all your users to the authorized_keys file of the web server user. You have to prefix each line with the command option.

# cat .ssh/authorized_keys 
command="/var/www/.htpasswd.sh" ssh-rsa AAAA... user@host

Whenever a user connects with his key only the .htpasswd.sh gets executed. The users do not have any shell access to the web server.

This is the script to change the password:

#! /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

The tricky part is the password verification. It is done by reading the old salt and encrypting the old password with the old salt. The result is compared with the old encrypted password in the htpasswd file.

Now the user can connect to the web server in order to change the password:

$ ssh www-data@localhost
Enter user name: szi
Old password: 
New password: 
Re-type new password: 
Updating password for user szi.
Connection to localhost closed.

Everybody can change only his own password and nobody has access to the encrypted passwords of the other users. This solution has an additional benefit about using the original htpasswd program in a shell script, because the passwords are never used as a command line argument. This would not be possible with htpasswd, because it can not read the password from stdin like mkpasswd.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文