zoukankan      html  css  js  c++  java
  • 批量多主机节点间免密登录配置SHEEL脚本

    原文

    一、使用场景

    在进行软件项目的实施部署过程中,经常需要在多个主机节点间登录操作,如果多个主机节点间已经配置了免密登录的话,将会对软件多主机节点实施部署工作效率有很大提高,例如已经免登录配置的服务器可以使用ansible-playbook自动化运维工具进行批量节点操作。那么怎么实现多个主机节点间批量配置免密登录呢?

    二、免密配置

    基于密钥配置主机192.168.1.1与主机192.168.1.2间的SSH免密登录步骤如下:

    1、在192.168.1.1上生成一对密钥(公钥/私钥)

    基于空口令使用ssh-keygen工具生成公钥和私钥生成一个新的ssh密钥,以实现无密码登录:

    ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

    2、在192.168.1.1将公钥发送给主机192.168.1.2,使用ssh-copy-id或scp命令:

    在主机192.168.1.1上用ssh-copy-id命令:

    ssh-copy-id root@192.168.1.2

    或者在主机192.168.1.2上使用scp命令:

    scp root@192.168.1.1:~/.ssh/id_rsa.pub id_rsa.pub.192.168.1.1
    
    cat id_rsa.pub.192.168.1.1 >>~/.ssh/authorized_keys

    注:(1)经过ssh-copy-id后接收公钥的192.168.1.2主机会把公钥追加到对应用户(这里为root)的$HOME/.ssh/authorized_keys文件中;(2)使用scp命令记得需要将id_rsa.pub内容追加到$HOME/.ssh/authorized_keys文件中。

    三、批量配置

    实现步骤如下:

    (1)读取配置文件

    (2)本地密钥对不存在则创建密钥

    (3)登陆到各个主机上,使用ssh-keygen工具生成公钥和私钥

    (4)拷贝将每个主机上的id_rsa.pub拷贝到本地,并汇总至authorized_keys

    (5)将本地authorized_keys分发到每个主机上

    四、脚本实现

    (1)准备配置文件account.txt

    192.168.1.1 root 123321
    192.168.1.2 root 123321
    192.168.1.3 root 123321
    192.168.1.4 root 123321

    (2)免登录配置脚本  (需要安装 expect)

    #!/bin/bash
    ############################################
    # Function :  配置账号免登录(完整版本)
    # Author : tang
    # Date : 2020-04-21
    #
    # Usage: sh auto_ssh_login.sh ./account.txt
    #
    ############################################
     
    FILENAME=$1
    if [ ! -n "$FILENAME" ]; then
            echo "[ERROR]: no host ip address account file supplied!!!"
            echo "Usage : $0 [host_ip_account.txt]"
            exit 1
    fi
     
    # 读取配置文件
    HOSTSADDR=()
    USERNAMES=()
    PASSWORDS=()
    while read line; do
            if [ ! -n "$line" ]; then
                    break 1
            fi
     
            ip=$(echo $line | cut -d " " -f1)        # 提取文件中的ip地址
            user_name=$(echo $line | cut -d " " -f2) # 提取文件中的用户名
            pass_word=$(echo $line | cut -d " " -f3) # 提取文件中的密码
            #echo "IP:$ip    User:$user_name   Password:$pass_word"
     
            if [ ! -n "$ip" ]; then
                    echo "[ERROR]: File content format error,reason get [ip address] empty"
                    exit 1
            fi
            if [ ! -n "$user_name" ]; then
                    echo "[ERROR]: File content format error,reason get [user name] empty"
                    exit 1
            fi
            if [ ! -n "$pass_word" ]; then
                    echo "[ERROR]: File content format error,reason get [password] empty"
                    exit 1
            fi
     
            if [ "$ip" == "$user_name" ]; then
                    echo "[ERROR]: File content format error,reason invalid file format"
                    exit 1
            fi
     
            HOSTSADDR[${#HOSTSADDR[*]}]=$ip
            USERNAMES[${#USERNAMES[*]}]=$user_name
            PASSWORDS[${#PASSWORDS[*]}]=$pass_word
    done <$FILENAME
     
    # 本地密钥对不存在则创建密钥
    [ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -p '' &>/dev/null
     
    # 首先登陆到各个主机上,使用ssh-keygen工具生成公钥和私钥
    echo "#### [1] call ssh-keygen to generate key..."
    for ((i = 0; i < ${#HOSTSADDR[@]}; i++)); do
            ip=${HOSTSADDR[$i]}
            user_name=${USERNAMES[$i]}
            pass_word=${PASSWORDS[$i]}
            echo "IP:$ip    User:$user_name   Password:$pass_word"
     
            expect <<EOF
                    spawn ssh $user_name@$ip "rm -rf  ~/.ssh; ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa -q"
                    expect {
                            "yes/no" { send "yes
    ";exp_continue}     
                            "password" { send "$pass_word
    "}
                    }
                    expect eof 
    EOF
    done
     
    # 其次,拷贝将每个主机上的id_rsa.pub拷贝到本地,并汇总至authorized_keys
    echo "#### [2] copy remote public key to local..."
     
    TMP_AUTHORIZED_KEYS="./.id_rsa.pub.$ip.tmp"
    for ((i = 0; i < ${#HOSTSADDR[@]}; i++)); do
            ip=${HOSTSADDR[$i]}
            user_name=${USERNAMES[$i]}
            pass_word=${PASSWORDS[$i]}
            echo "IP:$ip    User:$user_name   Password:$pass_word"
     
            TMP_FILE="./.id_rsa.pub.$ip.tmp"
            expect <<EOF
                    spawn scp $user_name@$ip:~/.ssh/id_rsa.pub  $TMP_FILE
                    expect {
                            "yes/no" { send "yes
    ";exp_continue}     
                            "password" { send "$pass_word
    "}
                    }
                    expect eof 
    EOF
     
            cat $TMP_FILE >>~/.ssh/authorized_keys
            rm -f $TMP_FILE
    done
     
    # 最后,将本地authorized_keys分发到每个主机上
    echo "#### [3] send local key to each host..."
    for ((i = 0; i < ${#HOSTSADDR[@]}; i++)); do
            ip=${HOSTSADDR[$i]}
            user_name=${USERNAMES[$i]}
            pass_word=${PASSWORDS[$i]}
            echo "IP:$ip    User:$user_name   Password:$pass_word"
     
            CMD="scp /root/.ssh/authorized_keys root@$ip:/root/.ssh/authorized_keys"
            if [ "$user_name" != "root" ]; then
                    CMD="scp /home/$user_name/.ssh/authorized_keys $user_name@$ip:/home/$user_name/.ssh/authorized_keys"
            fi
     
            expect <<EOF
                    spawn $CMD  
                    expect {
                            "yes/no" { send "yes
    ";exp_continue}     
                            "password" { send "$pass_word
    "}
                    }
                    expect eof 
    EOF
    done
     
    echo "[INFO]: config auto ssh success!"
  • 相关阅读:
    jquery插件:web2.0分格的分页脚,可用于ajax无刷新分页
    Application共享数据
    WebClient类
    HttpResponse类
    IEqualityComparer<T>接口
    物理数据库设计 理解浮点数
    Server对象,HttpServerUtility类,获取服务器信息
    Linq to OBJECT之非延时标准查询操作符
    IComparer<T> 接口Linq比较接口
    会话状态Session
  • 原文地址:https://www.cnblogs.com/hei-hei-hei/p/13803806.html
Copyright © 2011-2022 走看看