1 openssh详解

1.1 什么是openssh

OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件。而实现此功能的传统方式,如telnet(终端仿真协议)、 rcp ftp、 rlogin、rsh都是极为不安全的,并且会使用明文传送密码。OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输过程中的数据,并由此来代替原来的类似服务

  • 延伸:
    • ssh协议有两个版本:
      v1:基于CRC-32 做MAC,不安全; (一般用于实现主机认证)
      v2:基于协议协商选择双方都支持的最安全的MAC机制
      基于DH做密钥交换,基于RSA或DSA实现身份认证,从而实现无需输入账号面膜
      客户端通过检查服务器端的主机秘钥来判断是否能够继续通信;
    • 认证方式:
      1、基于口令的认证
      2、基于密钥的认证

1.2 为什么要使用openssh

由于传统的telnet、rcp ftp等工具是明文传输数据的,对数据安全性存在很大的安全隐患,而OpenSSH可以对传输的数据进行加密从而大大提高了数据的安全性

1.3 openssh工作原理

openSSH是基于C/S架构工作的

服务器端    //sshd,配置文件在/etc/ssh/sshd_config
客户端     //ssh,配置文件在/etc/ssh/ssh_config
    ssh-keygen      //密钥生成器
    ssh-copy-id     //将公钥传输至远程服务器
    scp             //跨主机安全复制工具
  1. 服务器建立公钥: 每一次启动 sshd 服务时,该服务会主动去找 /etc/ssh/ssh_host* 的文件,若系统刚刚安装完成时,由于没有这些公钥,因此 sshd 会主动去计算出这些需要的公钥,同时也会计算出服务器自己需要的私钥
  2. 客户端主动联机请求: 若客户端想要联机到 ssh 服务器,则需要使用适当的客户端程序来联机,包括 ssh, putty 等客户端程序连接
  3. 服务器传送公钥给客户端: 接收到客户端的要求后,服务器便将第一个步骤取得的公钥传送给客户端使用 (此时应是明码传送,反正公钥本来就是给大家使用的)
  4. 客户端记录并比对服务器的公钥数据及随机计算自己的公私钥: 若客户端第一次连接到此服务器,则会将服务器的公钥记录到客户端的用户家目录内的 ~/.ssh/known_hosts 。若是已经记录过该服务器的公钥,则客户端会去比对此次接收到的与之前的记录是否有差异。若接受此公钥, 则开始计算客户端自己的公私钥
  5. 回传客户端的公钥到服务器端: 用户将自己的公钥传送给服务器。此时服务器:具有服务器的私钥与客户端的公钥,而客户端则是: 具有服务器的公钥以及客户端自己的私钥,你会看到,在此次联机的服务器与客户端的密钥系统 (公钥+私钥) 并不一样,所以才称为非对称加密系统
  6. 开始双向加解密: (1)服务器到客户端:服务器传送数据时,拿用户的公钥加密后送出。客户端接收后,用自己的私钥解密 (2)客户端到服务器:客户端传送数据时,拿服务器的公钥加密后送出。服务器接收后,用服务器的私钥解密,这样就能保证通信安全

在这里插入图片描述

1.4 OpenSSH程序简介

1.4.1 OpenSSH的分为客户端和服务端两部分

 Clients端的配置文件:/etc/ssh/ssh_config
Server端的配置文件:/etc/ssh/sshd_config
Server端服务脚本:/etc/rc.d/init.d/sshd

OpenSSH在Linux系统中默认是安装并启动的

  1. openssh 主要的关键包
    openssh.x86_64 5.3p1-104.el6 //服务端和客户端的公共组件
    openssh-askpass.x86_64 5.3p1-104.el6 //
    openssh-clients.x86_64 5.3p1-104.el6 //客户端安装包
    openssh-server.x86_64 5.3p1-104.el6 //服务端安装包

  2. openssl-clients 几个常用文件
    /etc/ssh/ssh_config //客户端配置文件
    /usr/bin/scp //远程复制文件
    /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

  3. openssl-server 几个常用文件
    /etc/rc.d/init.d/sshd
    /etc/ssh/sshd_config
    /etc/sysconfig/sshd

1.4.2 服务器端配置文件/etc/ssh/sshd_config 主要参数详解

服务端配置文件是让别人登陆时使用的,配置文件中使用“#”注释掉的一般就是使用默认

参数说明
#Port 22默认端口号,为了其安全一般要更改为其他端口
#AddressFamily any说明要监听任意地址
#ListenAddress 0.0.0.0监听本机所有IPV4的ip
#ListenAddress ::监听本机所有的IPV6的地址
#LoginGraceTime 2m登陆宽限时长 默认2分钟不登录自动关闭
#PermitRootLogin yes是否支持管理员直接登陆
#MaxAuthTries 6最大尝试次数 (6次以后终端断开)
#MaxSessions 10最大并发允许链接数 (超过 将拒绝)
#RSAAuthentication yes是否支持RSA密钥认证
#PubkeyAuthentication yes是否支持公钥认证
#AuthorizedKeysFile .ssh/authorized_keys默认保存口令的文件
#PermitEmptyPasswords no是否支持空密码登陆

1.4.3 客户端配置文件/etc/ssh/ssh_config 主要参数详解

客户端配置文件时登陆别人的ssh使用的

参数说明
#Host *表示连接所有主机
#Port 22默认连接端口
#Cipher 3des加密时使用的加密机制
#StrictHostKeyChecking ask严格的主机秘钥检查 即第一次连接时是否询问

1.5 口令认证

以服务器中本地系统用户的登录名称、密码进行验证。从客户机的角度看,正在连接的服务器有可能被假冒;从服务器角度来看,当遭遇密码穷举攻击时防御能力较弱
在这里插入图片描述

  1. client端向server端发去连接请求
  2. server接受请求并向client端发送自己的主机公钥
  3. client输入密码,并使用server端公钥加密后发送给server(敏感信息安全传输)
  4. server接受加密的密码,使用私钥解密,匹配认证密码是否合法。合法则登录成功。

1.6 密钥对认证

首先客户端上的用户会在客户端生成一对密钥,并将自己的公钥上传到远程服务器上面(一般在对应用户的home目录下),自己保留私钥信息,之后在我们使用ssh命令远程登录服务器的时候,只需要我们输入远程服务器上面对应的用户名,而不需要再输入密码就可以进行登录
在这里插入图片描述

  1. 客户端生成一对密钥,并将公钥上传至服务端(~/.ssh/authorized_keys)
  2. 客户端请求连接,包含主机名和当前用户
  3. 服务端从authorized_keys中查找是否有用户信息,如果有则向客户端发送一段随机字符串,并用客户端的公钥进行加密
  4. 客户端用自己的私钥对随机字符串进行解密,并返还给服务端
  5. 服务端将解密后的字符串与之前发送的字符串进行比对,如一致则验证通过

公钥(Public Key)与私钥(Privtae Key)的关系

公钥与私钥是成对生成,这两个密钥互不相同,可以互相加密与解密。
不能根据一个密钥来推算出另一个密钥。
公钥对外公开,私钥只有私钥的持有人才知道。
公钥与私钥要配对使用,如果用公钥对数据进行加密,只有用相对就的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密

1.7 SSH知识总结

1.7.1 SSH的加密技术

加密技术:传输过程,数据加密。
1.SSH1没有对客户端的秘钥进行校验,很容易被植入恶意代码
2.SSH2增加了一个确认联机正确性的Diffe_Hellman机制,每次数据的传输,Server都会检查数据来源的正确性,避免黑客入侵。
SSH2支持RSA和DSA密钥
DSA:digital signature Algorithm 数字签名
RSA:既可以数字签名又可以加密

1.7.2 SSH常识

  1. SSH是安全的加密协议,用于远程连接Linux服务器
  2. SSH的默认端口是22,安全协议版本是SSH2
  3. SSH服务器端主要包含2个服务功能SSH连接和SFTP服务器
  4. SSH客户端包含ssh连接命令和远程拷贝scp命令等

1.7.3 如何防止SSH登录入侵

  1. 自定义 SSH 服务配置
[root@node1 ~]# cat /etc/ssh/sshd_config
PermitRootLogin {yes|no}    //是否允许root用户远程登录系统
PermitRootLogin without-password    //仅允许root用户基于密钥方式远程登录
PasswordAuthentication {yes|no}     //是否启用密码身份验证,默认开启
  1. SSH 安全注意事项
  • 密码应该经常换且足够复杂
[root@node1 ~]# tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30 | xargs   //生成30位的密码
oTchjzhwEZK5s7XCQ50Fnj9r0vX7gQ
[root@node1 ~]# openssl rand 20 -base64  //生成20位随机密码
Di9ry+dyV40xVvBHirsc3XpBOzg=    
  • 使用非默认端口,修改默认端口为其他端口)

  • 限制登录客户端地址

  • 仅监听特定的IP地址

  • 禁止管理员直接登录

  • 仅允许有限制用户登录
    AllowUsers:允许登陆的用户白名单 (多个用户使用空格隔开)
    AllowGroups:允许登陆的组的白名单

  • 使用基于密钥的认证

  • 禁止使用空密码

  • 禁止使用SSHv1版本

  • 设定空闲会话超时时长

  • 利用防火墙设置ssh访问策略

  • 限制ssh的访问频度和并发在线数

  • 做好日志的备份,经常分析(集中于某台服务器)

2 登录验证方式

1、ssh的基本语法
ssh [OPTIONS] [user]@server [COMMAND]

        -l user: 以指定用户身份连接至服务器;默认使用本地用户为远程登录时的用户;
            ssh user@server
            ssh -l user server
        -p PORT:指明要连接的端口
        -X   启用X11Forwarding,即转发X界面的请求;
        -x: 禁用;
        -Y:  启用信任的X11Forwarding

2、ssh 基于秘钥的认证
ssh-keygen语法:
ssh-keygen [OPTIONS]

        -t {rsa|dsa} 密钥类型 一般使用rsa
        -b # 指明密钥长度
        -f /PATH/TO/OUTPUT_KEYFILE  指明密钥文件
        -P '' :指明加密密钥的密码,表示使用空密码

2.1 密码验证(口令认证)

2.1.1 准备两台虚拟机,一台作为客户端,一台作为服务端,用客服端远程连接服务端

[root@node1 ~]# ssh root@192.168.25.110   ##root为服务端的用户,##192.168.25.110为服务端地址
The authenticity of host '192.168.25.110 (192.168.25.110)' can't be established.
ECDSA key fingerprint is SHA256:GnK28SJbU4C8Op2rmLAg5lcSBpfM/oeTUSmq0QkfdJY.
ECDSA key fingerprint is MD5:5a:a5:35:49:b5:d0:1d:ce:f0:16:8a:b6:68:f2:d9:3d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.25.110' (ECDSA) to the list of known hosts.
root@192.168.25.110's password:      ##输入root用户的密码
[root@node2 ~]$    ##此时由客户端成功连接到服务端

2.1.2 修改服务端ssh服务的配置文件,对客服端远程登录进行限制

[root@node2 ~]# vim /etc/ssh/sshd_config 
37 LoginGraceTime 2m
 38 PermitRootLogin no   ##不允许root用户登录
 39 StrictModes yes
 40 MaxAuthTries 6   ##最大失败连接次数
 41 MaxSessions 10
 42 AllowUsers tom ##只允许tom用户远程登录,相当于白名单
[root@node2 ~]# systemctl restart sshd   ##修改完配置文件需重启服务

2.1.3 客户端登录权限的验证

[root@node1 ~]# ssh harry@192.168.25.110
harry@192.168.25.110's password: 
Permission denied, please try again.  ##用harry用户登录,权限被拒
[root@node1 ~]# ssh root@192.168.25.110
root@192.168.25.110's password: 
Permission denied, please try again.  ##用root用户登录,权限被拒

[root@node1 ~]# ssh tom@192.168.25.110
tom@192.168.25.110's password: 
Last login: Thu Jul  9 11:27:11 2020 from 192.168.25.110
[tom@node2 ~]$   ##tom用户成功远程连接
##注意:虽然root用户被禁止远程登录,但可通过tom用户作为中间用户来进行切换,只要知道root用户的密码就可以##

[tom@node2 ~]$ su - root
Password:    ##输入root的密码##
Last login: Thu Jul  9 11:42:12 CST 2020 on pts/0
Last failed login: Thu Jul  9 11:54:05 CST 2020 from 192.168.25.110 on ssh:notty
There was 1 failed login attempt since the last successful login.
[root@node2 ~]#   ##成功由tom用户切换为root用户
##如要解决此bug需要在服务端开启pam认证,不给tom用户使用su命令切换用户的权限##
[root@node2 ~]# vim /etc/pam.d/su

 1 #%PAM-1.0
  2 auth            sufficient      pam_rootok.so
  3 # Uncomment the following line to implicitly trust users in the "wheel" group.
  4 #auth           sufficient      pam_wheel.so trust use_uid
  5 # Uncomment the following line to require a user to be in the "wheel" group.
  6 auth            required        pam_wheel.so use_uid  ##把此行的注释去掉
  7 auth            substack        system-auth
  8 auth            include         postlogin
  9 account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
 10 account         include         system-auth
 11 password        include         system-auth
 12 session         include         system-auth
 13 session         include         postlogin
 14 session         optional        pam_xauth.so
###修改为后再用tom用户进行切换就没有权限了
[root@node1 ~]# ssh tom@192.168.25.110
tom@192.168.25.110's password: 
Last login: Thu Jul  9 11:55:02 2020 from 192.168.25.110

[tom@node2 ~]$ su - root
Password: 
su: Permission denied
[tom@node2 ~]$ 

2.2 密钥对验证

  • 用户可通过使用公钥身份验证进行ssh登录身份验证。ssh允许用户使用私钥-公钥方案进行身份验证。这意味着将生成私钥和公钥这两个密钥。私钥文件用作身份验证凭据,像密码一样,必须妥善保管。公钥复制到用户希望登录的系统,用于验证私钥。公钥并不需要保密。拥有公钥的ssh服务器可以发布仅持有您私钥的系统才可解答的问题。因此,可以根据所持有的密钥进行验证。如此一来,就不必在每次访问系统时键入密码,但安全性仍能得到保证。

  • 使用ssh-keygen命令生成密码。将会生成私钥/.ssh/id_rsa和公钥/.ssh/id_rsa.pub

  • 生成ssh密钥后,密钥将默认存储在家目录下的.ssh/目录中。私钥和公钥的权限就分别为600和644。.ssh目录权限必须是700。

2.2.1 在客户机中创建密钥对

ssh-keygen命令
可用的加密算法:RSA、ECDSA、DSA

[root@node1 ~]# ssh-keygen -t rsa  ## -t 指定加密算法类型  ##生成密钥对
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:ch19XvS7ehReEWc36P+ViQ3C08fGyvWlnXpIOt5I3WA root@node2
The key's randomart image is:
+---[RSA 3072]----+
|              .o*|
|           . . +=|
|          o + + +|
|         . = * O+|
|      . S . +E%+O|
|       o    o=+O=|
|           .o.+oo|
|          .ooo.o.|
|          .o.oo  |
+----[SHA256]-----+

2.2.2 将公钥文件上传到服务器中目标用户的公钥库

[root@node1 ~]# ssh-copy-id root@192.168.25.111
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.25.111 (192.168.25.111)' can't be established.
ECDSA key fingerprint is SHA256:hQUryG5gU8B+A5iKi8iBZzTLWRvN1dosOSu7LxPrR5Y.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 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.25.111's password: 

Number of key(s) added: 1

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

2.2.3 客户端使用密钥对验证登录

[root@node1 ~]# ssh root@192.168.25.111
Last login: Sat Sep 25 15:59:31 2021 from 192.168.25.110

3 scp远程复制

使用scp命令可以利用SSH安全连接与远程主机相互复制文件。使用scp命令时,除了必须指定复制源、目标外,还应指定目标主机地址、登录用户,执行后提示验证口令即可

语法:
scp [OPTIONS] SRC…DEST

常用选项:
-r: 递归复制,复制目录及内部文件时使用;
-p: 保存源文件元数据信息中的属主、属组及权限;
-q: 静默模式
-P PORT: 指明远程服务器使用的端口
两种模式:
PUSH: scp [OPTIONS] /PATH/FROM/SOMEFILE … user@server:/PATH/TO/DEST

                   //复制本地文件至远程主机 (但远程目录一定要有写权限)

PULL: SCP [OPTIONS] user@server:/PATH/FROM/SOMEFILE /PATH/TO/DEST

                  //远程目标主机文件至本地

//将服务端的test文件传送到远程主机

[root@server ~]# ls
anaconda-ks.cfg  test2
[root@server ~]# scp -p /root/test2 root@192.168.58.20:/opt/
test2                                                                         100%    0     0.0KB/s   00:00    
[root@node1 ~]# 
//到node2 查看
[root@client~]# ls /opt/
data  test2

//复制远程主机/etc/fstab至服务端当前目录下

//在创建一个testing.txt的文件
[root@client ~]# touch testing.txt
[root@client ~]# ls
anaconda-ks.cfg  testing.txt
//在server,将client的testing cp到当前目录中来
 [root@server ~]# scp root@192.168.58.20:/root/testing.txt  ./
testing.txt                                                                   100%    0     0.0KB/s   00:00    
[root@server ~]# ls
anaconda-ks.cfg  test2  testing.txt
[root@node1 ~]# 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐