使用perl的expect在禁止root登陆的情况下批量修改root密码

前端之家收集整理的这篇文章主要介绍了使用perl的expect在禁止root登陆的情况下批量修改root密码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

   由于安全策略的限制,公司所有的linux服务器都设置了sshd_config中的PermitRootLogin no来禁止root用户直接登陆,但同时又由于安全需要,需要定期修改root密码,于是问题来了。在root无法登陆的情况下只能由普通用户登陆后su - 到root然后执行密码修改。于是我想到了如下方案:

   for i in `cat server_list`

       do ssh user1@$i "su -c 'echo \"newpasswd\" |passwd root --stdin'"

   done

但运行提示standard in must be a tty,通过搜索发现su 所需要标准输入的无法通过管道来获取,必须通过tty及终端。我们有数百台服务器需要这样的操作,每台手工登陆然后切换用户反复输入密码显然不可取。于是我想到了expect,网络上的关于expect的文档相当很少,而且由于这里需要输入两次密码(一次普通用户密码,一次跳转到目标服务器后输入的root用户密码),我尝试了多种expect脚本似乎都很难实现,expect会由于当前shell环境跳转到目标服务器而陷入等待,而设置的timeout值是在当前服务器上似乎无法生效。于是我想到了perl的expect模块,脚本如下。

使用方法:for i in `cat server_list`;do ./expect_login.pl -h $i;done


#!/usr/bin/perl -w
# Author: Ken Zhang @2013-12-29

# Filename: expect_login.pluse Getopt::Std;use vars qw/%opt/;use Expect;sub init(){        my $opt_string="u:h:p:";        getopts("$opt_string",\%opt) or usage();        #usage() if @ARGV==0;        }sub usage(){        print STDERR << "EOF"        usage: $0 [-u username] [-p password] [-h hostname]        example: $0 -u root -p password -h localhost.localdomainEOF        }sub connect(){        my $password = 'ken.zhang@2014';        my $username = 'ken.zhang';        my $hostname = 'localhost';        my $port='22';        $password = $opt{p} if $opt{p};        $username = $opt{u} if $opt{u};        $hostname = $opt{h} if $opt{h};        my $rootpass='RootP@aaA';   # default password for all servers.        $newrootpass='new_non-prod_password' if $hostname =~ /^b/i;    #new root password for non-prod servers        $newrootpass='new_prod_root_password' if $hostname =~ /^a|prd/i; #new root password for prod servers,server name start with 'a' or contains 'prd'        my $cmd="ssh";        my @params=($hostname,'-l'.$username,'-p'.$port);        $ENV{TERM} = "xterm";        my $exp = Expect->new;        $exp = Expect->spawn($cmd,@params);        $exp->log_file("output$$.log","w");# enable debug information if uncomment below       #$exp->exp_internal(1);# disable output to stdout if uncomment below. all outputs will go to logfile "output$$.log"#       $exp->log_stdout(1);        $exp->expect(5,       [qr/password/i => sub {my $self=shift; $self->send("$password\n");} ],       [qr/\(yes\/no\)\?/,sub {my $self=shift; $self->send("yes\n");exp_continue} ]                );        $exp->expect(5,'$');        $exp->send("su -c \"echo $newrootpass|passwd root --stdin\"\n");        $exp->expect(5,'[Pp]assword:');        $exp->send("$rootpass\n");        $exp->send("exit\n") if($exp->expect(5,'$'));        }&init();&connect();

猜你在找的Perl相关文章