万字详解SSH(SSH登录原理+SSH配置+模拟实现SSH免密登录)

Posted 何翰宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了万字详解SSH(SSH登录原理+SSH配置+模拟实现SSH免密登录)相关的知识,希望对你有一定的参考价值。

文章目录


一、SSH概述

ssh是一种用于安全访问远程服务器的协议,远程管理工具。对比起telnet,它更加的安全,那么它是如何保证安全的呢?

1. 加密算法

1)对称加密算法(DES)

  1. 小明想要给小红发送信息一个信息A,为了安全起见,小明使用一种加密算法,比如给信息通过加一个数字B得到一个新的数字C,然后以公开的方式发送给小红
  2. 小红接收到数字C后,通过减去一个数字B得到最终的真正的信息A
  3. 小明发送给小红的信息A称为明文;加密后的信息C称为密文;加密用的B称之为密钥
  4. 加密算法(方法)可以很复杂,不一定是加和减,也可以是乘和除等等

总结:

  • 发送方和接收方使用的是同一个密钥来进行加密和解密

  • 发送方使用密钥明文数据加密成密文,然后发送出去

  • 对称加密里最关键的就是这个密钥,客户端和服务器需要约定好密钥是啥

  • 如果是客户端生成了密钥,就需要通过网络告知服务器,密钥是啥

  • 密钥本身也在网络上文明传输,也容易被黑客获取,一旦被黑客获取到了了,后续的加密就失去了意义。

2)非对称加密(RSA)

引入非对称加密,使用非对称加密来对对称密钥进行加密

  1. 首先小红会生成一对公钥私钥,把公钥公开出去,自己保留私钥
  2. 当小明发送请求的时候,小红会先把自己的公钥发送给小明
  3. 小明拿着小红的公钥通过加密算法将信息A加密成密文C,以公开的方式发送给小红
  4. 小红收到密文C后,通过自己保留的私钥将密文解密成最终的消息A
  5. 这就是非对称加密,加密使用的是公钥,解密使用的是私钥,使用不同的秘钥进行加密和解密

解密:

  • 发送方使用接收方发送过来的公钥明文数据加密成密文,然后发送出去
  • 接收方收到密文后,使用自己本地保留的私钥将密文解密成明文进行读取

3) 对称加密与非对称加密区别

既然都有非对称加密了,为啥还非得用对称加密呢?

  1. 对称加密,成本是比较低(机器资源消耗少),速度也是很快的
  2. 非对称加密,成本比对称加密高很多(机器资源消耗的多),速度也慢
  3. 对称加密使用同一个密钥进行加密和解密,密钥本身也在网络上文明传输,也容易被黑客获取
  4. 非对称加密,加密使用公钥,解密使用私钥。更加安全

4)中间人攻击

通过非对称加密的手段,确实是可以更安全的进行数据传输,但是还有点问题,就是客户端是如何获取到公钥的?

如何保证客户端获取到的公钥是真实可靠的,而不是黑客伪造的?

在https中可以引入证书来抵制中间人攻击问题,那么ssh呢?

2. 环境准备

ip地址主机名称主机身份
192.168.44.129/24jumpserver跳板机
192.168.44.130/24realserver正真正内部服务器

3. SSH基于用户名密码的认证原理

命令:ssh [选项] 远程服务器的用户名@远程服务器的IP地址

认证原理:

  1. SSH服务端向SSH客户端发送了一个登录请求
  2. SSH服务端将自己的公钥发送给SSH客户端

示例:通过跳板机(jump)和主机(realserver)

命令:ssh root@192.168.44.130

如果是第一次访问则会出现一下内容

无法确认主机的真实性

说明

当客户端输入yes确认对方的公钥指纹后,server端的公钥就会被存放到客户机的用户家目录里~/.ssh/known_hosts文件中,下次再访问就直接通过密码登录,不需要再确认公钥。

  1. SSH客户端使用服务端发过来的公钥将自己的密码加密并且发送给SSH服务端
  2. SSH服务端收到SSH客户端发过来的加密密码后使用本地保留的私钥进行解密
  3. SSH服务端将解密出来的密码和/etc/shadow文件里的用户密码对比认证
  4. SSH服务端认证成功,则返回登录成功结果,并发送一个随机会话口令给客户端,该口令用于后面两台主机进行数据传输的一个临时加密会话口令

4. 小结

  • SSH是Linux下远程管理的工具,比telnet更安全
  • SH的全称Secure Shell,安全的shell,是Client/Server架构,默认端口号为22,TCP协议
  • SSH其实用于商业,而OpenSSH即为开源的,在Linux中默认安装

二、模拟SSH服务搭建

1. 搭建思路

  1. 关闭防火墙和selinux
  2. 配置网络yum源或本地yum源
  3. 软件安装和检查
  4. 了解并修改配置文件
  5. 启动服务检查运行状态设置开机自启动

2. VMware环境准备

为了最大程度的保护公司内网服务器的安全,公司内部有一台服务器做跳板机(JumpServer)。运维人员在维护过程中首先要统一登录到这台服务器,然后再登录到目标设备进行维护和操作。由于开发人员有时候需要通过跳板机登录到线上生产环境查看一些业务日志,所以现在需要运维人员针对不同的人员和需求对账号密码进行统一管理,并且遵循权限最小化原则

ip地址主机名称主机身份
192.168.44.132(NAT)+ IPADDR=192.168.80.22(仅主机)jumpserver跳板机
192.168.80.23 (仅主机)realserver正真正内部服务器

3. 通过jumpserver 和 realserver搭建SSH服务器

1. 关闭防火墙和SELinux

关闭防火墙命令:systemctl stop firewalld
关闭防火墙开机自启:systemctl disable firewalld

关闭selinux
命令:setenforce 0
修改配置文件永久关闭
vim /etc/selinux/config
SELINUX=disabled

2.配置yum源

  1. 把jumpserver主机配置外网yum源

    /etc/yum.repos.d/目录下的文件全部打包,再删除除了压缩文件的所有文件

    打包命令:tar -czf CentOS.tar.gz ./*


    配置阿里云yum源
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

    清理yum缓存
    yum clean all
    重新建立缓存
    yum makecache

  2. RealServer配置本地YUM源 => 把光盘镜像作为仓库(自建YUM仓库)
    挂载光盘
    创建目录:mkdir /mnt/cdrom
    挂载:mount -o ro /dev/sr0 /mnt/cdrom

    给开机执行文件添加可执行权限
    命令:chmod +x /etc/rc.local

往开机自启文件里写入开机自动挂载光盘
命令:echo 'mount -o -ro /dev/sr0 /mnt/cdrom' >> /etc/rc.local

rc.local:开机就会执行的文件

备份/etc/yum.repos.d/下的文件,再把这些文及其全部删除

/etc/yum.repos.d下创建一个本地yum源配置文集local.repo 文件
编辑配置文件

#仓库标识,名字随意
[local]
#仓库名称
name=local yum
#仓库路径 file://表示本地路径
baseurl=file:///mnt/cdrom
#是否启动该仓库 1:启动 0:不启动
enabled=1
#是否检测密钥
gpgcheck=0

清空原来的yum缓存:yum clean all
创建新yum缓存:yum makecache
列出可用仓库:yum repolist

3. 配置静态ip

1)JumpServer网卡配置

注意:仅主机模式的ip要和Vmnet1在同一网段
给JumpServer配置两张网卡(NAT模式 + 仅主机模式)

重启网卡:systemctl restart network
查看仅主机模式的网卡:ifconfig

复制NET模式网卡的配置文件ens33,给仅主机模式的网卡ens36配置。
命令:cp ifcfg-ens33 ./ifcfg-ens36


编辑ens36网卡配置文件

TYPE="Ethernet"
BOOTPROTO="static"
IPADDR=192.168.80.22
NETMASK=255.255.255.0
NAME="ens36"
DEVICE="ens36"
ONBOOT="yes"

保存退出,重启网卡
systemctl restart network
关闭NetworkManager
Linux图形化界面中的网络管理器,有些时候我们设置了静态IP。但是重启网络后,其并没有生效或者和你设置的IP地址不一致,很可能是由于NetworkManager工具的影响。

命令:systemctl stop NetworkManager
命令:systemctl disable NetworkManager

2)RealServer网卡配置

注意:仅主机模式的ip要和Vmnet1在同一网段

把NAT模式的网卡更改为仅主机模式,然后设置一个静态IP地址。

编辑/etc/sysconfig/network-scripts下的ens33网卡,保存退出重启网卡

TYPE="Ethernet"
BOOTPROTO="static"
IPADDR=192.168.80.23
NATMASK=255.255.255.0
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"

测试联通性,因为jumpserver和realserver都是仅主机模式,且在同一网段下,就可以ping一下

用jump主机ping一下real主机

4. openssh软件的安装

1) 安装

SSH服务底层的软件名称叫做openssh,open开源,ssh就是ssh服务。openssh属于C/S架构软件,其拥有客户端与服务器端。

客户端:ssh

服务端:openssh-server

把两台机器都安装openssh

命令:yum install openssh -y

检查openssh是否安装成功
命令:rpm -qa | grep openssh或者
yum list installed | grep openssh

2)获取openssh生成的文件列表

命令:rpm -ql openssh-server

# 配置文件
/etc/ssh/sshd_config 
/etc/sysconfig/sshd #ssh服务的主配置文件

# 服务管理脚本
/usr/lib/systemd/system/sshd.service

# 文件共享服务 提供文件上传下载的服务
/usr/libexec/openssh/sftp-server

# 二进制文件程序文件
/usr/sbin/sshd

# 公钥生成工具
/usr/sbin/sshd-keygen

# man手册
/usr/share/man/man5/sshd_config.5.gz
/usr/share/man/man8/sftp-server.8.gz
/usr/share/man/man8/sshd.8.gz


命令:rpm -ql openssh-clients

# 客户端配置文件
/etc/ssh/ssh_config

# 远程copy命令 服务器间进行文件传输
/usr/bin/scp

# sftp客户端  上传下载文件操作
/usr/bin/sftp
/usr/bin/slogin
/usr/bin/ssh
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan
# 客户端man手册
/usr/share/man/man1/scp.1.gz
/usr/share/man/man1/sftp.1.gz
/usr/share/man/man1/slogin.1.gz
/usr/share/man/man1/ssh-add.1.gz
/usr/share/man/man1/ssh-agent.1.gz
/usr/share/man/man1/ssh-copy-id.1.gz
/usr/share/man/man1/ssh-keyscan.1.gz
/usr/share/man/man1/ssh.1.gz
/usr/share/man/man5/ssh_config.5.gz
/usr/share/man/man8/ssh-pkcs11-helper.8.gz

3)查看并修改ssh服务端的配置文件

man 5 sshd_config

禁止realserver机器远程登录root账号

PermitRootLogin => yes or no,默认为yes 代表允许通过root账号远程登录此服务器

修改/etc/ssh/sshd_config第38行配置文件


修改后重启ssh服务,命令:systemctl restart sshd

三、SSH服务任务解决方案

1. 创建用户并授权

JumpServer跳板机创建用户并授权

  1. 第一步:创建用户与用户组(前端组,tom与jerry)

    创建前端组:groupadd html
    创建html组内用户tom和jerry
    useradd -g html
    useradd -g html

  2. 为用户添加密码
    命令:passwd [用户名]

  3. 为开发人员创建数据目录并且设置相应的权限
    创建用户数据目录
    命令:mkdir -p /code/html

    更改目录的文件所属组(更改为html,代表html组内成员可以对这个目录进行管理)

    修改文件所属组命令:chgrp -R html /code/html
    给文件所属组增加可写权限:chgrp g+w /code/html


    添加粘滞位权限,防止误删除操作

    去除其它用户的读写权限:chmod o=- /code/html
    添加粘滞位命令:chmod +t /code/html

2. 测试用户权限

只有自己的文件才可以删除和修改

不是同组的用户无法访问

3. 禁用root远程连接登录

禁止realserver的root用户远程登录
修改配置文件命令:# vim /etc/ssh/sshd_config
PermitRootLogin 设置为no

PermitRootLogin no

4. 更改SSH默认端口

更改realserver机器ssh默认端口号
修改配置文件命令:vim /etc/ssh/sshd_config
修改配置文件的第17行为 端口号为4567

5. 重启SSH服务

systemctl restart sshd

systemctl reload sshd

restart与reload的本质区别:

  1. restart其实相当于stop然后在start

  2. reload不停止现有业务,只是重新加载sshd对应的配置文件

6. 在RealServer创建一个hhy账号测试ssh

命令:useradd hhy
随意设置一个密码

测试从jumpserver远程连接realserver的hhy账号

命令:ssh -p 4567 hhy@192.168.80.23
-p:指定端口号

前面修改了端口号为4567,所以要指定端口号。默认的22就不需要指定

7. SSH客户端不验证指纹

第一次连接远程服务器时:

如果我们不想验证指纹
修改配置文件:vim /etc/ssh/ssh_config

第35行

改为 StrictHostKeyChecking no

8. 专业工具pwgen生成用户密码

其用户密码一定不要手工设置,建议使用专业的密码生成工具如pwgen。

先配置EPEL源
命令:wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
清楚yum缓存:yum clean all
建新缓存:yum makecache

安装pwgen密码生成工具
命令:yum -y install pwgen -y

使用pwgen密码生成工具

命令:pwgen -cnBs1 10 1

pwgen用法

# pwgen --help
# 用法: pwgen 选项参数 长度 生成个数
Usage: pwgen [ OPTIONS ] [ pw_length ] [ num_pw ]

# 密码中至少包含一个大写字母
-c or –capitalize

# 密码中不包含大写字母
-A or –no-capitalize

# 密码中至少包含一个数字
-n or –numerals

# 密码中不包含数字
-0 or –no-numerals

# 密码中至少包含一个特殊符号
-y or –symbols

# 生成完全随机密码
-s or –secure

# 密码中不包含歧义字符(例如1,l,O,0-B or –ambiguous

# 使用SHA1 hash给定的文件作为一个随机种子
-H or –sha1=path/to/file[#seed]

# 在列中打印生成的密码
-C

# 不要在列中打印生成的密码,即一行一个密码
-1

# 不要使用任何元音,以避免偶然的脏话
-v or –no-vowels

9. 踢出用户

查看当前在线用户


踢出某个账号
命令:pkill -kill -t pts/1

四、SSH免密登录解决方案

1. ssh连接

jumpserver 连接=> ssh hhy@realserver的ip地址


基于密钥对的认证方式


A主机 => JumpServer,B主机 => RealServer

第一步:在A主机(JumpServer)生成一个密钥对(公钥和私钥)

第二步:把A主机的公钥通过网络拷贝到B主机(RealServer)上,然后把其内容追加到B主机的~/.ssh/authorized_keys

第三步:由A主机(JumpServer)向B主机(RealServer)发起登录请求,然后直接在B主机上进行公钥比对(判断A主机的公钥是否已经存储在B主机的authorized_keys文件中),如果存在且正确,则生成一个随机的字符串(如itcast),然后使用A主机的公钥对其加密得到加密的后字符串(如dXdh,34njasz!z.)

第四步:通过网络,由B主机讲刚才生成的加密后的字符串传输给主机A,主机A接收到加密后的字符串以后,使用自己本地存储的私钥进行解密操作(得到hhy)

第五步:把解密得到的itcast发送到B主机,然后验证与刚才生成的字符串是否一致,如果一致,返回登录成功。反之,则返回登录失败。

到此免密登录全部完成!

2. SSH免密登录的具体实现

SSH免密的实现思路一共分为三个步骤(三步走)

第一步:在A主机针对某个账号(tom或jerry)生成公钥与私钥

第二步:使用某些方法把公钥发送到B主机中,然后追加到authorized_keys文件中

第三步:测试是否实现免密登录

1. 方法1(常用)

  1. 在 jumpserver的tom用户生成公钥和私钥

    命令:ssh-keygen
    一路回车就好

    查看公钥和私钥
    ~/.ssh/

  2. 使用ssh-copy-id把公钥文件中的内容传输到服务器端的~/.ssh/authorized_keys文件中

命令:ssh-copy-id hhy@192.168.80.23

  1. 在JumpServer客户端测试免密登录是否成功

2. 方法2(集群常用)

这里使用另一个用户jerry

  1. 生成公钥和私钥
    命令:ssh-keygen

如果不想一路确认,可以在ssh-keygen -P “”,直接生成公私钥


2. 把id_rsa.pub文件,scp到RealServer服务器端

3. 在RealServer服务器端,把id_rsa.pub文件中的内容追加到~/.ssh/authorized_keys文件中

命令:cat id_rsa.pub >> ~/.ssh/authorized_keys

**注意:**以上配置也比较简单,但是实际应用时要注意文件的权限


4. 测试免密是否成功

命令:ssh hhy@192.168.80.23

以上是关于万字详解SSH(SSH登录原理+SSH配置+模拟实现SSH免密登录)的主要内容,如果未能解决你的问题,请参考以下文章

[原创] SSH免密登录设置----原理详解

Linux——超超讲解SSH的原理与SSH的实现!建议收藏❤

ssh配置文件详解

SSH无密码登录的原理及配置

SSH原理 and SSH远程登录

python paramiko模拟ssh登录