批量自动化配置SSH免登陆
首先需要理解密钥产生的机制。SSH是基于密钥的,所以系统提供了SSH的命令 ssh-keygen用于生成密钥。
我们可以直接使用命令指定RSA生成一对密钥。
但是在自动过程中,为了避免交互,可以使用以下命令:
ssh-keygen -f id_rsa -t rsa -N ''
其中
-f 是输入文件名,会生成 id_rsa 和 id_rsa.pub 两个文件分别表示密钥和公钥;-t 是密钥内容,文件名称为 RSA;-N 解密的密码,默认为空。使用SSH登陆时第一次登陆会出现以下内容,进行确认是否登陆,如下所示:
root@server00:~/hao# ssh user@host The authenticity of host '106.12.31.101 (106.12.31.101)' can't be established. ECDSA key fingerprint is SHA256:SRQLrDAimMXE8tRTMyELTgOL9r+tvcJX4ZmwOQZ2d+Q. Are you sure you want to continue connecting (yes/no)?
以上的内容是从安全角度让用户进行确认,所以不显示此内容,可以通过配置实现:
ssh -o StrictHostKeyChecking=no user@host
注:
~/.ssh/known_hosts 中。ssh -i ssum_key.pem user@host;-i 参数,可在 ~/.ssh/config 添加 IdentityFile ~/.ssh/ssum_key.pem;~/.ssh/id_rsa,也可省去 -i 参数。输入密码有两种方法:sshpass 或 expect。这两种工具只需要在本机安装好即可,目标机器无需安装。
sshpass 命令可以用于 ssh 和 scp 命令,如:
sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@host
安装时也可以免交互,只需要在install后加上 -y 即可,如下所示:
apt install -y expect
示例脚本
#!/usr/bin/expect set timeout 30 spawn ssh -l root 106.12.31.101 expect "password*" send "\password\r" interact
sshpass)此脚本在本机执行,只需在本地1次:
ssh-keygen -f id_rsa -t rsa -N ''
sshpassapt install -y sshpass
使用以下基于 sshpass 的脚本可以实现自动化上传公钥的脚本。
#!/usr/bin/expect # Step 1: upload mykey.pub to server sshpass -p 'password' scp mykey.pub user@host: # Step 2: Add mykey.pub to authorized_keys sshpass -p 'password' ssh user@host "cat mykey.pub >> ~/.ssh/authorized_keys"
整体框架以下所示。
解释
sshpass服务器上存储了所有通过SSH登陆的文件,每个文件中的内容是密码,文件名为 登陆名@HostIP,如 root@106.12.31.101,内容是 $erver2019。
这样,只需使用 sshpass -f $1 ssh $1 "ls" 即可执行相关命令。
批量执行任务
#!/bin/bash cmd="cd /opt; ls" for file in $1/*; do name=$(basename $file) echo "------------------------------------------------------------------" echo "sshpass -f $name ssh $name \"$cmd\"" sshpass -f $file ssh -o StrictHostKeyChecking=no $name "$cmd" echo "" done
执行结果
root@server00:~# sh sh1.sh task1/ ------------------------------------------------------------------ sshpass -f root@106.12.31.101 ssh root@106.12.31.101 "cd /opt; ls" avalokita bcm-agent containerd hosteye java tomcat8 ------------------------------------------------------------------ sshpass -f root@121.199.10.158 ssh root@121.199.10.158 "cd /opt; ls" apache-tomcat-8.5.57 jdk-11.0.8 jdk1.8.0_261
# 示例1:循环输出编号 for a in {1..10}; do echo "ID:$a"; done # 示例2:使用for循环,注:格式上必需为两层括号 for((i=1;i<=10;i+=2)); do echo "Welcome $i times"; done # 示例3:文件循环遍历 for i in /etc/*.conf; do cp $i /backup; done
以下内容测试功能
# add public key sshpass -p 'password' scp mykey.pub user@host:; sshpass -p 'password' ssh user@host "cat mykey.pub >> ~/.ssh/authorized_keys" # remove public key ssh -i mykey user@host "cat ~/.ssh/authorized_keys | sed '/root@server00/d' >> v1.txt; rm -f ~/.ssh/authorized_keys; mv v1.txt ~/.ssh/authorized_keys"
编写成脚本 # password pubkey user ip #!/bin/bash sshpass -p '$1' scp $2 $user@$ip:; sshpass -p '$1' ssh $user@$ip "cat $pk >> ~/.ssh/authorized_keys" # remove public key V1: ssh -i mykey user@host "cat ~/.ssh/authorized_keys | sed '/root@server00/d' >> v1.txt; rm -f ~/.ssh/authorized_keys; mv v1.txt ~/.ssh/authorized_keys" V2: ssh -i mykey user@host "cat ~/.ssh/authorized_keys | sed -i '/root@server00/d' ~/.ssh/authorized_keys"
1. Make data: for a in {1..10}; do echo "ID:$a" >> v0.txt; done; cat v0.txt 2. cat v0.txt | sed '/1/d' >> v1.txt; rm -f v0.txt; mv v1.txt v0.txt sshpass -f $1 ssh $1 "ls" # 使用
# 根据ip列表指定的程序类型,将程序上传至 ip:/etc/fsy 目录下 cat $2 | while read line #读取iplist.txt中的每一行 do if [ ${line:0:2} == 'gw' ];then # 根据是否是gw开头,判断是否为网关 scp -r $1/gateway root@${line:3:20}:$tarpath # 上传网关程序 elif [ ${line:0:2} == 'tm' ];then # 根据是否是tm开头,判断是否为远控 scp -r $1/terminal root@${line:3:20}:$tarpath # 上传远控程序程序 else # 否则为路由程序,上传路由程序 scp -r $1/rcontrol root@${line:0:2}:$tarpath fi done