本文主要围绕着 ssh 服务以及如何通过 ssh-copy-id 实现无密码登陆.
1. sshd 服务以及配置 2.ssh-copy-id 命令的使用以及原理. 3. 批量多机互相信任.
SSH(Secure Shell) 是一种能够以安全的方式提供远程登录的协议, 也是目前远程管理 Linux 系统的首选方式. 在此之前, 一般使用 FTP 或 Telnet 来进行远程登录. 但是因为它们以明文的形式在网络中传输账户密码和数据信息, 因此很不安全, 很容易受到黑客发起的中间人攻击, 这轻则篡改传输的数据信息, 重则直接抓取服务器的账户密码.
想要使用 SSH 协议来远程管理 Linux 系统, 则需要部署配置 sshd 服务程序. sshd 是基于 SSH 协议开发的一款远程管理服务程序, 不仅使用起来方便快捷, 而且能够提供两种安全验证的方法:
基于口令的验证 - 用账户和密码来验证登录;
基于密钥的验证 - 需要在本地生成密钥对, 然后把密钥对中的公钥上传至服务器, 并与服务器中的公钥进行比较; 该方式相较来说更安全.
sshd 服务的配置信息保存在 / etc/ssh/sshd_config 文件中, 以下是对于一些常用的配置进行记录.
port 22 | 默认的 sshd 服务端口 |
ListenAddress 0.0.0.0 | 设定 sshd 服务器监听的 IP 地址 |
HostKey /etc/ssh/ssh_host_rsa_key | RSA 私钥存放的位置 |
HostKey /etc/ssh/ssh_host_ecdsa_key | ECDSA 私钥存放的位置 |
HostKey /etc/ssh/ssh_host_ed25519_key | ed25519 私钥存放的位置 |
PermitRootLogin yes | 设定是否允许 root 管理员直接登录 |
StrictModes yes | 当远程用户的私钥改变时直接拒绝连接 |
MaxAuthTries 6 | 最大密码尝试次数 |
MaxSessions 10 | 最大终端数 |
PasswordAuthentication yes | 是否允许密码验证 |
PermitEmptyPasswords no | 是否允许空密码登录(很不安全) |
ssh 命令
常用选项
-p 指定远程主机端口
-i 指定认证文件
-o ConnectionAttempts=NUM 连接失败后重试次数
-o ConnectTimeout=SEC 连接超时时间
-o StrictHostKeyChecking=no 自动去拉取主机 key 文件
-o PasswordAuthentication=no 禁止密码认证
示例:
ssh root@ip -p 端口号
2. ssh-copy-id 命令的使用以及原理,
2.1 生成 "密钥对".
ssh-keygen
常用参数 [-t dsa | ecdsa | ed25519 | rsa | rsa1], 指定加密方式.
示例:
[root@localhost .ssh]# ssh-keygen -t ecdsa
Generating public/private ecdsa key pair.
Enter file in which to save the key (/root/.ssh/id_ecdsa): 按回车键或设置密钥的存储路径
Enter passphrase (empty for no passphrase): 直接按回车键或设置密钥的密码
Enter same passphrase again: 再次按回车键或设置密钥的密码
Your identification has been saved in /root/.ssh/id_ecdsa.
Your public key has been saved in /root/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:yMZjxaP0yC2OQrRPEexfsbMweSPVVEvK88cvqUGA root@localhost.localdomain
- The key's randomart image is:
- +---[ECDSA 256]---+
- | .. ..oo.o |
- | .. .o+oo+ |
- | ... .oEo=o |
- | . ..*=O*o + |
- | o ..%*S+o . |
| . o =.o.. . . |
| . o . . o |
- | . . . |
- | .o |
- +----[SHA256]-----+
- [root@localhost .ssh]# ll
- total 8
- -rw------- 1 root root 227 Jun 10 23:55 id_ecdsa #私钥
- -rw-r--r-- 1 root root 188 Jun 10 23:55 id_ecdsa.pub #公钥
2.2 ssh-copy-id 将公钥上传到远程主机
基于密钥验证, 当我们讲公钥上传到我们需要远程登陆的主机的 authorized_keys 文件后我们就可以直接远程到主机了.
ssh-copy-id 常用选项:
-i 指定公钥文件
示例:
- [root@localhost yum.repos.d]# ssh-copy-id -i /root/.ssh/id_ecdsa.pub root@192.168.123.218
- /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_ecdsa.pub"
The authenticity of host '192.168.123.218 (192.168.123.218)' can't be established.
ECDSA key fingerprint is SHA256:Qh+4R5mpwlU6kK3bf0k53ngm+WpKKnfvL1ZJo+YM3ic.
ECDSA key fingerprint is MD5:d2:76:6d:33:45:e1:23:83:13:aa:10:ce:f7:1f:9f:32.
Are you sure you want to continue connecting (yes/no)? yes #输入 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.123.218's password: #填入密码
- Number of key(s) added: 1
- Now try logging into the machine, with: "ssh'root@192.168.123.218'"
and check to make sure that only the key(s) you wanted were added.
将公钥添加到远程主机后我们可以直接通过密钥登陆了.
我们这里要着重讲下 ssh-copy-id 的这个命令做了什么事.
1. 第一它将本地的主机的公钥添加到远程主机的 authorized_keys 文件里.
2. 第二它将在本地的用户的家目录的 .ssh / 目录下新建了一个 known_hosts 文件.
下面我们来做个实验, 假如我们需要将本地主机到远程主机的信任解除掉, 那么我们需要将远程主机的 authorized_keys 里的本地主机的密钥清除掉.
清除 authorized_keys 里的指定内容后, 我们再用 ssh ip 直接登陆远程主机, 会发现我们再次登陆需要输入密码, 但是我们不需要像第一次远程登陆那样先要输入 yes 再输入密码. 这个是由于本地的 known_hosts 文件导致的, 本地 known_hosts 文件已经将远程主机
的连接信息储蓄在这里了, 当我们清除了里面的远程主机的连接信息的时候, 我们再进行登陆的时候就要 yes 后再输入密码.
如果我们想以后不管远程登陆任何主机都可以直接输入密码不需要那个验证, 那么我们可以修改配置文件达到这个效果.
打开 / etc/ssh/ssh_config 文件:
找到:
# StrictHostKeyChecking ask
修改为
StrictHostKeyChecking no
3. 批量多机互相信任.
我在网上看到一种方法是将所有的主机设置成一样的公钥和私钥, 也就是在一台电脑上面生成密钥文件后, 然后分发到所有的主机中. 这种方法有好处也有坏处, 我们这里用另外一种方法.
思路: 第一步在每个主机上生成密钥后, 并把所有主机的公钥都传输到一台主机的 authorized_keys 文件里, 然后将 authorized_keys 文件再分发到所有主机, 这样就可以实现互相信任了, 但是还是会有一个问题就如何将所有的主机的公钥文件添加到一台主机的 authorized_keys 文件里 (复制下来然后添加进).
主要文件 believe.sh ,sshcopy.exp ,sshkeygen.exp,hosts 文件.(所有文件都在 / root/shell / 目录下)
believe.sh 文件
- #!/bin/bash
- for i in $(cat /root/shell/hosts ) #hosts 文件里包含
- do
- /root/shell/sshkey.exp #判断本地的密钥文件是否存在, 不存在就创建, 存在就退出.
- IP=$(echo "${i}" |awk -F":" '{print $1}')# 匹配出来 IP
- PW=$(echo "${i}" |awk -F":" '{print $2}')# 匹配出来 PW
- /root/shell/sshcopy.exp $IP $PW #复制公钥到远程主机
- scp -p /root/shell/sshkeygen.exp $IP:/root/ #将 sshkeygen.exp 文件复制到远程主机上 ssh root@$IP "yum install expect -y" #在远程主机上安装 expect
- ssh root@$IP "/root/sshkeygen.exp&" #在远程主机运行之前上传的 sshkeygen.exp 脚本, 在远程主机上生成密钥
- ssh root@$IP "cat ~/.ssh/*.pub">>/root/shell/authorized_keys #将远程主机的公钥复制到本地
- done
- for i in $(cat /root/shell/hosts)
- do
- IP=$(echo "${i}" |awk -F":" '{print $1}')
- scp /root/shell/authorized_keys $IP:~/.ssh/authorized_keys #包含所有的主机的公钥文件上传到各台远程主机
- done
sshcopy.exp(脚本的功能是: 将本地的公钥文件上传到远程主机) 该文件本地权限要是 755.
- #!/usr/bin/expect -d #-d 参数是开启调试, 你不需要调试的话可以将他去除.
- set ip [lindex $argv 0]
- set pw [lindex $argv 1]
- set timeout 60
- spawn ssh-copy-id $ip
- expect {
- #"*yes/no" {send "yes\r"; exp_continue} #如果这行注释了, 我们需要在 / etc/ssh/ssh_config 将# StrictHostKeyChecking ask 修改为 StrictHostKeyChecking no.
- "password:" {send "$pw\r"}
- }
- expect eof
sshkeygen.exp(脚本功能是: 判断是否有密钥文件, 有则退出, 没有则创建) 该文件本地权限要是 755.
- #!/usr/bin/expect -d #-d 参数是开启调试, 你不需要调试的话可以将他去除.
- set timeout 90
- spawn ssh-keygen
- expect {
- ".ssh/id_rsa" {send "\r";exp_continue}
- "Overwrite (y/n)?" exit
- "Enter passphrase" {send "\r";exp_continue}
- "Enter same passphrase again:" {send "\r"}
- }
- expect eof
hosts 文件 (包含 ip 和密码, ip 和密码之间以 ":" 间隔)
- 149.28.244.75:*p8V1xG{7)%sQV!
- 149.28.245.101:K(1q@jsvM@UVZtk
以上就可以批量实现主机直接互信 (可以直接远程登陆)
将所有主机的密钥文件设置一致的脚本链接是: http://www.cnblogs.com/kevingrace/p/9063745.html
来源: https://www.cnblogs.com/operationhome/p/9166583.html