shell脚本实现免密钥登陆远程主机

目标:实现免密登陆脚本, expect登陆远程主机,将生成的密钥写入到目标主机, expect测试远程登陆

一般免密钥登陆有两步操作

step1:主机上生成公钥和私钥

[root@n72-1 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
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:qzsUaW33T9YCv60HkR9aHKV6z53WBIms9bOmcRU0xa4 root@almalinux9-1.ilvdou.cn
The key's randomart image is:
+---[RSA 3072]----+
|               +=|
|           . ..+o|
|       o    + =+.|
|      + o .o.oo=o|
|     . oS....o*=+|
|      .  .  .oEB*|
|     .  .   .++B=|
|      ..     =+ o|
|      oo    . .o |
+----[SHA256]-----+

step2:将公钥文件id_rsa.pub拷贝到远程主机上

具体实现办法有两种:一种是命令方式,一种是手动在远程目标主机上操作。因为本文的目标是通过shell脚本实现自动化操作,所以选择命令的方式实现

[root@n72-1 ~]# ssh-copy-id root@192.168.35.152
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.35.152 (192.168.35.152)' can't be established.
ECDSA key fingerprint is SHA256:ct7zRI04EP17FuGBPe3bBXXCMCZ7U9T7c1DaUOaAd2E.
ECDSA key fingerprint is MD5:14:e1:0a:37:c5:7b:cf:6f:3e:eb:35:3a:b0:ab:c2:5a.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.35.152's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.35.152'"
and check to make sure that only the key(s) you wanted were added.

[root@n72-1 ~]# ssh root@192.168.35.152
Last login: Tue Dec  6 21:40:34 2022 from 192.168.35.1
[root@almalinux9-1 ~]#

参考文章:Linux 实现密钥免密登录aliaichidantong的博客-CSDN博客linux免密登录

可以看到ssh-keygen命令和ssh-copy-id命令都是交互式命令,要实现自动化执行,还需要用expect工具进行处理。所以一共会有三个文件,一个keygen的expect脚本文件,一个ssh-copy-id我把它命名为doit 的expect脚本文件,另外一个是shell脚本文件,实现常规的bash命令的执行。

shell脚本一步步实现

step1:用expect实现无交互式生成主机的私钥和公钥

keygen.exp文件内容

#!/bin/expect
spawn ssh-keygen -t rsa
expect "Enter file" { send "\n"; exp_continue }
expect "Enter passphrase" { send "\n"; exp_continue }
expect "Enter same passphrase" {send "\n" }
expect eof

step2:用expect实现无交互式的将主机公钥传给远程目标机器

doit.exp文件内容

#!/bin/expect

set ip [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh-copy-id root@$ip
expect {
    "yes/no" { send "yes\n";exp_continue }
    "password" { send "$password\n" }
}
expect eof

step3:多系统兼容,菜单式交互实现动态添加免密钥登陆远程主机

shell脚本文件n72-w3-12.sh

#!/bin/bash
. /etc/os-release

if [[ "$ID" -eq "rocky" || "$ID" -eq "centos" || "$ID" -eq "almalinux" ]]; then
	OSID="centos"
elif [[ "$ID" -eq "ubuntu" ]];then
	OSID="ubuntu"
else
	echo "该脚本仅支持centos系列和Ubuntu系列操作系统,其他系统不支持,谢谢,再见!"
	exit
fi

password="dashuilvdou"

MAIN_MENU="安装MySQL
安装Apache
免密钥登陆主机
退出"

function select_menu_main() {
	PS3="请选择(1-4):"
	select menu in $MAIN_MENU;do
	case $REPLY in
	1)
		install_mysql
		;;
	2)
		install_apache
		;;
	3)
		nokey_login
		;;
	4)
		break
		;;
	*)
		echo -e "\e[1;31m输入错误,请输入正确的数字(1-4)!\e[0m"
		;;
	esac
	done
}

function install_mysql() {
	echo "hello, you have choose to install MySQL application."
	sleep 1
}

function install_apache() {
    echo "hello, you have choose to install apache application."
    sleep 1
}

function nokey_login() {
	while :; do
		echo "1.设置免密钥登陆主机"
		echo "2.免密钥远程登陆"
		echo "输入exit退出"
		read -p "$(echo -e '\033[1;32m请输入你的选项:\033[0m')" option
		
		case $option in
		1)
			set_nokey_login
			;;
		2)
			see_nokey_login
			;;
		"exit")
			break
			;;
		esac
	done
}

function set_nokey_login() {
    check_expect_env
	check_ssh_key
	read -p "$(echo -e '\033[1;32m请输入主机IPLIST:\033[0m')" IPLIST
	read -p "$(echo -e '\033[1;32m请输入密码:\033[0m')" PASSWORD
	if [[ -n "$PASSWORD" ]] ; then password=$PASSWORD; fi
	ssh_copy_id_set $IPLIST
}

function ssh_copy_id_set() {
	until [ -z "$1" ]; do
		expect doit.exp $1 $password
		echo -e "\033[1;32m主机:$1 免密钥远程登陆设置完成。\033[0m"
		shift
	done
	echo
}

function see_nokey_login() {
	read -p "$(echo -e '\033[1;31m请输入远程主机IP:\033[0m')" IP
	expect -c "
    spawn ssh root@$IP;
    expect \"*]#\" { send \"uname -a\r\" }
    send \"exit\r\"
    expect eof
    "
}

function check_ssh_key() {
	if [[ ! -f /root/.ssh/id_rsa.pub ]]; then 
		expect keygen.exp
	fi
}

function check_expect_env() {
    if [[ "$OSID" -eq "centos" ]];then
        rpm -q expect &> /dev/null || yum install -y expect
    else
        dpkg -s expect &> /dev/null || $(apt update; apt install -y expect)
    fi
}
#check_ssh_key

select_menu_main

该脚本可以在RHEL系列如centos、rocky、almalinux和Ubuntu上执行。目前只是实现了菜单的两层交互选择,以及shift对输入参数的动态切换,还有expect免交互的脚本实现。

shell脚本上还预留了一些空白函数,待后续补充,欢迎大家评论区交流。

运维之路漫漫,且行且前进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值