当前位置: 首页 > news >正文

批量实现多台服务器之间ssh无密码登录的相互信任关系

 

最近IDC上架了一批hadoop大数据业务服务器,由于集群环境需要在这些服务器之间实现ssh无密码登录的相互信任关系具体的实现思路:在其中的任一台服务器上通过"ssh-keygen -t rsa"产生公私钥文件,然后将公钥文件拷贝成authorized_keys文件,最后将它的.ssh目录下的文件全部批量拷贝到其他服务器的/root/.ssh目录(即当前用户家目录的.ssh)下即可。这批hadoop服务器的ssh端口默认都是22,密码默认都是kevin123456,ip列表如下:

192.168.10.202
192.168.10.203
192.168.10.205
192.168.10.206
192.168.10.207
192.168.10.208

注意:批量部署信任关系后,目标机器的公私钥文件id_rsa和id_rsa.pub会被覆盖,但是authorized_keys文件不会被覆盖,只会进行新内容追加,所以如果目标机器之前做了别的信任关系,在新的信任关系做好后,老的信任关系不会丢失。

1)方法一(适用于机器数量不算多的情况下)

首先在其中任一台服务器,如192.168.10.202上生产公私钥文件:
[root@server-202 ~]# ssh-keygen -t rsa
[root@server-202 ~]# ls /root/.ssh/
id_rsa  id_rsa.pub
[root@server-202 ~]# cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
[root@server-202 ~]# ls /root/.ssh/
authorized_keys  id_rsa  id_rsa.pub
[root@server-202 ~]# vim /root/hosts
192.168.10.202
192.168.10.203
192.168.10.205
192.168.10.206
192.168.10.207
192.168.10.208
[root@server-202 ~]# for i in `cat /root/hosts`;do rsync -e "ssh -p22" -avpgolr /root/.ssh root@$i:/root/;done
执行该命令后,需要多次手动输入密码

执行后,这些机器之间就可以通过ssh密码登录了,即实现了相互信任关系。检查下这些机器的/root/.ssh目录,发现他们的公私钥文件都是192.168.10.202这台机器的。
该种方法仅适用于少数服务器的情况,因为涉及到中途人工交互(输入密码等),如果服务器数量众多的情况下,适用这种方式就比较傻X了,这就需要用到下面这种方法。

2)方法二(使用expect工具,适用于机器数量众多的情况下)
expect是交互性很强的脚本语言,可以帮助运维人员实现批量管理成千上百台服务器操作,是一款很实用的批量部署工具!expect依赖于tcl,而linux系统里一般不自带安装tcl,所以需要手动安装。选择其中的任意一台服务器上操作,比如这里还是选择192.168.10.202这台机器。expect-5.43.0.tar和tcl8.4.11-src.tar的下载地址:https://pan.baidu.com/s/1kVyeLt9       提取密码:af9p

将expect和tcl的软件包下载放到/usr/local/src目录下,解压tcl,进入tcl解压目录,然后进入unix目录进行编译安装
[root@server-202 ~]# cd /usr/local/src/
[root@server-202 src]# tar -zvxf tcl8.4.11-src.tar.gz
[root@server-202 src]# cd tcl8.4.11/unix
[root@server-202 unix]# ./configure
[root@server-202 unix]# make && make install
 
安装expect
[root@server-202 src]# tar -zvxf expect-5.43.0.tar.gz
[root@server-202 src]# cd expect-5.43.0
[root@server-202 expect-5.43.0]# ./configure --with-tclinclude=/usr/local/src/tcl8.4.11/generic --with-tclconfig=/usr/local/lib/
[root@server-202 expect-5.43.0]# make && make install
 
安装完成后进行测试
[root@server-202 ~]# expect
expect1.1>
 
[root@server-202 ~]# which expect
/usr/local/bin/expect
 
做个expect执行文件的软件
[root@server-202 ~]# ln -s /usr/local/bin/expect /usr/bin/expect
[root@server-202 ~]# ll /usr/bin/expect
 
批量实现信任关系的脚本如下:
[root@server-202 ~]# vim /opt/ssh_auth.sh
#!/bin/sh 
DEST_USER=$1 
PASSWORD=$2 
HOSTS_FILE=$3 
if [ $# -ne 3 ]; then 
    echo "Usage:" 
    echo "$0 remoteUser remotePassword hostsFile" 
    exit 1 
fi 
   
SSH_DIR=~/.ssh 
SCRIPT_PREFIX=./tmp 
echo =========================== 
 
# 1. prepare  directory .ssh 
mkdir $SSH_DIR 
chmod 700 $SSH_DIR 
   
# 2. generat ssh key 
TMP_SCRIPT=$SCRIPT_PREFIX.sh 
echo  "#!/usr/bin/expect">$TMP_SCRIPT 
echo  "spawn ssh-keygen -b 1024 -t rsa">>$TMP_SCRIPT 
echo  "expect *key*">>$TMP_SCRIPT 
echo  "send \r">>$TMP_SCRIPT 
if [ -f $SSH_DIR/id_rsa ]; then 
    echo  "expect *verwrite*">>$TMP_SCRIPT 
    echo  "send y\r">>$TMP_SCRIPT 
fi 
echo  "expect *passphrase*">>$TMP_SCRIPT 
echo  "send \r">>$TMP_SCRIPT 
echo  "expect *again:">>$TMP_SCRIPT 
echo  "send \r">>$TMP_SCRIPT 
echo  "interact">>$TMP_SCRIPT 
   
chmod +x $TMP_SCRIPT 
   
/usr/bin/expect $TMP_SCRIPT 
rm $TMP_SCRIPT 
   
# 3. generat file authorized_keys 
cat $SSH_DIR/id_rsa.pub>>$SSH_DIR/authorized_keys 
   
# 4. chmod 600 for file authorized_keys 
chmod 600 $SSH_DIR/authorized_keys 
echo =========================== 
 
# 5. copy all files to other hosts 
for ip in $(cat $HOSTS_FILE)   
do 
    if [ "x$ip" != "x" ]; then 
        echo ------------------------- 
        TMP_SCRIPT=${SCRIPT_PREFIX}.$ip.sh 
        # check known_hosts 
        val=`ssh-keygen -F $ip` 
        if [ "x$val" == "x" ]; then 
            echo "$ip not in $SSH_DIR/known_hosts, need to add" 
            val=`ssh-keyscan $ip 2>/dev/null` 
            if [ "x$val" == "x" ]; then 
                echo "ssh-keyscan $ip failed!" 
            else 
                echo $val>>$SSH_DIR/known_hosts 
            fi 
        fi 
        echo "copy $SSH_DIR to $ip" 
                   
        echo  "#!/usr/bin/expect">$TMP_SCRIPT 
        echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT 
        echo  "expect *assword*">>$TMP_SCRIPT 
        echo  "send $PASSWORD\r">>$TMP_SCRIPT 
        echo  "interact">>$TMP_SCRIPT 
           
        chmod +x $TMP_SCRIPT 
        #echo "/usr/bin/expect $TMP_SCRIPT" >$TMP_SCRIPT.do 
        #sh $TMP_SCRIPT.do& 
       
        /usr/bin/expect $TMP_SCRIPT 
        rm $TMP_SCRIPT 
        echo "copy done."                 
    fi 
done 
   
echo done.
 
 
在上面脚本文件的同目录下新建名为host的文件,将要建立ssh互信的机器名或ip地址添加到该文件中,每个机器名或ip占一行,如:
[root@server-202 ~]# vim /opt/host
192.168.10.202
192.168.10.203
192.168.10.205
192.168.10.206
192.168.10.207
192.168.10.208
 
最后就可以运行这个脚本ssh_auth.sh文件,ssh_auth.sh接受三个参数,远程机器用户名、密码和host文件名(相对路径或绝对路径均可)。
[root@server-202 ~]# sh /opt/ssh_auth.sh root kevin123456 /opt/host
 
然后查看下其他服务器,发现.ssh目录下的文件和192.168.10.202机器的.ssh目录下的文件一致。
最后就可以在这些机器之间进行相互信任的ssh无密码跳转登录了!
 
==========================================================================
注意:上面脚本针对的是服务器ssh端口是22的情况,如果ssh是非22端口,比如是22222端口。
则只需要在ssh_auth.sh脚本中修改下面两行内容:
[root@server-202 ~]# cp /opt/ssh_auth.sh /opt/ssh_auth.sh.bak
[root@server-202 ~]# vim /opt/ssh_auth.sh              #注意下面一个小写p,一个大写P
.......
val=`ssh-keyscan $ip 2>/dev/null`
修改为
val=`ssh-keyscan -p 22222 $ip 2>/dev/null`
.......
echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT
修改为
echo  "spawn scp -P 22222 -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT
 
[root@server-202 ~]# diff /opt/ssh_auth.sh /opt/ssh_auth.sh.bak
57c57
<             val=`ssh-keyscan -p 22222 $ip 2>/dev/null` 
---
>             val=`ssh-keyscan $ip 2>/dev/null` 
67c67
<         echo  "spawn scp -P 22222 -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT 
---
>         echo  "spawn scp -r  $SSH_DIR $DEST_USER@$ip:~/">>$TMP_SCRIPT
 
最后执行脚本,进行相互信任关系批量部署即可
[root@server-202 ~]# sh /opt/ssh_auth.sh root kevin123456 /opt/host

相关文章:

  • 与Bob McWhirter的问答:WildFly Swarm更名为Thorntail项目
  • AsyncTask实现原理
  • 最简单的无缝轮播
  • c中perror函数
  • 小身材超能量Oracle新一代数据库机帮助所有规模企业迈向云端
  • Confluence 6 注册单一小工具
  • Redis分布式锁的try-with-resources实现
  • shell脚本案例(五)利用nmap批量扫描存活主机
  • Echarts关于仪表盘
  • mysql 查询当天、本周,本月,上一个月的数据---https://www.cnblogs.com/benefitworld/p/5832897.html...
  • php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中)...
  • linux---文件颜色含义
  • echarts学习笔记 各图配置(折线图、圆环图、柱形图、折线面积图)
  • 如何查看一个网页特定效果的js代码(动画效果可js和css)(页面可以看到js的源代码)...
  • (转)创业的注意事项
  • 「译」Node.js Streams 基础
  • 5、React组件事件详解
  • Android交互
  • android图片蒙层
  • CSS 提示工具(Tooltip)
  • express + mock 让前后台并行开发
  • flutter的key在widget list的作用以及必要性
  • javascript 哈希表
  • JAVA之继承和多态
  • js ES6 求数组的交集,并集,还有差集
  • JS 面试题总结
  • Swift 中的尾递归和蹦床
  • 工程优化暨babel升级小记
  • 码农张的Bug人生 - 见面之礼
  • 再次简单明了总结flex布局,一看就懂...
  • MPAndroidChart 教程:Y轴 YAxis
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​决定德拉瓦州地区版图的关键历史事件
  • #1015 : KMP算法
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (4.10~4.16)
  • (python)数据结构---字典
  • (第二周)效能测试
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (转)甲方乙方——赵民谈找工作
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Framework杂记
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET6实现破解Modbus poll点表配置文件
  • .NET使用存储过程实现对数据库的增删改查
  • .NET下ASPX编程的几个小问题
  • /etc/fstab 只读无法修改的解决办法
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [2016.7.Test1] T1 三进制异或