集群SSH免密

编辑SSH脚本

创建免密脚本目录

mkdir /root/sshfree
cd /root/sshfree

写入脚本

vim sshcopy.sh
#!/usr/bin/env bash

basepath=$(cd $(dirname $0 ; pwd))
FILENAME=$1

function check_file (){
printf "[\e[0;34mINFO\e[0m]\e[0;35m	检查ip.txt文件\e[0m\n"
if [ ! -n "${FILENAME}" ]; then
    printf "[\e[0;31mERROR\e[0m]\e[0;35m	未提供ip.txt文件\e[0m\n"
    printf "[\e[0;34mUsage\e[0m]	$0 [\e[0;34mip.txt\e[0m]\n"
    exit 1
fi

IPADDRESS=()
USERNAMES=()
PASSWORDS=()
while read line; do
    if [ ! -n "${line}" ]; then
        printf "[\e[0;31mERROR\e[0m]\e[2;35m ip.txt是空的\e[0m\n"
        break 1
    fi

    ip=$(echo ${line} | cut -d " " -f1)
    user_name=$(echo ${line} | cut -d " " -f2)
    pass_word=$(echo ${line} | cut -d " " -f3)

    if [ "${ip}" == "${user_name}" ]; then
        printf "[\e[0;31mERROR\e[0m]\e[2;35m ip.txt文件内容错误 正确格式 [ip地址 用户名字 用户密码]\e[0m\n"
        exit 2
    fi

    if [ ! -n "${ip}" ]; then
        printf "[\e[0;31mERROR\e[0m]\e[2;35m ip.txt文件内容错误 正确格式 [ip地址 用户名字 用户密码]\e[0m\n"
        exit 3
    fi
    if [ ! -n "${user_name}" ]; then
        printf "[\e[0;31mERROR\e[0m]\e[2;35m ip.txt文件内容错误 正确格式 [ip地址 用户名字 用户密码]\e[0m\n"
        exit 4
    fi

    if [ ! -n "${pass_word}" ]; then
        printf "[\e[0;31mERROR\e[0m]\e[2;35m ip.txt文件内容错误 正确格式 [ip地址 用户名字 用户密码]\e[0m\n"
        exit 5
    fi

    IPADDRESS[${#IPADDRESS[*]}]=${ip}
    USERNAMES[${#USERNAMES[*]}]=${user_name}
    PASSWORDS[${#PASSWORDS[*]}]=${pass_word}
done < ${FILENAME}
}

function create_key () {
[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -p '' &>/dev/null
printf "[\e[0;34mINFO\e[0m]\e[0;35m    调用 ssh-keygen 生成密钥\e[0m\n"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
    ip=${IPADDRESS[$i]}
    user_name=${USERNAMES[$i]}
    pass_word=${PASSWORDS[$i]}

    expect -c "
    spawn ssh ${user_name}@${ip} \"rm -rf ~/.ssh && ssh-keygen -t rsa -N \'\' -f ~/.ssh/id_rsa -q \> /dev/null 2>&1 \"
        expect {
                \"*yes/no*\" {send \"yes\r\"; exp_continue}
                \"*assword*\" {send \"${pass_word}\r\"; exp_continue}
                \"*assword*\" {send \"${pass_word}\r\";}
               }" > /dev/null 2>&1
    if [ $? -eq 0 ];then
        printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m ${ip} 调用 ssh-keygen 生成密钥成功\e[0m\n"
    fi
done
}

function create_key_tmp_file () {
printf "[\e[0;34mINFO\e[0m]\e[0;35m    将公钥复制到本地\e[0m\n"

for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
    ip=${IPADDRESS[$i]}
    user_name=${USERNAMES[$i]}
    pass_word=${PASSWORDS[$i]}

    TMP_FILE="${basepath}/.id_rsa.pub.$ip.tmp"
    expect -c "
    spawn scp $user_name@$ip:~/.ssh/id_rsa.pub  $TMP_FILE
        expect {
                \"*yes/no*\" {send \"yes\r\"; exp_continue}
                \"*assword*\" {send \"$pass_word\r\"; exp_continue}
                \"*assword*\" {send \"$pass_word\r\";}
               }" > /dev/null 2>&1

    cat $TMP_FILE >> ~/.ssh/authorized_keys
    rm -f $TMP_FILE

    if [ $? -eq 0 ];then
        printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m 成功复制 ${ip} 的公钥到本地\e[0m\n"
    fi

done
}

function scp_authorized_keys_file () {
printf "[\e[0;34mINFO\e[0m]\e[0;35m    向每个主机发送本地密钥\e[0m\n"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
    ip=${IPADDRESS[$i]}
    user_name=${USERNAMES[$i]}
    pass_word=${PASSWORDS[$i]}

    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 -c "
    spawn $CMD
        expect {
                \"*yes/no*\" {send \"yes\r\"; exp_continue}
                \"*assword*\" {send \"$pass_word\r\"; exp_continue}
                \"*assword*\" {send \"$pass_word\r\";}
               }" > /dev/null 2>&1

    if [ $? -eq 0 ];then
        printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m 成功发送 ${ip} 的本地密钥到每个主机\e[0m\n"
    fi

done
}

function vimetcsshssh_config () {
printf "[\e[0;34mINFO\e[0m]\e[0;35m    设置本地免认证 /etc/ssh/ssh_config\e[0m\n"
cat >> /etc/ssh/ssh_config << EOF
        UserKnownHostsFile /dev/null
        StricthostKeyChecking no
        Loglevel quiet
#UserKnownHostsFile ~/.ssh/known_hosts
EOF
    if [ $? -eq 0 ];then
        printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m 成功设置本地免认证\e[0m\n"
    fi
}

check_file
create_key
create_key_tmp_file
scp_authorized_keys_file
vimetcsshssh_config

printf "[\e[0;34mINFO\e[0m]\e[0;35m    成功配置自动ssh\e[0m\n"
printf "[\e[0;34mINFO\e[0m]\e[0;35m    手动编辑本机的 /etc/hosts 文件\e[0m\n"
printf "[\e[0;34mINFO\e[0m]\e[0;35m    手动分发本机的 /etc/hosts 文件到所有节点\e[0m\n"
printf "[\e[0;34mINFO\e[0m]\e[0;35m    手动分发本机的 /etc/ssh/ssh_config 文件到所有节点\e[0m\n"

编辑主机文本

分别写入主机IP、账号、密码

vim ip.txt
192.168.123.11 root 123456
192.168.123.12 root 123456
192.168.123.13 root 123456

若数量大可以自动化输入至ip.txt,编辑脚本

vim ip.sh
#!/bin/bash
a=192.168.123.
b=root
c=123456
for j in {1..4}
do
    echo "$a$j $b $c" >> /root/ip.txt
done

然后执行脚本生成txt

sh ip.sh

执行免密脚本

sh sshcopy.sh ip.txt

编辑hosts

vim /etc/hosts

分发hosts、以及ssh配置至所有节点

for i in {066..100}
do
scp /etc/hosts host$i:/etc/hosts
scp /root/.ssh/known_hosts host$i:/root/.ssh/
scp /etc/ssh/ssh_config host$i:/etc/ssh/ssh_config
done