jericho0702 发表于 2018-8-30 12:52:23

使用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.pl
  use 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 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,
  ,
  
  );
  $exp->expect(5,'$');
  $exp->send("su -c \"echo $newrootpass|passwd root --stdin\"\n");
  $exp->expect(5,'assword:');
  $exp->send("$rootpass\n");
  $exp->send("exit\n") if($exp->expect(5,'$'));
  }
  &init();
  &connect();

页: [1]
查看完整版本: 使用perl的expect在禁止root登陆的情况下批量修改root密码