转 在shell脚本中使用expect实现scp传输问题 以及自动化远程部署
1.安装expect
expect用于shell脚本中自动交互,其是基于tcl编程语言的工具。所以安装expect首先安装tcl。本文中使用的是expect5.45和tcl8.6.6。
安装tcl
[root@tseg0 /]$ mkdir /tools
[root@tseg0 /]$ tar -zxvf tcl8.6.6-src.tar.gz
[root@tseg0 /]$ cd tcl8.6.6/unix/
[root@tseg0 /]$ ./configure
[root@tseg0 /]$ make
[root@tseg0 /]$ make install
- 1
- 2
- 3
- 4
- 5
- 6
安装expect
[root@tseg0 /]$ cd /tools
[root@tseg0 /]$ tar -zxvf expect5.45.tar.gz
[root@tseg0 /]$ cd expect5.45/
[root@tseg0 /]$ ./configure --with-tcl=/usr/local/lib/ --with-tcl include=/tools/tcl8.6.6/generic/
[root@tseg0 /]$ make
[root@tseg0 /]$ make install
- 1
- 2
- 3
- 4
- 5
- 6
shell脚本实现scp传输
命令解释
-c 表示可以在命令行下执行except脚本;
spawn 命令激活一个unix程序来交互,就是在之后要执行的命令;
expect “aaa” 表示程序在等待这个aaa的字符串;
send 向程序发送字符串,expect和send经常是成对出现的,比如当expect“aaa”的时候,send“bbb”。
执行脚本
#! /bin/sh
expect -c "
spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/
expect {
\"*assword\" {set timeout 300; send \"$pass\r\"; exp_continue;}
\"yes/no\" {send \"yes\r\";}
}
expect eof"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
解释:
第二行: -c 表示可以不用与控制台交互;
第三行:spawn激活一个scp的unix程序;
第五行:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串, exp_continue表示执行下面的匹配;
第六航:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串;
第八行:表示结束。
####sample 1:
1.vi 1.sh
#! /bin/sh
export pass=123456
export name=root
expect -c "
spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/
expect {
\"*assword\" {set timeout -1; send \"$pass\r\"; exp_continue;}
\"yes/no\" {send \"yes\r\";}
}
expect eof"
set timeout -1 ------->>>>>>注意此处的-1,-1表示永不超时,也就是:等 scp 命令正常执行完成之后,控制权会转移到下一行。
set timeout 300 ------->>>>>>300表示300秒后超时,在超时之后,控制权会转移到下一行;若在超时时间之内,程序运行完,则控制权也会转移到下一行。
2. nohup sh 1.sh
转自 http://blog.csdn.net/BlockheadLS/article/details/52980797
####sampe 2
感谢https://www.jianshu.com/p/71e9c9a9c31f
shell 脚本sftp 文件下载
#!/bin/bash
sftp_Host="192.168.1.1"
sftp_userName="admin"
sftp_passWord="admin"
sftp_port=22
sftpRemotePath="/data/fiels"
sftpLocalPath="/root/sftp"
current=$(date "+%Y-%m-%d %H:%M:%S")
echo "当前时间是:$current"
if [[ $# == 0 ]]; then
yesterday=$(date "+%Y%m%d" -d "-1 days")
fi
if [[ $# == 1 ]]; then
yesterday=$1
fi
myDir=$sftpLocalPath
if [[ ! -d $myDir ]]; then
mkdir -p $myDir
fi
sftpLoadPath=$sftpRemotePath$yesterday
fileFilter=$yesterday*.gz
# SFTP非交互式操作
sftp_download()
{
expect <<- EOF
set timeout 5
spawn sftp -P $sftp_port $sftp_userName@$sftp_Host
expect {
"(yes/no)?" {send "yes\r"; expect_continue }
"*assword:" {send "$sftp_passWord\r"}
}
expect "sftp>"
send "cd $sftpLoadPath \r"
expect "sftp>"
send "lcd $myDir \r"
expect "sftp>"
set timeout -1
send "mget $fileFilter \r"
expect "sftp>"
send "bye\r"
EOF
}
unGzipFiles(){
cd $myDir
fileList=`ls *`
fileArr=($fileList)
for fileName in ${fileArr[@]}
do
echo "开始解压文件:$fileName"
gzip -d $fileName
done
}
reNameFiles(){
cd $myDir
fileList=`ls *`
fileArr=($fileList)
for fileName in ${fileArr[@]}
do
echo "reNameFile :$fileName"
mv $fileName $fileName".csv"
done
}
echo "执行sftp下载操作 : 数据日期:$yesterday"
sftp_download
echo "$yesterday 文件下载完成"
echo "执行解压操作"
unGzipFiles
echo "重命名文件"
reNameFiles
########感谢AlexYBB
linux expect中的timeout设定
在做日志分析工具时,发现在屏幕上拿到日志结果会有点慢,然后查了一下expect ssh timeout的设置,原来是这里有个默认时间的问题,所以整理一下:
expect脚本我们都知道,首先spawn我们要执行的命令,然后就给出一堆expect的屏幕输出,如果输出match了我们的expect的东西,我们就会send一个命令上去,模拟用户输入。
但是expect中等待命令的输出信息是有一个timeout的设定的,默认是10秒。这个特性是防止那些执行死机的命令的。一旦到了这个timeout,还是没有屏幕输出的话,expect脚本中下面的代码就会执行。或者我们在expect脚本中如果定义了timeout的响应代码的话,这些代码就会被执行。
解决这样的问题非常简单,最简单的办法就是在expect脚本的开头定义:
set timeout -1 -- 没有timeout set timeout XX -- 设定具体的timeout时间(秒)
###sample
感谢吴老师
expect交互式安装软件
公司一些宿主机需要安装软件,吴老师要求写一个安装脚本;
脚本思路:首先要把安装的包拷贝到每台机器上,然后要让每台机器都运行一次安装命令;就想到了应用scp、ssh命令,但这两个命令需要输入对端密码,需要与机器交互;此时可以应用交互式命令expect。
expect可以实现自动交互:
set:设置变量;set timeout -1,永不超时;set timeout 300,300秒后没有expect内容出现退出;
spawn:想要执行的命令,你想要进行的交互命令;
expect:等待命令提示信息,交互的过程,系统会给一些输入密码等提示,expect就是抓取其中关键字,当expect抓取到了后面的关键字,就会执行send。
send:发送信息,完成交互,检测到关键字后向交互界面输入的信息。
interact:
expect eof:结束退出;
代码如下:
#!/bin/bash
#
SERVERS="192.168.254.11 192.168.254.12 192.168.254.13" //需要安装的所有主机
PASSWORD="123456" //统一密码
VIB_FILE="/app/vmware-esx-MegaCli-8.07.07.vib" //安装包路径
SHELL_FILE="/app/megacli_install.sh" //安装脚本(脚本中就一条安装vib文件的命令)
vib_shell_copy(){
expect << EOF
set timeout -1 //设置超时时间
spawn scp -o StrictHostKeyChecking=no $VIB_FILE $SHELL_FILE $1:/tmp/ //spawn调用scp命令将安装包和安装脚本copy到$1主机的tmp目录下
expect "assword:" //检测关键信息
send "$2\r" //输出信息$2(密码),通过scp密码交互
expect eof //完成expect
EOF
}
vib_install(){
expect << EOF
set timeout -1
spawn ssh -o stricthostkeychecking=no root@$1 "sh /tmp/megacli_install.sh"
expect "assword:"
send "$2\r"
expect eof
EOF
}
for SER in $SERVERS
do vib_shell_copy $SER $PASSWORD &> /dev/null
echo "$SER copy successed"
vib_install $SER $PASSWORD &> /dev/null
echo "$SER install successed"
done
测试了一下脚本没问题,在生产运行脚本,第四五台机器时脚本就走不动了,咨询一下吴老师,是scp、ssh命令会有首次交互确认的问题,选项 -o stricthostkeychecking=no 关闭主机密钥检查就OK了。
标签: Linux shell
巧用expect安装插件 原创
2020-02-06
剑侠闯江湖
码龄16年
关注
背景
某产品的插件基本都是一步步安装,需要输入一些相对比较专业的参数,对于没有接触过该产品的人而言,就不知道怎么选择。而某客户对于该插件的需求是恒定的,则可以通过expect来自动执行安装,降低了对售后人员的技术要求。
解决方法
!/usr/bin/expect
spawn bash install.bin
set openstack 11
expect "*1*12*select:" { send "$openstack\r" }
set install 1
expect "*operation:" { send "$install\r" }
set expert n
expect "*expert*:" { send "$expert\n" }
set sdnip 2009:d::101
expect "*sdn*" { send "$sdnip\n" }
set https y
expect "*HTTPS*:" { send "$https\n" }
set ssl n
expect "*validation*" { send "$ssl\n" }
set port 8443
expect "*8443*" { send "$port\n" }
set username root
expect "*name:" { send "$username\n" }
set passwd password
expect "*password:" { send "$passwd\n" }
interact
###sample
##remove -P 22 because we meet error :exec: 22: No such file or directory
###add -o stricthostkeychecking=no to 首次登陆时候 提示 avoid Are you sure you want to continue connecting ###(yes/no)?
##remove -P 22 from sftp because we meet error :exec: 22: No such file or directory,Couldn't read packet: ##Connection reset by peer
##in windows nbu master : check security management _ token management : token is MVFNJBPGRJXHCMFU
###check another day token still is MVFNJBPGRJXHCMFU
expect <<- EOF
set timeout 5
spawn sftp -o stricthostkeychecking=no useradmin@10.200.1.1
expect {
"(yes/no)?" {send "yes\r"; expect_continue }
"*assword:" {send "user@pass\r"}
}
expect "sftp>"
send "cd /dbsoft/nbusoft/NBU8.1 \r"
expect "sftp>"
send "lcd /tmp/nbu \r"
expect "sftp>"
set timeout -1
send "mget rman.sh \r"
expect "sftp>"
send "mget NetBackup_8.1.2_CLIENTS2.tar.gz \r"
expect "sftp>"
send "mget rman_arc.sh\r"
expect "sftp>"
send "mget mysql_backup.sh\r"
expect "sftp>"
send "mget mysqlbackup_5.7\r"
expect "sftp>"
send "bye\r"
EOF
因为expect 使用 sftp 可以会存在泄露密码,安全隐患
登录
ssh免密登录远程执行命令/脚本 原创
2018-06-27
5点赞
p7+
码龄5年
关注
执行一条命令
ssh 192.168.1.12 source /etc/profile
1
执行多条命令(如果有空格,那么需要使用双引号)
ssh 192.168.222.102 "source /etc/profile;/root/apps/test.sh"
1
执行脚本的坑
通过ssh执行命令,是没有环境变量的,例如远程启动zookeeper。我们知道,zookeeper是需要java环境的支持,但是我们通过ssh启动其他服务器上的zookeeper时,虽然显示启动成功,
但是切换到zookeeper服务器查看进程时,却发现没有zookeeper的进程。为什么呢?
我们知道,在/etc/profile中配置JAVA_HOME后需要source /etc/profile后,java环境才生效,而linux重启后,
即使不手动执行source /etc/profile,java环境也是有效的,这是因为linux在启动时,已经初始化了/etc/profile文件。
通过ssh远程执行脚本或命令时,如果执行的东西是需要环境支持的,那么我们必须要先初始化环境。例如:test.sh需要java的支持,并且/etc/profile中配置了java的路径
ssh 192.168.222.102 "source /etc/profile;/root/apps/test.sh"
1
免密登陆的zookeeper自启动脚本
#!/bin/bash
SERVERS="pc-server1 pc-server2 pc-server3"
PASSWORD=root
# 自动复制ssh密钥到相应的主机
auto_ssh_copy_id(){
expect -c "set timeout -1;
spawn ssh-copy-id $1;
expect {
*(yes/no)* {send -- yes\r;exp_continue;}
*assword:* {send -- $2\r;exp_continue;}
eof {exit 0;}
}";
}
ssh_copy_id_to_all(){
for SERVER in $SERVERS
do
auto_ssh_copy_id $SERVER $PASSWORD
done
}
ssh_copy_id_to_all
zk(){
for SERVER in $SERVERS
do
ssh root@$SERVER "source /etc/profile;zkServer.sh $1"
done
}
case $1 in
start)
zk $1
;;
stop)
zk $1
;;
status)
zk $1
;;
*)
echo "Usgae:{start|stop|status}"
esac
##sample 因为登录用户不是 root,而是 root 权限的ddadmin ,配置ssh 免密登录,感谢zyp,如果上一次已经配置了一次信任关系,则这一部分再次不用执行,ssh-keygen -P '' ,
## 否则,可能导致之前的关系失效。
#方法1 . ssh-copy-id 命令可用,
su - root
ssh-keygen -P '' 《-如果上一次已经配置了一次信任关系,则这一部分再次不用执行 ,否则,可能导致之前的信任关系失效
ssh-copy-id -i ddadmin@ip
验证
ssh useradmin@ip
##
如果碰到报错:/usr/bin/ssh-copy-id: ERROR: No identities found
# ssh-copy-id -i adadmin@host
/usr/bin/ssh-copy-id: ERROR: No identities found
ssh-copy-id -i /root/.ssh/id_rsa.pub adadmin@host
ssh adadmin@host
##方法2:ssh-copy-id 因为网络防火墙不可用
使用公钥认证脚本将文件从本地拷贝到远程主机
要使用公钥认证脚本将文件从本地拷贝到远程主机,你可以使用scp命令。scp命令使用ssh协议进行加密认证传输,所以你需要在本地和远程主机之间建立ssh连接。
以下是步骤:
step 1:
从本地计算机使用以下命令生成密钥:
ssh-keygen -t rsa
step 2 接下来,将公钥复制到远程主机:
方法2:
在目标主机上执行,
手动创建.ssh目录和authorized_keys文件,如果它们不存在。
将本地公钥文件中的内容复制到authorized_keys文件中
修改authorized_keys文件的权限,使其只对所属用户可读可写:
touch ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
连接到远程主机并将本地公钥文件的内容粘贴到远程authorized_keys文件中。
vi ~/.ssh/authorized_keys
源主机上,可以使用以下命令在本地检索公钥文件:
$ cat ~/.ssh/id_rsa.pub
然后将所检索到的内容粘贴到远程授权文件中。
step 3:
现在你可以使用scp命令将文件从本地复制到远程主机了:
scp /path/to/local/file user@remote_host:/path/to/remote/directory
###sample 5 信任关系配置
步骤1:脚本内容
sshUserSetup.sh
#!/bin/sh
# Nitin Jerath - Aug 2005
#Usage sshUserSetup.sh -user <user name> [ -hosts \"<space separated hostlist>\" | -hostfile <absolute path of cluster configuration file> ] [ -advanced ] [ -verify] [ -exverify ] [ -logfile <desired absolute path of logfile> ] [-confirm] [-shared] [-help] [-usePassphrase] [-noPromptPassphrase]
#eg. sshUserSetup.sh -hosts "host1 host2" -user njerath -advanced
#This script is used to setup SSH connectivity from the host on which it is
# run to the specified remote hosts. After this script is run, the user can use # SSH to run commands on the remote hosts or copy files between the local host
# and the remote hosts without being prompted for passwords or confirmations.
# The list of remote hosts and the user name on the remote host is specified as
# a command line parameter to the script. Note that in case the user on the
# remote host has its home directory NFS mounted or shared across the remote
# hosts, this script should be used with -shared option.
#Specifying the -advanced option on the command line would result in SSH
# connectivity being setup among the remote hosts which means that SSH can be
# used to run commands on one remote host from the other remote host or copy
# files between the remote hosts without being prompted for passwords or
# confirmations.
#Please note that the script would remove write permissions on the remote hosts
#for the user home directory and ~/.ssh directory for "group" and "others". This
# is an SSH requirement. The user would be explicitly informed about this by teh script and prompted to continue. In case the user presses no, the script would exit. In case the user does not want to be prompted, he can use -confirm option.
# As a part of the setup, the script would use SSH to create files within ~/.ssh
# directory of the remote node and to setup the requisite permissions. The
#script also uses SCP to copy the local host public key to the remote hosts so
# that the remote hosts trust the local host for SSH. At the time, the script
#performs these steps, SSH connectivity has not been completely setup hence
# the script would prompt the user for the remote host password.
#For each remote host, for remote users with non-shared homes this would be
# done once for SSH and once for SCP. If the number of remote hosts are x, the
# user would be prompted 2x times for passwords. For remote users with shared
# homes, the user would be prompted only twice, once each for SCP and SSH.
#For security reasons, the script does not save passwords and reuse it. Also,
# for security reasons, the script does not accept passwords redirected from a
#file. The user has to key in the confirmations and passwords at the prompts.
#The -verify option means that the user just wants to verify whether SSH has
#been set up. In this case, the script would not setup SSH but would only check
# whether SSH connectivity has been setup from the local host to the remote
# hosts. The script would run the date command on each remote host using SSH. In
# case the user is prompted for a password or sees a warning message for a
#particular host, it means SSH connectivity has not been setup correctly for
# that host.
#In case the -verify option is not specified, the script would setup SSH and
#then do the verification as well.
#In case the user speciies the -exverify option, an exhaustive verification would be done. In that case, the following would be checked:
# 1. SSH connectivity from local host to all remote hosts.
# 2. SSH connectivity from each remote host to itself and other remote hosts.
#echo Parsing command line arguments
numargs=$#
ADVANCED=false
HOSTNAME=`hostname`
CONFIRM=no
SHARED=false
i=1
USR=$USER
if test -z "$TEMP"
then
TEMP=/tmp
fi
IDENTITY=id_rsa
LOGFILE=$TEMP/sshUserSetup_`date +%F-%H-%M-%S`.log
VERIFY=false
EXHAUSTIVE_VERIFY=false
HELP=false
PASSPHRASE=no
RERUN_SSHKEYGEN=no
NO_PROMPT_PASSPHRASE=no
while [ $i -le $numargs ]
do
j=$1
if [ $j = "-hosts" ]
then
HOSTS=$2
shift 1
i=`expr $i + 1`
fi
if [ $j = "-user" ]
then
USR=$2
shift 1
i=`expr $i + 1`
fi
if [ $j = "-logfile" ]
then
LOGFILE=$2
shift 1
i=`expr $i + 1`
fi
if [ $j = "-confirm" ]
then
CONFIRM=yes
fi
if [ $j = "-hostfile" ]
then
CLUSTER_CONFIGURATION_FILE=$2
shift 1
i=`expr $i + 1`
fi
if [ $j = "-usePassphrase" ]
then
PASSPHRASE=yes
fi
if [ $j = "-noPromptPassphrase" ]
then
NO_PROMPT_PASSPHRASE=yes
fi
if [ $j = "-shared" ]
then
SHARED=true
fi
if [ $j = "-exverify" ]
then
EXHAUSTIVE_VERIFY=true
fi
if [ $j = "-verify" ]
then
VERIFY=true
fi
if [ $j = "-advanced" ]
then
ADVANCED=true
fi
if [ $j = "-help" ]
then
HELP=true
fi
i=`expr $i + 1`
shift 1
done
if [ $HELP = "true" ]
then
echo "Usage $0 -user <user name> [ -hosts \"<space separated hostlist>\" | -hostfile <absolute path of cluster configuration file> ] [ -advanced ] [ -verify] [ -exverify ] [ -logfile <desired absolute path of logfile> ] [-confirm] [-shared] [-help] [-usePassphrase] [-noPromptPassphrase]"
echo "This script is used to setup SSH connectivity from the host on which it is run to the specified remote hosts. After this script is run, the user can use SSH to run commands on the remote hosts or copy files between the local host and the remote hosts without being prompted for passwords or confirmations. The list of remote hosts and the user name on the remote host is specified as a command line parameter to the script. "
echo "-user : User on remote hosts. "
echo "-hosts : Space separated remote hosts list. "
echo "-hostfile : The user can specify the host names either through the -hosts option or by specifying the absolute path of a cluster configuration file. A sample host file contents are below: "
echo
echo " stacg30 stacg30int 10.1.0.0 stacg30v -"
echo " stacg34 stacg34int 10.1.0.1 stacg34v -"
echo
echo " The first column in each row of the host file will be used as the host name."
echo
echo "-usePassphrase : The user wants to set up passphrase to encrypt the private key on the local host. "
echo "-noPromptPassphrase : The user does not want to be prompted for passphrase related questions. This is for users who want the default behavior to be followed."
echo "-shared : In case the user on the remote host has its home directory NFS mounted or shared across the remote hosts, this script should be used with -shared option. "
echo " It is possible for the user to determine whether a user's home directory is shared or non-shared. Let us say we want to determine that user user1's home directory is shared across hosts A, B and C."
echo " Follow the following steps:"
echo " 1. On host A, touch ~user1/checkSharedHome.tmp"
echo " 2. On hosts B and C, ls -al ~user1/checkSharedHome.tmp"
echo " 3. If the file is present on hosts B and C in ~user1 directory and"
echo " is identical on all hosts A, B, C, it means that the user's home "
echo " directory is shared."
echo " 4. On host A, rm -f ~user1/checkSharedHome.tmp"
echo " In case the user accidentally passes -shared option for non-shared homes or viceversa,SSH connectivity would only be set up for a subset of the hosts. The user would have to re-run the setyp script with the correct option to rectify this problem."
echo "-advanced : Specifying the -advanced option on the command line would result in SSH connectivity being setup among the remote hosts which means that SSH can be used to run commands on one remote host from the other remote host or copy files between the remote hosts without being prompted for passwords or confirmations."
echo "-confirm: The script would remove write permissions on the remote hosts for the user home directory and ~/.ssh directory for "group" and "others". This is an SSH requirement. The user would be explicitly informed about this by the script and prompted to continue. In case the user presses no, the script would exit. In case the user does not want to be prompted, he can use -confirm option."
echo "As a part of the setup, the script would use SSH to create files within ~/.ssh directory of the remote node and to setup the requisite permissions. The script also uses SCP to copy the local host public key to the remote hosts so that the remote hosts trust the local host for SSH. At the time, the script performs these steps, SSH connectivity has not been completely setup hence the script would prompt the user for the remote host password. "
echo "For each remote host, for remote users with non-shared homes this would be done once for SSH and once for SCP. If the number of remote hosts are x, the user would be prompted 2x times for passwords. For remote users with shared homes, the user would be prompted only twice, once each for SCP and SSH. For security reasons, the script does not save passwords and reuse it. Also, for security reasons, the script does not accept passwords redirected from a file. The user has to key in the confirmations and passwords at the prompts. "
echo "-verify : -verify option means that the user just wants to verify whether SSH has been set up. In this case, the script would not setup SSH but would only check whether SSH connectivity has been setup from the local host to the remote hosts. The script would run the date command on each remote host using SSH. In case the user is prompted for a password or sees a warning message for a particular host, it means SSH connectivity has not been setup correctly for that host. In case the -verify option is not specified, the script would setup SSH and then do the verification as well. "
echo "-exverify : In case the user speciies the -exverify option, an exhaustive verification for all hosts would be done. In that case, the following would be checked: "
echo " 1. SSH connectivity from local host to all remote hosts. "
echo " 2. SSH connectivity from each remote host to itself and other remote hosts. "
echo The -exverify option can be used in conjunction with the -verify option as well to do an exhaustive verification once the setup has been done.
echo "Taking some examples: Let us say local host is Z, remote hosts are A,B and C. Local user is njerath. Remote users are racqa(non-shared), aime(shared)."
echo "$0 -user racqa -hosts "A B C" -advanced -exverify -confirm"
echo "Script would set up connectivity from Z -> A, Z -> B, Z -> C, A -> A, A -> B, A -> C, B -> A, B -> B, B -> C, C -> A, C -> B, C -> C."
echo "Since user has given -exverify option, all these scenario would be verified too."
echo
echo "Now the user runs : $0 -user racqa -hosts "A B C" -verify"
echo "Since -verify option is given, no SSH setup would be done, only verification of existing setup. Also, since -exverify or -advanced options are not given, script would only verify connectivity from Z -> A, Z -> B, Z -> C"
echo "Now the user runs : $0 -user racqa -hosts "A B C" -verify -advanced"
echo "Since -verify option is given, no SSH setup would be done, only verification of existing setup. Also, since -advanced options is given, script would verify connectivity from Z -> A, Z -> B, Z -> C, A-> A, A->B, A->C, A->D"
echo "Now the user runs:"
echo "$0 -user aime -hosts "A B C" -confirm -shared"
echo "Script would set up connectivity between Z->A, Z->B, Z->C only since advanced option is not given."
echo "All these scenarios would be verified too."
exit
fi
if test -z "$HOSTS"
then
if test -n "$CLUSTER_CONFIGURATION_FILE" && test -f "$CLUSTER_CONFIGURATION_FILE"
then
HOSTS=`awk '$1 !~ /^#/ { str = str " " $1 } END { print str }' $CLUSTER_CONFIGURATION_FILE`
elif ! test -f "$CLUSTER_CONFIGURATION_FILE"
then
echo "Please specify a valid and existing cluster configuration file."
fi
fi
if test -z "$HOSTS" || test -z $USR
then
echo "Either user name or host information is missing"
echo "Usage $0 -user <user name> [ -hosts \"<space separated hostlist>\" | -hostfile <absolute path of cluster configuration file> ] [ -advanced ] [ -verify] [ -exverify ] [ -logfile <desired absolute path of logfile> ] [-confirm] [-shared] [-help] [-usePassphrase] [-noPromptPassphrase]"
exit 1
fi
if [ -d $LOGFILE ]; then
echo $LOGFILE is a directory, setting logfile to $LOGFILE/ssh.log
LOGFILE=$LOGFILE/ssh.log
fi
echo The output of this script is also logged into $LOGFILE | tee -a $LOGFILE
if [ `echo $?` != 0 ]; then
echo Error writing to the logfile $LOGFILE, Exiting
exit 1
fi
echo Hosts are $HOSTS | tee -a $LOGFILE
echo user is $USR | tee -a $LOGFILE
SSH="/usr/bin/ssh"
SCP="/usr/bin/scp"
SSH_KEYGEN="/usr/bin/ssh-keygen"
calculateOS()
{
platform=`uname -s`
case "$platform"
in
"SunOS") os=solaris;;
"Linux") os=linux;;
"HP-UX") os=hpunix;;
"AIX") os=aix;;
*) echo "Sorry, $platform is not currently supported." | tee -a $LOGFILE
exit 1;;
esac
echo "Platform:- $platform " | tee -a $LOGFILE
}
calculateOS
BITS=1024
ENCR="rsa"
deadhosts=""
alivehosts=""
if [ $platform = "Linux" ]
then
PING="/bin/ping"
else
PING="/usr/sbin/ping"
fi
#bug 9044791
if [ -n "$SSH_PATH" ]; then
SSH=$SSH_PATH
fi
if [ -n "$SCP_PATH" ]; then
SCP=$SCP_PATH
fi
if [ -n "$SSH_KEYGEN_PATH" ]; then
SSH_KEYGEN=$SSH_KEYGEN_PATH
fi
if [ -n "$PING_PATH" ]; then
PING=$PING_PATH
fi
PATH_ERROR=0
if test ! -x $SSH ; then
echo "ssh not found at $SSH. Please set the variable SSH_PATH to the correct location of ssh and retry."
PATH_ERROR=1
fi
if test ! -x $SCP ; then
echo "scp not found at $SCP. Please set the variable SCP_PATH to the correct location of scp and retry."
PATH_ERROR=1
fi
if test ! -x $SSH_KEYGEN ; then
echo "ssh-keygen not found at $SSH_KEYGEN. Please set the variable SSH_KEYGEN_PATH to the correct location of ssh-keygen and retry."
PATH_ERROR=1
fi
if test ! -x $PING ; then
echo "ping not found at $PING. Please set the variable PING_PATH to the correct location of ping and retry."
PATH_ERROR=1
fi
if [ $PATH_ERROR = 1 ]; then
echo "ERROR: one or more of the required binaries not found, exiting"
exit 1
fi
#9044791 end
echo Checking if the remote hosts are reachable | tee -a $LOGFILE
for host in $HOSTS
do
if [ $platform = "SunOS" ]; then
$PING -s $host 5 5
elif [ $platform = "HP-UX" ]; then
$PING $host -n 5 -m 5
else
$PING -c 5 -w 5 $host
fi
exitcode=`echo $?`
if [ $exitcode = 0 ]
then
alivehosts="$alivehosts $host"
else
deadhosts="$deadhosts $host"
fi
done
if test -z "$deadhosts"
then
echo Remote host reachability check succeeded. | tee -a $LOGFILE
echo The following hosts are reachable: $alivehosts. | tee -a $LOGFILE
echo The following hosts are not reachable: $deadhosts. | tee -a $LOGFILE
echo All hosts are reachable. Proceeding further... | tee -a $LOGFILE
else
echo Remote host reachability check failed. | tee -a $LOGFILE
echo The following hosts are reachable: $alivehosts. | tee -a $LOGFILE
echo The following hosts are not reachable: $deadhosts. | tee -a $LOGFILE
echo Please ensure that all the hosts are up and re-run the script. | tee -a $LOGFILE
echo Exiting now... | tee -a $LOGFILE
exit 1
fi
firsthost=`echo $HOSTS | awk '{print $1}; END { }'`
echo firsthost $firsthost
numhosts=`echo $HOSTS | awk '{ }; END {print NF}'`
echo numhosts $numhosts
if [ $VERIFY = "true" ]
then
echo Since user has specified -verify option, SSH setup would not be done. Only, existing SSH setup would be verified. | tee -a $LOGFILE
continue
else
echo The script will setup SSH connectivity from the host ''`hostname`'' to all | tee -a $LOGFILE
echo the remote hosts. After the script is executed, the user can use SSH to run | tee -a $LOGFILE
echo commands on the remote hosts or copy files between this host ''`hostname`'' | tee -a $LOGFILE
echo and the remote hosts without being prompted for passwords or confirmations. | tee -a $LOGFILE
echo | tee -a $LOGFILE
echo NOTE 1: | tee -a $LOGFILE
echo As part of the setup procedure, this script will use 'ssh' and 'scp' to copy | tee -a $LOGFILE
echo files between the local host and the remote hosts. Since the script does not | tee -a $LOGFILE
echo store passwords, you may be prompted for the passwords during the execution of | tee -a $LOGFILE
echo the script whenever 'ssh' or 'scp' is invoked. | tee -a $LOGFILE
echo | tee -a $LOGFILE
echo NOTE 2: | tee -a $LOGFILE
echo "AS PER SSH REQUIREMENTS, THIS SCRIPT WILL SECURE THE USER HOME DIRECTORY" | tee -a $LOGFILE
echo AND THE .ssh DIRECTORY BY REVOKING GROUP AND WORLD WRITE PRIVILEDGES TO THESE | tee -a $LOGFILE
echo "directories." | tee -a $LOGFILE
echo | tee -a $LOGFILE
echo "Do you want to continue and let the script make the above mentioned changes (yes/no)?" | tee -a $LOGFILE
if [ "$CONFIRM" = "no" ]
then
read CONFIRM
else
echo "Confirmation provided on the command line" | tee -a $LOGFILE
fi
echo | tee -a $LOGFILE
echo The user chose ''$CONFIRM'' | tee -a $LOGFILE
if [ "$CONFIRM" = "no" ]
then
echo "SSH setup is not done." | tee -a $LOGFILE
exit 1
else
if [ $NO_PROMPT_PASSPHRASE = "yes" ]
then
echo "User chose to skip passphrase related questions." | tee -a $LOGFILE
else
typeset -i PASSPHRASE_PROMPT
if [ $SHARED = "true" ]
then
PASSPHRASE_PROMPT=2*${numhosts}+1
else
PASSPHRASE_PROMPT=2*${numhosts}
fi
echo "Please specify if you want to specify a passphrase for the private key this script will create for the local host. Passphrase is used to encrypt the private key and makes SSH much more secure. Type 'yes' or 'no' and then press enter. In case you press 'yes', you would need to enter the passphrase whenever the script executes ssh or scp. " | tee -a $LOGFILE
echo "The estimated number of times the user would be prompted for a passphrase is $PASSPHRASE_PROMPT. In addition, if the private-public files are also newly created, the user would have to specify the passphrase on one additional occasion. " | tee -a $LOGFILE
echo "Enter 'yes' or 'no'." | tee -a $LOGFILE
if [ $PASSPHRASE = "no" ]
then
read PASSPHRASE
else
echo "Confirmation provided on the command line" | tee -a $LOGFILE
fi
echo | tee -a $LOGFILE
echo The user chose ''$PASSPHRASE'' | tee -a $LOGFILE
if [ "$PASSPHRASE" = "yes" ]
then
RERUN_SSHKEYGEN="yes"
#Checking for existence of ${IDENTITY} file
if test -f $HOME/.ssh/${IDENTITY}.pub && test -f $HOME/.ssh/${IDENTITY}
then
echo "The files containing the client public and private keys already exist on the local host. The current private key may or may not have a passphrase associated with it. In case you remember the passphrase and do not want to re-run ssh-keygen, press 'no' and enter. If you press 'no', the script will not attempt to create any new public/private key pairs. If you press 'yes', the script will remove the old private/public key files existing and create new ones prompting the user to enter the passphrase. If you enter 'yes', any previous SSH user setups would be reset. If you press 'change', the script will associate a new passphrase with the old keys." | tee -a $LOGFILE
echo "Press 'yes', 'no' or 'change'" | tee -a $LOGFILE
read RERUN_SSHKEYGEN
echo The user chose ''$RERUN_SSHKEYGEN'' | tee -a $LOGFILE
fi
else
if test -f $HOME/.ssh/${IDENTITY}.pub && test -f $HOME/.ssh/${IDENTITY}
then
echo "The files containing the client public and private keys already exist on the local host. The current private key may have a passphrase associated with it. In case you find using passphrase inconvenient(although it is more secure), you can change to it empty through this script. Press 'change' if you want the script to change the passphrase for you. Press 'no' if you want to use your old passphrase, if you had one."
read RERUN_SSHKEYGEN
echo The user chose ''$RERUN_SSHKEYGEN'' | tee -a $LOGFILE
fi
fi
fi
echo Creating .ssh directory on local host, if not present already | tee -a $LOGFILE
mkdir -p $HOME/.ssh | tee -a $LOGFILE
echo Creating authorized_keys file on local host | tee -a $LOGFILE
touch $HOME/.ssh/authorized_keys | tee -a $LOGFILE
echo Changing permissions on authorized_keys to 644 on local host | tee -a $LOGFILE
chmod 644 $HOME/.ssh/authorized_keys | tee -a $LOGFILE
mv -f $HOME/.ssh/authorized_keys $HOME/.ssh/authorized_keys.tmp | tee -a $LOGFILE
echo Creating known_hosts file on local host | tee -a $LOGFILE
touch $HOME/.ssh/known_hosts | tee -a $LOGFILE
echo Changing permissions on known_hosts to 644 on local host | tee -a $LOGFILE
chmod 644 $HOME/.ssh/known_hosts | tee -a $LOGFILE
mv -f $HOME/.ssh/known_hosts $HOME/.ssh/known_hosts.tmp | tee -a $LOGFILE
echo Creating config file on local host | tee -a $LOGFILE
echo If a config file exists already at $HOME/.ssh/config, it would be backed up to $HOME/.ssh/config.backup.
echo "Host *" > $HOME/.ssh/config.tmp | tee -a $LOGFILE
echo "ForwardX11 no" >> $HOME/.ssh/config.tmp | tee -a $LOGFILE
if test -f $HOME/.ssh/config
then
cp -f $HOME/.ssh/config $HOME/.ssh/config.backup
fi
mv -f $HOME/.ssh/config.tmp $HOME/.ssh/config | tee -a $LOGFILE
chmod 644 $HOME/.ssh/config
if [ $RERUN_SSHKEYGEN = "yes" ]
then
echo Removing old private/public keys on local host | tee -a $LOGFILE
rm -f $HOME/.ssh/${IDENTITY} | tee -a $LOGFILE
rm -f $HOME/.ssh/${IDENTITY}.pub | tee -a $LOGFILE
echo Running SSH keygen on local host | tee -a $LOGFILE
$SSH_KEYGEN -t $ENCR -b $BITS -f $HOME/.ssh/${IDENTITY} | tee -a $LOGFILE
elif [ $RERUN_SSHKEYGEN = "change" ]
then
echo Running SSH Keygen on local host to change the passphrase associated with the existing private key | tee -a $LOGFILE
$SSH_KEYGEN -p -t $ENCR -b $BITS -f $HOME/.ssh/${IDENTITY} | tee -a $LOGFILE
elif test -f $HOME/.ssh/${IDENTITY}.pub && test -f $HOME/.ssh/${IDENTITY}
then
continue
else
echo Removing old private/public keys on local host | tee -a $LOGFILE
rm -f $HOME/.ssh/${IDENTITY} | tee -a $LOGFILE
rm -f $HOME/.ssh/${IDENTITY}.pub | tee -a $LOGFILE
echo Running SSH keygen on local host with empty passphrase | tee -a $LOGFILE
$SSH_KEYGEN -t $ENCR -b $BITS -f $HOME/.ssh/${IDENTITY} -N '' | tee -a $LOGFILE
fi
if [ $SHARED = "true" ]
then
if [ $USER = $USR ]
then
#No remote operations required
echo Remote user is same as local user | tee -a $LOGFILE
REMOTEHOSTS=""
chmod og-w $HOME $HOME/.ssh | tee -a $LOGFILE
else
REMOTEHOSTS="${firsthost}"
fi
else
REMOTEHOSTS="$HOSTS"
fi
for host in $REMOTEHOSTS
do
echo Creating .ssh directory and setting permissions on remote host $host | tee -a $LOGFILE
echo "THE SCRIPT WOULD ALSO BE REVOKING WRITE PERMISSIONS FOR "group" AND "others" ON THE HOME DIRECTORY FOR $USR. THIS IS AN SSH REQUIREMENT." | tee -a $LOGFILE
echo The script would create ~$USR/.ssh/config file on remote host $host. If a config file exists already at ~$USR/.ssh/config, it would be backed up to ~$USR/.ssh/config.backup. | tee -a $LOGFILE
echo The user may be prompted for a password here since the script would be running SSH on host $host. | tee -a $LOGFILE
$SSH -o StrictHostKeyChecking=no -x -l $USR $host "/bin/sh -c \" mkdir -p .ssh ; chmod og-w . .ssh; touch .ssh/authorized_keys .ssh/known_hosts; chmod 644 .ssh/authorized_keys .ssh/known_hosts; cp .ssh/authorized_keys .ssh/authorized_keys.tmp ; cp .ssh/known_hosts .ssh/known_hosts.tmp; echo \\"Host *\\" > .ssh/config.tmp; echo \\"ForwardX11 no\\" >> .ssh/config.tmp; if test -f .ssh/config ; then cp -f .ssh/config .ssh/config.backup; fi ; mv -f .ssh/config.tmp .ssh/config\"" | tee -a $LOGFILE
echo Done with creating .ssh directory and setting permissions on remote host $host. | tee -a $LOGFILE
done
for host in $REMOTEHOSTS
do
echo Copying local host public key to the remote host $host | tee -a $LOGFILE
echo The user may be prompted for a password or passphrase here since the script would be using SCP for host $host. | tee -a $LOGFILE
$SCP $HOME/.ssh/${IDENTITY}.pub $USR@$host:.ssh/authorized_keys | tee -a $LOGFILE
echo Done copying local host public key to the remote host $host | tee -a $LOGFILE
done
cat $HOME/.ssh/${IDENTITY}.pub >> $HOME/.ssh/authorized_keys | tee -a $LOGFILE
for host in $HOSTS
do
if [ $ADVANCED = "true" ]
then
echo Creating keys on remote host $host if they do not exist already. This is required to setup SSH on host $host. | tee -a $LOGFILE
if [ $SHARED = "true" ]
then
IDENTITY_FILE_NAME=${IDENTITY}_$host
COALESCE_IDENTITY_FILES_COMMAND="cat .ssh/${IDENTITY_FILE_NAME}.pub >> .ssh/authorized_keys"
else
IDENTITY_FILE_NAME=${IDENTITY}
fi
$SSH -o StrictHostKeyChecking=no -x -l $USR $host " /bin/sh -c \"if test -f .ssh/${IDENTITY_FILE_NAME}.pub && test -f .ssh/${IDENTITY_FILE_NAME}; then echo; else rm -f .ssh/${IDENTITY_FILE_NAME} ; rm -f .ssh/${IDENTITY_FILE_NAME}.pub ; $SSH_KEYGEN -t $ENCR -b $BITS -f .ssh/${IDENTITY_FILE_NAME} -N '' ; fi; ${COALESCE_IDENTITY_FILES_COMMAND} \"" | tee -a $LOGFILE
else
#At least get the host keys from all hosts for shared case - advanced option not set
if test $SHARED = "true" && test $ADVANCED = "false"
then
if [ $PASSPHRASE = "yes" ]
then
echo "The script will fetch the host keys from all hosts. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase." | tee -a $LOGFILE
fi
$SSH -o StrictHostKeyChecking=no -x -l $USR $host "/bin/sh -c true"
fi
fi
done
for host in $REMOTEHOSTS
do
if test $ADVANCED = "true" && test $SHARED = "false"
then
$SCP $USR@$host:.ssh/${IDENTITY}.pub $HOME/.ssh/${IDENTITY}.pub.$host | tee -a $LOGFILE
cat $HOME/.ssh/${IDENTITY}.pub.$host >> $HOME/.ssh/authorized_keys | tee -a $LOGFILE
rm -f $HOME/.ssh/${IDENTITY}.pub.$host | tee -a $LOGFILE
fi
done
for host in $REMOTEHOSTS
do
if [ $ADVANCED = "true" ]
then
if [ $SHARED != "true" ]
then
echo Updating authorized_keys file on remote host $host | tee -a $LOGFILE
$SCP $HOME/.ssh/authorized_keys $USR@$host:.ssh/authorized_keys | tee -a $LOGFILE
fi
echo Updating known_hosts file on remote host $host | tee -a $LOGFILE
$SCP $HOME/.ssh/known_hosts $USR@$host:.ssh/known_hosts | tee -a $LOGFILE
fi
if [ $PASSPHRASE = "yes" ]
then
echo "The script will run SSH on the remote machine $host. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase." | tee -a $LOGFILE
fi
$SSH -x -l $USR $host "/bin/sh -c \"cat .ssh/authorized_keys.tmp >> .ssh/authorized_keys; cat .ssh/known_hosts.tmp >> .ssh/known_hosts; rm -f .ssh/known_hosts.tmp .ssh/authorized_keys.tmp\"" | tee -a $LOGFILE
done
cat $HOME/.ssh/known_hosts.tmp >> $HOME/.ssh/known_hosts | tee -a $LOGFILE
cat $HOME/.ssh/authorized_keys.tmp >> $HOME/.ssh/authorized_keys | tee -a $LOGFILE
#Added chmod to fix BUG NO 5238814
chmod 644 $HOME/.ssh/authorized_keys
#Fix for BUG NO 5157782
chmod 644 $HOME/.ssh/config
rm -f $HOME/.ssh/known_hosts.tmp $HOME/.ssh/authorized_keys.tmp | tee -a $LOGFILE
echo SSH setup is complete. | tee -a $LOGFILE
fi
fi
echo | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
echo Verifying SSH setup | tee -a $LOGFILE
echo =================== | tee -a $LOGFILE
echo The script will now run the 'date' command on the remote nodes using ssh | tee -a $LOGFILE
echo to verify if ssh is setup correctly. IF THE SETUP IS CORRECTLY SETUP, | tee -a $LOGFILE
echo THERE SHOULD BE NO OUTPUT OTHER THAN THE DATE AND SSH SHOULD NOT ASK FOR | tee -a $LOGFILE
echo PASSWORDS. If you see any output other than date or are prompted for the | tee -a $LOGFILE
echo password, ssh is not setup correctly and you will need to resolve the | tee -a $LOGFILE
echo issue and set up ssh again. | tee -a $LOGFILE
echo The possible causes for failure could be: | tee -a $LOGFILE
echo 1. The server settings in /etc/ssh/sshd_config file do not allow ssh | tee -a $LOGFILE
echo for user $USR. | tee -a $LOGFILE
echo 2. The server may have disabled public key based authentication.
echo 3. The client public key on the server may be outdated.
echo 4. ~$USR or ~$USR/.ssh on the remote host may not be owned by $USR. | tee -a $LOGFILE
echo 5. User may not have passed -shared option for shared remote users or | tee -a $LOGFILE
echo may be passing the -shared option for non-shared remote users. | tee -a $LOGFILE
echo 6. If there is output in addition to the date, but no password is asked, | tee -a $LOGFILE
echo it may be a security alert shown as part of company policy. Append the | tee -a $LOGFILE
echo "additional text to the <OMS HOME>/sysman/prov/resources/ignoreMessages.txt file." | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
#read -t 30 dummy
for host in $HOSTS
do
echo --$host:-- | tee -a $LOGFILE
echo Running $SSH -x -l $USR $host date to verify SSH connectivity has been setup from local host to $host. | tee -a $LOGFILE
echo "IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL. Please note that being prompted for a passphrase may be OK but being prompted for a password is ERROR." | tee -a $LOGFILE
if [ $PASSPHRASE = "yes" ]
then
echo "The script will run SSH on the remote machine $host. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase." | tee -a $LOGFILE
fi
$SSH -l $USR $host "/bin/sh -c date" | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
done
if [ $EXHAUSTIVE_VERIFY = "true" ]
then
for clienthost in $HOSTS
do
if [ $SHARED = "true" ]
then
REMOTESSH="$SSH -i .ssh/${IDENTITY}_${clienthost}"
else
REMOTESSH=$SSH
fi
for serverhost in $HOSTS
do
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
echo Verifying SSH connectivity has been setup from $clienthost to $serverhost | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
echo "IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL." | tee -a $LOGFILE
$SSH -l $USR $clienthost "$REMOTESSH $serverhost \"/bin/sh -c date\"" | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
done
echo -Verification from $clienthost complete- | tee -a $LOGFILE
done
else
if [ $ADVANCED = "true" ]
then
if [ $SHARED = "true" ]
then
REMOTESSH="$SSH -i .ssh/${IDENTITY}_${firsthost}"
else
REMOTESSH=$SSH
fi
for host in $HOSTS
do
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
echo Verifying SSH connectivity has been setup from $firsthost to $host | tee -a $LOGFILE
echo "IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL." | tee -a $LOGFILE
$SSH -l $USR $firsthost "/bin/sh -c \"$REMOTESSH $host \\"/bin/sh -c date\\"\"" | tee -a $LOGFILE
echo ------------------------------------------------------------------------ | tee -a $LOGFILE
done
echo -Verification from $clienthost complete- | tee -a $LOGFILE
fi
fi
echo "SSH verification complete." | tee -a $LOGFILE
#!end
步骤2.执行过程
sshUserSetup.sh --oracle自动化互信工具
[root@rac2 ios]# sh sshUserSetup.sh -user root -hosts "rac1 rac2" -advanced
The output of this script is also logged into /tmp/sshUserSetup_2023-06-27-13-32-30.log
Hosts are rac1 rac2
user is root
Platform:- Linux
Checking if the remote hosts are reachable
PING rac1 (192.168.1.79) 56(84) bytes of data.
64 bytes from rac1 (192.168.1.79): icmp_seq=1 ttl=64 time=0.224 ms
64 bytes from rac1 (192.168.1.79): icmp_seq=2 ttl=64 time=0.181 ms
64 bytes from rac1 (192.168.1.79): icmp_seq=3 ttl=64 time=0.217 ms
64 bytes from rac1 (192.168.1.79): icmp_seq=4 ttl=64 time=0.183 ms
64 bytes from rac1 (192.168.1.79): icmp_seq=5 ttl=64 time=0.263 ms
--- rac1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.181/0.213/0.263/0.034 ms
PING rac2 (192.168.1.80) 56(84) bytes of data.
64 bytes from rac2 (192.168.1.80): icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from rac2 (192.168.1.80): icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from rac2 (192.168.1.80): icmp_seq=3 ttl=64 time=0.058 ms
64 bytes from rac2 (192.168.1.80): icmp_seq=4 ttl=64 time=0.063 ms
64 bytes from rac2 (192.168.1.80): icmp_seq=5 ttl=64 time=0.059 ms
--- rac2 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.049/0.056/0.063/0.006 ms
Remote host reachability check succeeded.
The following hosts are reachable: rac1 rac2.
The following hosts are not reachable: .
All hosts are reachable. Proceeding further...
firsthost rac1
numhosts 2
The script will setup SSH connectivity from the host rac2 to all
the remote hosts. After the script is executed, the user can use SSH to run
commands on the remote hosts or copy files between this host rac2
and the remote hosts without being prompted for passwords or confirmations.
NOTE 1:
As part of the setup procedure, this script will use ssh and scp to copy
files between the local host and the remote hosts. Since the script does not
store passwords, you may be prompted for the passwords during the execution of
the script whenever ssh or scp is invoked.
NOTE 2:
AS PER SSH REQUIREMENTS, THIS SCRIPT WILL SECURE THE USER HOME DIRECTORY
AND THE .ssh DIRECTORY BY REVOKING GROUP AND WORLD WRITE PRIVILEDGES TO THESE
directories.
Do you want to continue and let the script make the above mentioned changes (yes/no)?
yes
The user chose yes
Please specify if you want to specify a passphrase for the private key this script will create for the local host. Passphrase is used to encrypt the private key and makes SSH much more secure. Type 'yes' or 'no' and then press enter. In case you press 'yes', you would need to enter the passphrase whenever the script executes ssh or scp.
The estimated number of times the user would be prompted for a passphrase is 4. In addition, if the private-public files are also newly created, the user would have to specify the passphrase on one additional occasion.
Enter 'yes' or 'no'.
yes
The user chose yes
The files containing the client public and private keys already exist on the local host. The current private key may or may not have a passphrase associated with it. In case you remember the passphrase and do not want to re-run ssh-keygen, press 'no' and enter. If you press 'no', the script will not attempt to create any new public/private key pairs. If you press 'yes', the script will remove the old private/public key files existing and create new ones prompting the user to enter the passphrase. If you enter 'yes', any previous SSH user setups would be reset. If you press 'change', the script will associate a new passphrase with the old keys.
Press 'yes', 'no' or 'change'
yes
The user chose yes
Creating .ssh directory on local host, if not present already
Creating authorized_keys file on local host
Changing permissions on authorized_keys to 644 on local host
Creating known_hosts file on local host
Changing permissions on known_hosts to 644 on local host
Creating config file on local host
If a config file exists already at /root/.ssh/config, it would be backed up to /root/.ssh/config.backup.
Removing old private/public keys on local host
Running SSH keygen on local host
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+vp8+7LiLphjO2lg/whKsg5Ai00pIV6+jfSpnmg3qXA root@rac2
The key's randomart image is:
+---[RSA 1024]----+
|o . |
|o.o. |
|.ooo |
|o+o = . |
|o..o + S |
|. o . . |
|+oE+.+. |
|==o=@..o. o |
|=+o=+=o**oo=. |
+----[SHA256]-----+
Creating .ssh directory and setting permissions on remote host rac1
THE SCRIPT WOULD ALSO BE REVOKING WRITE PERMISSIONS FOR group AND others ON THE HOME DIRECTORY FOR root. THIS IS AN SSH REQUIREMENT.
The script would create ~root/.ssh/config file on remote host rac1. If a config file exists already at ~root/.ssh/config, it would be backed up to ~root/.ssh/config.backup.
The user may be prompted for a password here since the script would be running SSH on host rac1.
Warning: Permanently added 'rac1,192.168.1.79' (ECDSA) to the list of known hosts.
root@rac1's password:
Done with creating .ssh directory and setting permissions on remote host rac1.
Creating .ssh directory and setting permissions on remote host rac2
THE SCRIPT WOULD ALSO BE REVOKING WRITE PERMISSIONS FOR group AND others ON THE HOME DIRECTORY FOR root. THIS IS AN SSH REQUIREMENT.
The script would create ~root/.ssh/config file on remote host rac2. If a config file exists already at ~root/.ssh/config, it would be backed up to ~root/.ssh/config.backup.
The user may be prompted for a password here since the script would be running SSH on host rac2.
Warning: Permanently added 'rac2,192.168.1.80' (ECDSA) to the list of known hosts.
root@rac2's password:
Permission denied, please try again.
root@rac2's password:
Done with creating .ssh directory and setting permissions on remote host rac2.
Copying local host public key to the remote host rac1
The user may be prompted for a password or passphrase here since the script would be using SCP for host rac1.
root@rac1's password:
Done copying local host public key to the remote host rac1
Copying local host public key to the remote host rac2
The user may be prompted for a password or passphrase here since the script would be using SCP for host rac2.
root@rac2's password:
Done copying local host public key to the remote host rac2
Creating keys on remote host rac1 if they do not exist already. This is required to setup SSH on host rac1.
Creating keys on remote host rac2 if they do not exist already. This is required to setup SSH on host rac2.
Updating authorized_keys file on remote host rac1
Updating known_hosts file on remote host rac1
The script will run SSH on the remote machine rac1. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase.
Updating authorized_keys file on remote host rac2
Updating known_hosts file on remote host rac2
The script will run SSH on the remote machine rac2. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase.
cat: /root/.ssh/known_hosts.tmp: No such file or directory
cat: /root/.ssh/authorized_keys.tmp: No such file or directory
SSH setup is complete.
------------------------------------------------------------------------
Verifying SSH setup
===================
The script will now run the date command on the remote nodes using ssh
to verify if ssh is setup correctly. IF THE SETUP IS CORRECTLY SETUP,
THERE SHOULD BE NO OUTPUT OTHER THAN THE DATE AND SSH SHOULD NOT ASK FOR
PASSWORDS. If you see any output other than date or are prompted for the
password, ssh is not setup correctly and you will need to resolve the
issue and set up ssh again.
The possible causes for failure could be:
1. The server settings in /etc/ssh/sshd_config file do not allow ssh
for user root.
2. The server may have disabled public key based authentication.
3. The client public key on the server may be outdated.
4. ~root or ~root/.ssh on the remote host may not be owned by root.
5. User may not have passed -shared option for shared remote users or
may be passing the -shared option for non-shared remote users.
6. If there is output in addition to the date, but no password is asked,
it may be a security alert shown as part of company policy. Append the
additional text to the <OMS HOME>/sysman/prov/resources/ignoreMessages.txt file.
------------------------------------------------------------------------
--rac1:--
Running /usr/bin/ssh -x -l root rac1 date to verify SSH connectivity has been setup from local host to rac1.
IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL. Please note that being prompted for a passphrase may be OK but being prompted for a password is ERROR.
The script will run SSH on the remote machine rac1. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase.
Tue Jun 27 01:35:32 EDT 2023
------------------------------------------------------------------------
--rac2:--
Running /usr/bin/ssh -x -l root rac2 date to verify SSH connectivity has been setup from local host to rac2.
IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL. Please note that being prompted for a passphrase may be OK but being prompted for a password is ERROR.
The script will run SSH on the remote machine rac2. The user may be prompted for a passphrase here in case the private key has been encrypted with a passphrase.
Tue Jun 27 13:35:33 CST 2023
------------------------------------------------------------------------
------------------------------------------------------------------------
Verifying SSH connectivity has been setup from rac1 to rac1
IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL.
Tue Jun 27 01:35:33 EDT 2023
------------------------------------------------------------------------
------------------------------------------------------------------------
Verifying SSH connectivity has been setup from rac1 to rac2
IF YOU SEE ANY OTHER OUTPUT BESIDES THE OUTPUT OF THE DATE COMMAND OR IF YOU ARE PROMPTED FOR A PASSWORD HERE, IT MEANS SSH SETUP HAS NOT BEEN SUCCESSFUL.
Tue Jun 27 13:35:34 CST 2023
------------------------------------------------------------------------
-Verification from complete-
SSH verification complete.
执行脚本后
看到yes/no 输入yes,
Enter passphrase (empty for no passphrase): 回车
Enter same passphrase again:回车
输入对应ip的对应ssh密码即可。
效果演示:
配置一些集群和分布式都能用到
重点参数介绍: -user 用户 指定互信
-hosts "ip或主机名......." 指定互信主机
-advanced 不加单向互信,加上双向互信
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/sa_dan/article/details/131413508
###sample 目的dep_rman_shell.sh 将文件推送到远程,同时远程执行对应脚本,远程修改主机的rman 脚本
file1: dep_rman_shell.sh
#!/bin/bash
#add more hosts
echo "please make sure config file (rman_shell_config.sh) is ok"
head -n 6 rman_shell_config.sh
echo "please input servers:(10.10.10.10 10.20.20.20.20)"
read SERVERS
echo "SERVERS=$SERVERS"
echo "please input os password:"
read PASSWORD
echo "password=$PASSWORD"
#VIB_FILE="/tmp/nbu/host.tmp"
SHELL_FILE="/dbsoft/nbusoft/NBU8.1/config/shell/rman_shell_config.sh"
#--remove set timeout -1 because it running quickly,have already config have hosts' trust info
vib_shell_copy(){
expect << EOF
set timeout -1
spawn scp -o StrictHostKeyChecking=no $SHELL_FILE useradmin@$1:/tmp/
expect "assword:"
send "$2\r"
expect eof
EOF
}
#--remove set timeout -1 because it running quickly ,have already config have hosts' trust info
vib_install(){
expect << EOF
set timeout -1
spawn ssh -o stricthostkeychecking=no useradmin@$1 "sh /tmp/rman_shell_config.sh"
expect "assword:"
send "$2\r"
expect eof
EOF
}
#--add more password in list ,have already config have trust info
for SER in $SERVERS
#do vib_shell_copy $SER $PASSWORD &> /dev/null
#for PASSWORD in $PASS
do vib_shell_copy $SER $PASSWORD
echo "$SER copy successed"
#vib_install $SER $PASSWORD &> /dev/null
vib_install $SER $PASSWORD
echo "$SER install successed"
done
-file 2 rman_shell_config
export sid=ntbs
export user=opntbs
export arch_policy=rman_ntbs_arc
export host=pntbsdb_svc
export ora_policy=rman_ntbsdb
hostname
RSTAT=`ps -ef|grep $user|grep pmon |wc -l`
if [ "$RSTAT" = 0 ]
then
su - $user <<!
cd /usr/openv/netbackup/bin
expect <<- EOF
set timeout 20
spawn ./oracle_link
expect "Do you want to continue? (y/n) \[n\] "
send "y \r"
expect "to make sure the linking process was successful"
EOF
!
echo "install is ok"
else
echo "please check"
fi
cd /usr/openv/netbackup/ext/db_ext/shell
mv sample1 $sid
#cd /usr/openv/netbackup/ext/db_ext/shell
#mv sample1 $sid
cd $sid
perl -p -i -e "s/opigfs/$user/g" *.sh
perl -p -i -e "s/pigfsdb01/$host/g" *.sh
perl -p -i -e "s/rman_igfs_arc/$arch_policy/g" *.sh
perl -p -i -e "s/rman_igfs_new/$ora_policy/g" *.sh
--file 3 readme
1.first edit config file
2.then sh dep*.sh ,input two ip and password
-注意;
上面脚本需要输入主机密码,如果信任关系建立好,不需要输入密码, 如下命令即可
scp $VIB_FILE $SHELL_FILE useradmin@$1:/backup/suseript/nbu
ssh useradmin@$1 "sh /backup/suseript/nbu/media_config.sh"
### sample 3 目的 dep_media.sh 将配置文件host.tmp 传到对应的机器上,同时运行media_config.sh 将运行一系列命令
file 1: dep_media
#!/bin/bash
#add more hosts
echo "please make sure config file (host.tmp) is ok"
echo "make sure all host directroy /backup/suseript/nbu is ok"
head -n 6 host.tmp
echo "please input above info yes/no"
read option
echo "option=$option"
SERVERS="dbsanmd01 dbsanmd02 dbsanmd03 dbsanmd04"
VIB_FILE="/backup/suseript/nbu/host.tmp"
SHELL_FILE="/backup/suseript/nbu/media_config.sh"
#--remove set timeout -1 because it running quickly,have already config have hosts' trust info
vib_shell_copy(){
scp $VIB_FILE $SHELL_FILE useradmin@$1:/backup/suseript/nbu
}
#--remove set timeout -1 because it running quickly ,have already config have hosts' trust info
vib_install(){
ssh useradmin@$1 "sh /backup/suseript/nbu/media_config.sh"
}
#--add more password in list ,have already config have trust info
for SER in $SERVERS
#do vib_shell_copy $SER $PASSWORD &> /dev/null
#for PASSWORD in $PASS
#do vib_shell_copy $SER $PASSWORD
do vib_shell_copy $SER
echo "$SER copy successed"
#vib_install $SER $PASSWORD &> /dev/null
#vib_install $SER $PASSWORD
vib_install $SER
echo "$SER install successed"
done
##for local
sh /backup/suseript/nbu/media_config.sh
bpnbat -login -info /backup/script/nbu/nbu.info
os_name_list=`cat /backup/script/nbu/host.tmp|grep -v "#" |awk ' { print $2 }'|grep -v svc`
for os_name in ${os_name_list}
do
os_name_svc=`cat /backup/script/nbu/host.tmp|grep -v "#" |awk ' { print $2 }'|grep svc`
if [ ! -n "$os_name_svc" ]
then
echo "nothing to do"
else
echo $os_name
nbhostmgmt -add -host $os_name -mappingname $os_name_svc
nbhostmgmt -add -host $os_name -mappingname $os_name_svc -isshared
fi
done
echo "####please ingore the error Exit Status 8715/8724#######"
file2: media_config
hostname
cp /etc/hosts /etc/hosts.bak
/usr/openv/netbackup/bin/bpclntcmd -clear_host_cache
cat /backup/script/nbu/host.tmp >> /etc/hosts
os_name_list=`cat /backup/script/nbu/host.tmp|grep -v "#" |awk ' { print $2 }'`
for os_name in ${os_name_list}
do
echo $os_name
/usr/openv/netbackup/bin/admincmd/bptestbpcd -client $os_name -verbose
done
ls
file 3: host.tmp
##202007###
5.6.1.20
db
file 4:
cat /backup/script/nbu/nbu.info
unixpwd
swnubmaster01
cradmin
CR@zh123
参考
https://www.veritas.com/support/en_US/doc/15263389-127350397-0/v14664081-127350397
########sample 44. 检查磁带包含哪些备份片
附录:
4. 检查磁带包含哪些备份片
#!/bin/ksh
media=$1
media=0279L7
NBADM=/usr/openv/netbackup/bin/admincmd
echo "Media $media contains following files:"
$NBADM/bpimmedia -l -mediaid $media | grep "^IMAGE" | awk {'print $4'} |
while read BID
do
ctime=`echo $BID | sed 's/^.*_//'`
$NBADM/bpflist -l -backupid $BID -ut $ctime | awk {'print $10'}
done
##
##手工 check tape contain backup
/usr/openv/netbackup/bin/admincmd/bpimmedia -l -mediaid 0279L7 | grep "^IMAGE" | awk {'print $4'}
结果
ilog01_1608865795