管理每台服务器的信任关系

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

#!/usr/bin/env perl -w 
#Description: This script is for looking up,adding,deleting user certification tool !
#Date:2011/8/29
#Hostgroup is defined by yourself !
#Version : 1.1
#####################################################################################

#use warnings;
use diagnostics;
use strict;
use Net::OpenSSH;
use Getopt::Long;
use vars qw($host $show $add $del $name $group $all $cert $role $cmd_line);

my $std;
my $user = 'root';
my $cmd_locate_II = "ls `cat /etc/passwd| grep -v 'nologin'| grep -v 'false' | awk -F: '{print \$6\"/.ssh/authorized_keys\"}'` 2>/dev/null";
my @ip_hash;
my @path;
my $tmp = 0;
my $count = 0;
my ($flag_s, $flag_a, $flag_d, $flag_c);

GetOptions (
	'host=s' => \$host,
	'show!' => \$show,
	'add!' => \$add,
	'del!' => \$del,
	'index=s' => \$name,
	'all!' => \$all,
	'group=s' => \$group,
	'cert!' => \$cert,
	'role=s' => \$role,
	'cmd!' => \$cmd_line,
);

my %param = (
		user => $user,
		timeout => 30
);

###########Hostgroup##############
my %hostgroup=(
		'xxx' => "xxx xxx xxx", #ip地址
);

#[Main]#
##################Show##################
if($show and not defined($add) and not defined($del) and not defined($cmd_line)){
	if($host and not defined($name) and not defined($group) and not defined($all) and not defined($role)){
		&sShow($host, $cmd_locate_II);
		print "\n\t \t \t*******Done !*******\n\n";
	}
	
	if($host and $name and not defined($group) and not defined($all) and not defined($role)){
		&mShow($host,$cmd_locate_II);
		print "\n\t \t \t*******Done !*******\n\n";
	}

	if($group and not defined($name) and not defined($all) and not defined($host) and not defined($role)){
		@ip_hash=split / /,$hostgroup{$group};
		foreach my $ip(@ip_hash){
			&sShow($ip, $cmd_locate_II);
		}
		print "\n\t \t \t*******Done !*******\n\n";		
	}
	
	if($name and $group and not defined($all) and not defined($host) and not defined($role)){
		@ip_hash=split / /,$hostgroup{$group};
		print"\t \t[---------------Certification $name in $group platform :--------------\n";
		foreach my $ip(@ip_hash){
			&mShow($ip, $cmd_locate_II);
			$count = 0;
		}
	print "\n\t \t \t*******Done !*******\n\n";
	}

	if($name and $all and not defined($host) and not defined($group) and not defined($role)){
		my @tmp_ip=&ipLoop;
		foreach my $ip(@tmp_ip){
			&mShow($ip, $cmd_locate_II);
			$count = 0;
		}
	print "\n\t \t \t*******Done !*******\n\n";
	}

	if($all and not defined($name) and not defined($group) and not defined($host) and not defined($role)){
		my @tmp_ip = &ipLoop;
		foreach(@tmp_ip){
			&sShow($_, $cmd_locate_II);		
		}
		print "\n\t \t \t*******Done !*******\n\n";
	}

	if($host and $role and $name and not defined($all) and not defined($group)){
		print "\t \t[-------------------<<[$host]>>------------------]\n";
		&roleSSH($host, $role);
		print "\n\t \t \t*******Done !*******\n\n";
	}
	
	if($group and $role and $name and not defined($all) and not defined($host)){
		@ip_hash = split / /,$hostgroup{$group};
		foreach(@ip_hash){
			print "\t \t[------------------<<[$_]>>------------------]\n";
			&roleSSH($_,$role);
		}
		print "\n\t \t \t*******Done !*******\n\n";
	}	
 
	if($all and $role and not defined($group) and not defined($host) and $name){
		my @tmp_ip = &ipLoop;
		foreach(@tmp_ip){
			print "[-----------------<<[$_]>>------------------]\n";
			&roleSSH($_,$role);
		}
		print "\n\t \t \t*******Done !*******\n\n";
	}

	if($host and $role and not defined($name) and not defined($all) and not defined($group)){
		print "\t \t[-------------------<<[$host]>>------------------]\n";
		&roleSSH($host, $role);
		print "\n\t \t \t*******Done !*******\n\n";
	}
	
	if($group and $role and not defined($name) and not defined($all) and not defined($host)){
		@ip_hash = split / /,$hostgroup{$group};
		foreach(@ip_hash){
			print "\t \t[------------------<<[$_]>>------------------]\n";
			&roleSSH($_,$role);
		}
		print "\n\t \t \t*******Done !*******\n\n";
	}	
 
	if($all and $role and not defined($group) and not defined($host) and not defined($name)){
		my @tmp_ip = &ipLoop;
		foreach(@tmp_ip){
			print "[-----------------<<[$_]>>------------------]\n";
			&roleSSH($_,$role);
		}
		print "\n\t \t \t*******Done !*******\n\n";
	}
}elsif(not defined($add) and not defined($del) and not defined($cmd_line)){ 
	$flag_s = 's';
	&Usage if $flag_s eq 's';
}

##################Add#####################

if($add and not defined($del) and not defined($cmd_line) and not defined($show)){
	if($host and $role and not defined($group) and not defined($all)){
		print "Please enter your certification : ";
		my $id_rsa = <STDIN>;
		chomp($id_rsa);
		&sConsole;
		&sAdd($host, $cmd_locate_II,$id_rsa);
		print "\n\t \t \t \t*******Done!*******\n\n";
	}
	
	if($all and $role and not defined($host) and not defined($group)){
		my @tmp_ip = &ipLoop;
		print "Please enter your certification : ";
		my $id_rsa = <STDIN>;
		chomp($id_rsa);
		&sConsole;
		foreach my $ip(@tmp_ip){
			$std=&SSH($ip, $cmd_locate_II);
			@path=split /\n/,$std;
			my @cus_path = grep /$role/, @path;
			foreach my $p(@path){
				if($cus_path[0] eq $p){
					my $cmd_echo = "echo '$id_rsa' >> $p && echo '\t \t \t \t*******<'$ip'><'$p'> successful! *******'";
					$std = &SSH($ip,$cmd_echo);
					print "$std";
				}
			}
		}
	print "\n\t \t \t \t*******Done !*******\n\n";	
	}

	if($group and $role and not defined($host) and not defined($all)){
		print "Please enter your certification : ";
		my $id_rsa = <STDIN>;
		chomp($id_rsa);
		&sConsole;
		@ip_hash=split / /,$hostgroup{$group};
		foreach (@ip_hash){
			&sAdd($_, $cmd_locate_II, $id_rsa);
		}
	print "\n\t \t \t \t*******Done !*******\n\n";
	}
}elsif(not defined($show) and not defined($del) and not defined($cmd_line)){
	$flag_a = 'a';
	&Usage if $flag_a eq 'a' and $flag_s ne 's';
}

#######################Del###########################

if($del and not defined($show) and not defined($add) and not defined($cmd_line)){
	if($host and $role and $name and not defined($group) and not defined($all)){
		&sConsole;
		&sDel($host, $cmd_locate_II);
		print "\n\t \t \t \t*******Done !*******\n\n";
	}

	if($group and $name and $role and not defined($host) and not defined($all)){
		@ip_hash = split / /,$hostgroup{$group};
		&sConsole;
		foreach(@ip_hash){
			&sDel($_, $cmd_locate_II);
			print "\n\t \t \t \t*******Done !*******\n\n";
		}
	}

	if($all and $name and $role and not defined($host) and not defined($group)){
		my @tmp_ip = &ipLoop;
		&sConsole;
		foreach my $ip(@tmp_ip){
			$std=&SSH($ip, $cmd_locate_II);
			@path=split /\n/,$std;
			my @cus_path = grep /$role/, @path;
			foreach my $p(@path){
				if($cus_path[0] eq $p){
					my $cmd_del = "sed -i '/$name/d' $p && echo '\t \t \t \t*******<$ip>successful!*******'";
					$std = &SSH($ip,$cmd_del);
					print "$std";
				}
			}
		}
	print "\n\t \t \t \t*******Done !*******\n\n";	
	}
}elsif(not defined($show) and not defined($add) and not defined($cmd_line)){
	$flag_d = 'd';
	&Usage if $flag_s ne 's' and $flag_a ne 'a' and $flag_d eq 'd';
}

if($cmd_line and not defined($add) and not defined($show) and not defined($del)){
  if($host and not defined($group) and not defined($all)){
    print "Please input your command : ";
    my $icmd = <STDIN>;
    chomp($icmd);
    &sCmd($host, $icmd);
    print "\n \t \t \t \t******* Done ! *******\n\n";
  }

  if($group and not defined($host) and not defined($all)){
    print "Please input your command : ";
    my $icmd = <STDIN>;
    chomp($icmd);
    @ip_hash = split / /, $hostgroup{$group};
    foreach(@ip_hash){
      &sCmd($_, $icmd);
    }
    print "\n \t \t \t \t******* Done ! *******\n\n";
  }

  if($all and not defined($group) and not defined($host)){
    print "Please input your command : ";
    my $icmd = <STDIN>;
    chomp($icmd);
    &sCmd($host, $icmd);
    my @tmp_ip = &ipLoop;
    foreach (@tmp_ip){
      &sCmd($_, $icmd);
    }
    print "\n\t \t \t \t******* Done ! *******\n\n";
  }
}elsif(not defined($show) and not defined($add) and not defined($del)){
    $flag_c = 'c';
    &Usage if $flag_s ne 's' and $flag_a ne 'a' and $flag_d eq 'd' and $flag_c eq 'c';
}

######FUNCTION#####
###Usage for help###

sub Usage{
	print <<EOF;
	-host <ip> : Input the host ip for searching;
	-group <group name> : Input the groupname for searching;
	-all : Searching the whole hosts ip;
	-show : Display the host which have specified certifications;
	-del : Delete a name you choose for the host which have specified certifications with [-all && -dirpath|-group|-host];
	-add : Add a name you choose for the host which have specified certifications with [-all && -dirpath|-group|-host]; 
	-dirpath <pathname> : Input a path;
	-index <name> : Input searching index;
	-cert : Display whole certification;
	-role : Display specified user role;
	-cmd : useradd userdel groupadd groupdel are permitted !
	example:
		If you want to show a single host which has certification: 
				certmgr -host [ip] -show [-role] <rolename> [-cert]
		If you want to show whole host which have spicified certifications:
				certmgr -all -show -index <name> [-role] <rolename>
		If you want to show hostgroup which have spicified certifications:
				certmgr -show -group <groupname> -index <name>  [-role] <rolename>
		If you want to show hostgroup all certifications:
				certmgr -show -all [-cert]
		If you want to add a certification on a host:
				certmgr -add -host <ip> 
		If you want to add a certification on the whole hostgroup:
				certmgr -add -all -role <rolename>
		If you want to add a certification on a hostgroup:
				certmgr -add -group <groupname> -dirpath <dirpath>
		If you want to delelte a specified certification on a host:
				certmgr -del -host -index <name>
		If you want to delelte a specified certification on a hostgroup:
				certmgr -del -group <groupname> -index <name>
		If you want to add a specified certification on the whole hostgroup:
				certmgr -del -all -index <name> -role <rolename>
		If you want to input a cmd in a host or hostgroup which you chose:
				certmgr -host [-all | -group <groupname>] <hostname> -cmd 
				cmd no accept special symbol !
EOF
	exit;
}

sub SSH{
	 my $ssh = Net::OpenSSH->new($_[0],%param);
 	 my ($stdout,$stderr) = $ssh->capture2($_[1]);
 	 if($stdout){
 			return $stdout;
   }else{
      print $ssh->error;
      $stderr and return $stderr;
    }
}

sub ipLoop{
	my @all_ip;
	foreach(values(%hostgroup)){
		my @split_ip = split / /,$_;
		foreach(@split_ip){
			push @all_ip,$_; 
		}
	}
return @all_ip;
}

sub roleCheck{
	if(/^\/root/){
		print "\n\t\tRole : root\n\n";
	}elsif(/^\/\w+\/(\w+)\//){
		print "\n\t\tRole : $1\n\n";
	}
}

sub roleSSH{
	my ($ip_role,$r_path) = @_;
	my $cmd_role = "cat /etc/passwd | grep '$r_path' | awk -F: '{print \$6}'";
	$std = &SSH($ip_role,$cmd_role);
	$std =~ s/\s+/\/\.ssh\/authorized_keys/ if $std;
	if($std){
		my $cmd_cat_role = $name ? "cat -n $std | grep $name" : "cat -n $std";
		$std = &SSH($ip_role,$cmd_cat_role);
		print "$std" if $std;
	}else{
		print "\n\t \t \tNo such user role !\n\n";
	}
}

sub sShow{
	my ($ip_role,$cmd) = @_;
	$std = &SSH($ip_role,$cmd);
	chomp($std);
	@path = split /\n/,$std;
	print "<[--------------[$ip_role] has this certifications :-------------]>\n";
	foreach my $p(@path){
		my $cmd_show = $cert ? "cat -n $p" : "cat -n $p |awk '{print \"\t\t\" \$1 \"  \"\$4}'|cut -d'\@' -f1";
		$std = &SSH($ip_role,$cmd_show);
		print "\n\t[This Path : {$p} ]\n" if $std;
		print "$std";
	}
	@path = ();
}

sub mShow{
	my ($ip_role,$cmd) = @_;
	$std=&SSH($ip_role, $cmd);
	chomp($std);
	@path = split /\n/,$std;
	print "\t \t<[------------------<<[$ip_role]>>-----------------]>\n";
	foreach my $p(@path){
		my $cmd_search_name = "cat -n $p | grep $name | awk '{a++} END {print a}'";
		$std = &SSH($ip_role, $cmd_search_name);
		$tmp = $std and print"\n\t[$p] >>> cetification times: $tmp" if $std and $std ne "\n";
		$_ = $p and &roleCheck($_) if $std ne "\n";
		$count = $count+$tmp;
		$tmp = 0;
	}
	print "\n\t\tTotal times : $count\n\n";
}

sub sAdd{
	my ($ip_role,$cmd,$rsa) = @_;
	$std = &SSH($ip_role,$cmd);
	@path = split /\n/,$std;
	my @cus_path = grep /$role/, @path;
	my $cmd_echo = "echo '$rsa' >> @cus_path && echo '\t \t \t \t*******[$ip_role] successful!*******'";
	$std = &SSH($ip_role,$cmd_echo);
	print "$std";
	print "\n";
}

sub sDel{
	my ($ip_role,$cmd) = @_;
	$std = &SSH($ip_role,$cmd);
	my @path = split /\n/,$std;
	my @cus_path = grep /$role/, @path;
	my $cmd_del = "sed -i '/$name/d' @cus_path && echo '\t \t \t \t*******[$ip_role] successful!*******'";
	$std = &SSH($ip_role,$cmd_del);
	print "$std";
	print "\n";
}

sub sCmd{
	my ($ip_role, $cmd) = @_;
	if(defined($cmd)){
		if($cmd =~ m/useradd/){
			my $uname = $cmd;
			$uname =~ s/.*\s(\w+)$/$1/;
			$uname =~ s/(\w*)/\/home\/$1\/.ssh/;
			if(-d $uname){
				print "The directory already exits !\n";
				exit;
			}else{
				$cmd =~ s/$/&&mkdir -p $uname&&touch $uname\/authorized_keys&&echo "Successful"/;
				$std = &SSH($ip_role, $cmd);
				print "\n\t\t\t\t$std \n";
			}
		}elsif($cmd =~ m/userdel/){
			$cmd =~ s/$/&&echo "Successful"/;
			$std = &SSH($ip_role, $cmd);
			print "\n\t\t\t\t$std \n";
		}elsif($cmd =~ m/groupadd/){
			$cmd =~ s/$/&&echo "Successful"/;
			$std = &SSH($ip_role, $cmd);
			print "\n\t\t\t\t$std \n";
		}elsif($cmd =~ m/groupdel/){
			$cmd =~ s/$/&&echo "Successful"/;
			$std = &SSH($ip_role, $cmd);
			print "\n\t\t\t\t$std \n";
		}else{
			print "Sorry these [useradd | userdel | groupadd | groupdel] are permitted !\n";
			exit;
		}
	}else{
		exit;
	}
}

sub sConsole{
	print "Are you sure ? [yes|no]: ";
	my $input = <STDIN>;
	chomp($input);
	if($input eq 'yes'){
		print "\n\t\t\t\tOK ! Starting !\n\n";
	}else{
		exit;
	}
}
###END###