ssh原理:在SSH安全协议的原理中, 是一种非对称加密与对称加密算法的结合。用于确保远程登录和其他网络服务的会话安全,通过非对称加密、会话加密、多重验证机制等手段,保护数据传输的机密性和完整性。
ssh登录有2种方法:账号密码登录和公钥登录
一、帐号密码登录
没办法公证,不像https有CA证书公证。
1.服务端收到登录请求后,首先互换公钥。
2.客户端用服务端的公钥加密账号密码并发送
3.服务端用自己的秘钥解密后得到账号密码,然后进行验证
4.服务端用客户端的公钥加密验证结果并返回
5.客户端用自己的秘钥解密后得到验证结果
二、ssh免密码登录
利用公钥登录
步骤:
1.客户端用户必须手动地将自己的公钥添加到服务器一个名叫authorized_keys的文件里,顾名思义,这个文件保存了所有可以远程登录的机器的公钥。
2.客户端发起登录请求,并且发送一个自己公钥的指纹(具有唯一性,但不是公钥)
3.服务端根据指纹检测此公钥是否保存在authorized_keys中
4.若存在,服务端便生成一段随机字符串,然后利用客户端公钥加密并返回
5.客户端收到后用自己的私钥解密,再利用服务端公钥加密后发回
6.服务端收到后用自己的私钥解密,如果为同一字符串,则验证通过
三、分发密钥方法
1)ssh分发
ssh-keygen --help
-t type:指定密钥类型,包括“dsa”, “ecdsa” or “rsa”
-p(小) :更改私钥的密码。程序会提示输入私钥的密码以及2次新密码
-P(大):提供私钥的旧密码。
-N:提供私钥的新密码
-f :指定密钥文件的文件名
-b:指定密钥长度
-e:读取openssh的私钥或者公钥文件
ssh-copy-id命令:
ssh-copy-id [-i [identity_file]] [user@]machine
选项:-i 指定要分发的公钥
2 ) 使用expect解决交互式分发
expect脚本中常见命令:spawn, expect, send, interact…
spawn打开一个进程
expect该命令从进程接受字符串,如果接受的字符串和期待的字符串不匹配,则一直阻塞,直到匹配上或者等待超时才继续往下执行
expect会等待特定的输出(如"password:"),然后发送相应的响应(如密码)。
send向进程发送字符串,与手动输入内容等效,通常字符串需要以’\r’结尾
expect{"匹配字符" send {"需要发送的"}
"匹配字符"send{"需要发送的字符"}}
或者
expect "匹配字符"
send "发送字符\r"
interact该命令将控制权交给控制台,之后就可以进行人工操作了。通常用于使用脚本进行自动化登录之后再手动执行某些命令。如果脚本中没有这一条语句,脚本执行完将自动退出。
set timeout 30 设置超时时间timeout为30s,expect命令阻塞超时时会自动往下继续执行。将timeout配置为-1时表示expect一直阻塞直到与期待的字符串匹配上才继续往下执行。超时时间timeout默认为10s
[lindex $argv n]可以在脚本中使用该命令获取在脚本执行时传入的第n-1个参数。argv为传入的参数,另外argc表示传入参数的个数,n是从0开始,表示第一个参数…n=1表示第二个参数
exp_continue:继续执行下面匹配
\r:linux下的回车(Enter键)
安装
yum -y install expect
expect脚本:
[root@localhost ~]# vi ssh.exp
[root@localhost ~]# cat ssh.exp
#!/usr/bin/expect
set timeout 30
set ip [lindex $argv 0] #第1个参数,编号是0
set password [lindex $argv 1] #第2个参数,编号是1
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub root@$ip
expect {
"(yes/no)?" {send "yes\r";exp_continue}
"password:" {send "$password\r"}
}
expect eof
expect /server/script/ssh_expect.exp 192.168.200.10 000000
#192是第1个参数,编号是0 000000是第2个参数,编号是1
实现自动分发,无需手动输入ip及密码,将expect程序嵌套在shell脚本 :
[root@localhost ~]# cat autossh.sh
#!/bin/bash
#########################1.创建密钥##################
. /etc/init.d/functions # 注意. /之间是有空格的,不然就变成"当前目录"的"."了
#/etc/init.d/functions 是一个包含了一系列用于初始化脚本(init scripts)的函数的库文件
#点号(.)是source命令的简写,用于在当前shell环境中执行脚本,而不是创建一个新的子shell
if [ ! -e "/root/.ssh/id_dsa.pub" ];then
ssh-keygen -t dsa -P '' -f /root/.ssh/id_dsa >/dev/null 2>&1
if [ $? -eq 0 ];then
action "创建密钥成功" /bin/true
else
action "创建密钥失败" /bin/false
exit 0
fi
else
action "密钥已存在" /bin/true
fi
######################2.分发密钥####################
for ip in 10.10.102.{129..180} #是一个 Bash 的大括号扩展。它会生成一个序列,从 129 到 180。
do
/usr/bin/expect << EOF > /dev/null 2>&1
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub -p22 $ip
expect {
"yes/no" {send "yes\r";exp_continue}
"password" {send "000000\r"}
}
expect eof
EOF
if [ $? -eq 0 ];then
action "$ip分发密钥完成" /bin/true
else
action "$ip分发密钥失败" /bin/false
fi
done