linux服务器ssh免密登陆
前言
针对某些服务(例如:ansible、部分大数据服务等)需要访问其他服务器,输入命令的访问方式对程序来说不是很友好,所以有必要设置服务器间免密登陆。
一、本机公钥私钥生成
可通过ssh-keygen命令生成公钥及私钥
[root@xxxx ~]# ssh-keygen --help
usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]
[-N new_passphrase] [-C comment] [-f output_keyfile]
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
ssh-keygen -i [-m key_format] [-f input_keyfile]
ssh-keygen -e [-m key_format] [-f input_keyfile]
ssh-keygen -y [-f input_keyfile]
ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]
ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]
ssh-keygen -B [-f input_keyfile]
ssh-keygen -D pkcs11
ssh-keygen -F hostname [-f known_hosts_file] [-l]
ssh-keygen -H [-f known_hosts_file]
ssh-keygen -R hostname [-f known_hosts_file]
ssh-keygen -r hostname [-f input_keyfile] [-g]
ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]
ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]
[-j start_line] [-K checkpt] [-W generator]
ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]
[-O option] [-V validity_interval] [-z serial_number] file ...
ssh-keygen -L [-f input_keyfile]
ssh-keygen -A
ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]
file ...
ssh-keygen -Q -f krl_file file ...
执行ssh-keygen命令,一路敲回车即可。
[root@xxxx ~]# ssh-keygen
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:50lPbV5NyFv9ZwGkr18bYbLLOmy6autrmD+x1Lq7kV0 root@ft-001
The key's randomart image is:
+---[RSA 2048]----+
| .o |
| .....|
| . o.+|
| .. ++|
| S oE.o+o*|
| oo=.+.o+oo|
| +o+.+....o |
| o *. +o o o|
| =XOo+.o+ . |
+----[SHA256]-----+
完成后,会在当前登陆用户的家目录下生成一个ssh的隐藏目录,公钥及私钥默认生成到改路径下。例如:如果是root用户的话,路径为:/root/.ssh/
。
二、配置免密登陆
方法一:通过ssh-copy-id命令实现(推荐使用)
通过ssh-copy-id命令实现
[root@xxxx .ssh]# ssh-copy-id -i id_rsa.pub root@192.168.222.169
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/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.222.169's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.222.169'"
and check to make sure that only the key(s) you wanted were added.
至此即可通过ssh 'root@192.168.222.169'
命令免密登陆。
优点
- 可自动再对端主机上生成authorized_keys文件
- 复制前会比对公钥和authorized_keys文件内容,如果authorized_keys文件中已经包含本机公钥,则不进行复制
- 默认采用追加的方式添加至authorized_keys文件,不会覆盖原文件
方法二:通过scp命令实现
将公钥添加到authorized_keys文件
将公钥添加到authorized_keys文件,如果该文件不存在,则需要在公钥目录下手动创建一个authorized_keys文件。创建authorized_keys文件的命令为:touch authorized_keys
,再通过如下命令将公钥追加到authorized_keys文件即可。
cat id_rsa.pub >> authorized_keys
再将authorized_keys文件拷贝至拷贝至对端服务器即可
scp id_rsa.pub root@192.168.222.169:~/.ssh/
至此即可通过ssh 'root@192.168.222.169’命令免密登陆。
该种方法会直接覆盖对端服务器的authorized_keys文件,执行前请先备份。
方法三:手动拷贝
操作方法同方法二,将scp实现的步骤通过手动拷贝文件实现。不做赘述。
三、配置双向免密登陆
在对端主机上重新执行一、二两步即可完成双向免密登陆。
四、注意事项
- 注意
.ssh/
目录权限需为700 - authorized_keys、id_rsa文件的权限需保持为600
- id_rsa.pub文件的权限需为644
五、可能遇到的问题
-
Are you sure you want to continue connecting (yes/no)?
取消StrictHostKeyChecking
配置完成ssh免密登陆后,第一次通过ssh远程登陆的时候会提示Are you sure you want to continue connecting (yes/no)?
[root@xxxx .ssh]# ssh 'root@192.168.222.159'
The authenticity of host '192.168.222.159 (192.168.222.159)' can't be established.
ECDSA key fingerprint is SHA256:lcxgoc3ZSmJdXR7qZ40zi3ZBZTb/KtzvcdJnSk4+3z4.
ECDSA key fingerprint is MD5:90:ce:5f:ec:c1:0e:fc:c1:87:e2:1f:11:a3:ac:dd:55.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.222.159' (ECDSA) to the list of known hosts.
Last login: Thu Jun 23 11:49:27 2022 from 192.168.222.169
[root@cccc ~]#
如何取消?
方法一
使用带参数的ssh命令跳过StrictHostKeyChecking校验
[root@xxxx .ssh]# ssh -o StrictHostKeyChecking=no 'root@192.168.222.159'
方法二
修改配置文件/etc/ssh/ssh_config
,将# StrictHostKeyChecking yes
改为 StrictHostKeyChecking no
即可
上面这种配置为ssh的全局配置,如果想单独针对某个用户可以将如下配置写到用户家目录的.ssh/config
文件即可
echo "StrictHostKeyChecking no" >> ~/.ssh/config && chmod 600 ~/.ssh/config
- ssh登陆慢
可先用ssh root@192.168.222.159 -vvv
查看出现在哪一步比较慢
例如:出现
debug1: Unspecified GSS failure. Minor code may provide more information
No credentials cache found
出现如上问题可以使用: ssh -o GSSAPIAuthentication=no root@192.168.222.159
解决。也可以通过修改/etc/ssh/ssh_config
文件,将GSSAPIAuthentication yes
改为GSSAPIAuthentication no
即可。同样,也可以使用如下命令针对某个用户单独设置:
echo "GSSAPIAuthentication no" >> ~/.ssh/config && chmod 600 ~/.ssh/config
六、免密登陆自动化配置脚本
#!/bin/bash
set -e
###配置服务器之间的ssh免密登陆###
function get_ip (){
read -p "Please input the Peer IP(remote IP):" Peer_IP
IP_ADDR="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"
chk=`echo $Peer_IP | egrep $IP_ADDR | wc -l`
if [ $chk == 0 ];then
echo "$Peer_IP is not a ip address,Please re-enter your address!"
get_ip
fi
}
function get_name_port (){
read -p "Please input the user you want to login(root default):" login_name
if [ -z $login_name ];then
login_name=root
fi
read -p "Please input the ssh port(22 default):" PORT
if [ -z $PORT ];then
PORT=22
fi
}
function copy_pub (){
if [ $UID == 0 ];then
echo -e "\033[32mPlease input the passwd of $login_name for $Peer_IP \033[0m"
ssh-copy-id -i /root/.ssh/id_rsa.pub $login_name@$Peer_IP -p $PORT
else
dir=`grep -w $UID /etc/passwd | awk -F : '{print $6}'`
echo -e "\033[032mPlease input the passwd of $login_name for $Peer_IP \033[0m"
ssh-copy-id -i $dir/.ssh/id_rsa.pub $login_name@$Peer_IP -p $PORT
fi
}
get_ip
get_name_port
echo -e "\033[33m######################################################\033[0m"
echo -e "\033[32mThe public key and private key are being generated.If \nthere is any confirmation, please press enter directly.\nIf there are prompted that id_RSA already exists,please\nmake a backup before overwriting\033[0m"
echo -e "\033[33m######################################################\033[0m"
ssh-keygen
copy_pub
#!/bin/bash
set -e
input_file=input.txt
# 定义颜色变量
red='\033[0;31m'
yellow='\033[1;33m'
blue='\033[0;34m'
green='\033[0;32m'
NC='\033[0m' # No Color
# 彩色文字输出函数
function echo_color()
{
# 循环读取参数
for ((i=1; i<=$#; i+=2)); do
color=${!i}
content=$(($i + 1))
echo -e -n "${!color}${!content}${NC} "
done
echo;
}
#生成密钥
echo_color "blue" "请按提示输入..."
read -p "是否需要在免密完成后删除${input_file}(y/n):" yyy
ssh-keygen
# 读取文本文件内容
while read -r username password ip_address port; do
echo_color "blue" "************正在配置 $username@$ip_address 的免密登录...************"
#sshpass -p "$password" ssh-copy-id -f -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no -p "$port" "$username@$ip_address"
sshpass -p "$password" ssh-copy-id -f -i -o StrictHostKeyChecking=no -p "$port" "$username@$ip_address"
done < $input_file
ip=`awk '{print $3}' < $input_file`
ips=${ip[*]}
case $yyy in
[yY]|[yY][eE][sS])
rm -f $input_file
echo_color "green" "${ips}免密已配置完成, ${input_file}文件已删除"
;;
*)
echo_color "yellow" "${ips}免密已配置完成, ${input_file}文件未删除,为避免密码信息泄露,建议手动删除该文件"
esac
input.txt文件示例:
root 123456 192.168.1.100 22
mysql 123456 192.168.1.150 55555