通过ssh在linux服务器上更改密码的脚本

时间:2011-11-23 02:40:16

标签: linux shell ssh passwords

我们的IT环境中有许多Red Hat Linux服务器。我的团队成员要求我编写一个脚本(最好是shell脚本),使用SSH在一次访问中更改每个用户的密码。

我试图找到一个解决方案,但我找到的很多脚本都在使用Expect。我们的服务器上没有安装Expect,系统管理员拒绝让我们安装它。此外,用户没有超级用户访问权限,因此无法使用passwd --stdinchpasswd

是否可以编写脚本以便用户可以在列表中的所有服务器上运行它并仅更改自己用户的密码?

17 个答案:

答案 0 :(得分:21)

远程机器不需要安装。您可以在本地工作站或VM(虚拟盒)或任何* nix框上安装expect,并编写一个调用此.ex(expect)脚本的包装器(从发行版到发行版可能会有一些小变化,这在CentOS 5/6上进行了测试):

#!/usr/bin/expect -f
# wrapper to make passwd(1) be non-interactive
# username is passed as 1st arg, passwd as 2nd

set username [lindex $argv 0]
set password [lindex $argv 1]
set serverid [lindex $argv 2]
set newpassword [lindex $argv 3]

spawn ssh $serverid passwd
expect "assword:"
send "$password\r"
expect "UNIX password:"
send "$password\r"
expect "password:"
send "$newpassword\r"
expect "password:"
send "$newpassword\r"
expect eof

答案 1 :(得分:12)

您无需root权限即可使用passwd

这应该可以正常工作。

passwd <<EOF
old password
new password
new password
EOF

答案 2 :(得分:10)

您应该尝试pssh(同时并行ssh)。

cat>~/ssh-hosts<<EOF
user100@host-foo
user200@host-bar
user848@host-qux
EOF

pssh -h ~/pssh-hosts 'printf "%s\n" old_pass new_pass new_pass | passwd'

答案 3 :(得分:6)

以squashbuff为例,我尝试了以下方法,这对我很有用:

#!/bin/bash
for server in `cat hostlist`; do
echo $server;
ssh username@$server 'passwd <<EOF
old_password
new_password
new_password
EOF';
done

安全方面,可以改进输入而不回显到屏幕或将明文保存到磁盘。

答案 4 :(得分:4)

echo "name:password" | chpasswd

答案 5 :(得分:3)

另一种可能性:在一台服务器上手动更改它。从/ etc / shadow中获取加密密码。现在,做这样的事情:

for host in $HOST_LIST; do
    ssh $host "passwd -p 'encrypted_passwd' user"
done

当然,'encrypted_pa​​sswd'是您从/ etc / shadow中手动更改密码的地方。$ HOST_LIST是您希望密码更改的主机列表。可以使用以下命令创建:

export HOST_LIST="server1 server2 server15 server67"

或者使用文件(正如其他人建议的那样):

export HOST_LIST=`cat host_list.txt`

文件“host_list.txt”包含您希望更改密码的所有系统的列表。

编辑:如果您的passwd版本不支持-p选项,则可能有'usermod'程序可用。上面的示例保持不变,只需将'passwd'替换为'usermod'。

此外,您可以考虑useful tool pdsh,这会将上述示例简化为以下内容:

echo $HOST_LIST | pdsh -Rssh -w- "usermod -p 'encrypted_passwd' user"

要注意的最后一个“问题”:加密密码可能包含美元符号字符('$')作为字段分隔符。你可能不得不在你的for循环或pdsh命令中逃脱那些(即“$”变为“\ $”)。

答案 6 :(得分:2)

  1. 在要执行脚本的任何服务器上安装sshpass

    yum -y install sshpass
    
  2. 准备一个文本文件,您必须在其中传递主机用户名密码端口等详细信息。 (根据您的要求)。

    192.168.1.2|sachin|dddddd|22
    
  3. 使用以下详细信息准备脚本文件。

    #!/bin/bash
    
    FILE=/tmp/ipaddress.txt
    
    MyServer=""
    MyUser=""
    MyPassword=""
    MyPort=""
    
    exec 3<&0
    exec 0<$FILE
    
    while read line
    do
        MyServer=$(echo $line | cut -d'|' -f1)
        MyUser=$(echo $line | cut -d'|' -f2)
        MyPassword=$(echo $line | cut -d'|' -f3)
        MyPort=$(echo $line | cut -d'|' -f4)
    
        HOST=$MyServer
        USR=$MyUser
        PASS=$MyPassword
    
        sshpass -p $PASS ssh -p $MyPort -o StrictHostKeychecking=no $USR@$HOST \
                -T "echo 'sachin@patel' | passwd --stdin root"                 \
                < /dev/null | tee -a output.log
    done
    
    exec 0<&3
    

答案 7 :(得分:1)

您可能希望向同行提供的替代方案是让他们使用无密码身份验证。他们生成一个公钥/私钥对,并在他们登录的每台服务器上的〜/ .ssh / authorized_keys文件中注册他们的公钥。

答案 8 :(得分:1)

我刚刚实现了一个小的tool,它可以一次更改许多用户/主机的密码。它是基于Java的应用程序,因此可以在Windows和Linux上运行。它是免费的,请尽情享受:)

答案 9 :(得分:1)

Expect附带的passmass脚本(man page)并不要求在远程计算机上安装Expect。

答案 10 :(得分:1)

您是否尝试过App::Unix::RPasswd

答案 11 :(得分:1)

你能用Perl吗?

Here有一个脚本可以更改一组主机中的密码。

如果需要在运行脚本的本地计算机上安装一些Perl模块(Net::OpenSSH::ParallelExpect及其依赖项),但在必须更改密码的远程服务器上没有任何内容。

答案 12 :(得分:0)

如果您有ssh,为什么首先要输入密码?将用户的公共ssh密钥推送到他们有权使用的所有服务器并完成它。这也可以让您轻松地授予和撤销所有您想要的访问权限。

在之前的$ dayjob中,我们有数万台服务器,他们有一个数据库,允许工程师在哪些服务器上安装,而ssh密钥的安装是一个自动化过程。几乎NOBODY在任何机器上都有密码。

答案 13 :(得分:0)

我想我应该把我的解决方案放在答案字段中 - 不确定这是否应该成为问题的一部分..

好的,我已经使用Dennis的建议整理了部分工作的解决方案。

servers.txt看起来像:

server1
server2
server3
.
.
.

我正在使用:

for server in `cat servers.txt`; do
ssh $server -l user 'passwd <<EOF
old_pass
new_pass
new_pass
EOF';
done

这会产生:

user@server1's password: **<Type password manually>**
(current) UNIX password: New UNIX password: Retype new UNIX password: Changing password for user user.
Changing password for user
passwd: all authentication tokens updated successfully.
user@server2's password: **<Type password manually>**
(current) UNIX password: New UNIX password: Retype new UNIX password: Changing password for user user.
Changing password for user
passwd: all authentication tokens updated successfully.

所以在这里,我仍然需要为每个服务器输入一次旧密码。这可以避免吗?

答案 14 :(得分:0)

echo -e“wakka2 \ nwakka2 \ n”| passwd root

答案 15 :(得分:0)

cat /tmp/passwords | ssh $server sudo chpasswd -e

如果密码已加密,或

cat /tmp/passwords | ssh $server sudo chpasswd

如果密码未加密。

/ tmp / passwords的格式应为“user:password”

答案 16 :(得分:-2)

真正的问题是他们为什么不使用某种名称服务? NIS /黄页或LDAP,您无需在一堆服务器上手动更改密码。用户更改密码一次,并在域名主文件中完成。