1. SSH简介

SSH是Secure Shell Protocol的简写,由 IETF 网络工作小组(Network Working Group)制定;在进行数据传输之前,SSH先对连接数据包通过加密技术进行加密处理,加密后在进行数据传输。确保了传递的数据安全。SSH是专为远程登录会话和其他网络服务提供的安全性协议。利用SSH协议可以有效的防止远程管理过程中的信息泄露问题,在当前的生产环境运维工作中,绝大多数企业普遍采用SSH协议服务来代替传统的不安全的远程联接服务软件,如telnet(23端口,非加密的)等。

在默认状态下,SSH服务主要提供两个服务功能:

  • 一是提供类似telnet远程连接服务器的服务,即上面提到的SSH服务;
  • 另一个是类似FTP服务的sftp-server,借助SSH协议来传输数据的,提供更安全的SFTP服务(vsftp,proftp)。

ssh服务端由2部分组成:

  • openssh(提供ssh服务) openssl(提供加密的程序)
  • ssh的客户端可以用:XSHELL,Securecrt, Mobaxterm等工具进行连接

2. SSH的工作机制

服务器启动的时候自己产生一个密钥(768bit公钥),本地的ssh客户端发送连接请求到ssh服务器,服务器检查连接点客户端发送的数据和IP地址,确认合法后发送公钥(768bits)给客户端,此时客户端将本地私钥(256bit)和服务器的公钥(768bit)结合成密钥对key(1024bit),发回给服务器端,建立连接通过key-pair数据传输。

image.png

3. SSH的加密技术

加密技术:传输过程,数据加密。

1、SSH1没有对客户端的秘钥进行校验,很容易被植入恶意代码
2、SSH2增加了一个确认联机正确性的Diffe_Hellman机制,每次数据的传输,Server都会检查数据来源的正确性,避免黑客入侵。

SSH2支持RSA和DSA密钥

DSA:digital signature Algorithm 数字签名 RSA:既可以数字签名又可以加密

查看SSH进程

  1. [root@m01 ~]# ps -ef |grep sshd
  2. root 1476 1 0 17:54 ? 00:00:00 /usr/sbin/sshd -D
  3. root 1765 1476 0 17:55 ? 00:00:00 sshd: root@pts/0
  4. root 2210 1476 0 17:57 ? 00:00:00 sshd: root@pts/1
  5. [root@m01 ~]# netstat -lntup |grep sshd
  6. tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1476/sshd
  7. tcp6 0 0 :::22 :::* LISTEN 1476/sshd
  8. //0.0.0.0:22 监听本机所有IP(网卡)的22口,生产环境只需要监听内网网段

4.SSHv1和v2版本

SSH版本分为v1和v2:

  • sshv1版本不会经常更换锁头和钥匙,因此会有安全隐患
  • sshv2版本会经常更换锁头和钥匙,因此提高了远程连接安全性

SSH排错小思路:

  • ping ssh服务端(排除物理网络,路由问题)
  • telnet 服务端22端口(22端口有没有开启)

SSH知识小结:

  • SSH是安全的加密协议,用于远程连接Linux服务器
  • SSH的默认端口是22,安全协议版本是SSH2,除了2之外还有SHA1(有漏洞)
  • SSH服务器端主要包含2个服务功能SSH远程连接和SFTP服务器
  • SSH客户端包含ssh连接命令和远程拷贝scp命令等

防止SSH登录入侵:

  • 密钥登录,更改端口
  • 牤牛阵法
    • 防火墙封闭SSH,指定源限制(局域网,信任公网)
    • 开启SSH只监听内网IP(ListenAddress 172.16.1.*)
  • 尽量不给服务器外网IP
  • 控制服务/程序的权限(最小化权限)
  • 将一台机器上不同的服务拆分到不同的服务器单独的提供服务

5. SSH 配置文件

  1. /etc/ssh/ssh下的两个ssh文件
  2. ssh_config #ssh客户端配置文件
  3. sshd_config #ssh服务端配置文件
  4. //公钥保存配置文件(~/.ssh/known_hosts)每访问一台主机所获得的公钥,都保存在该文件下
  5. [root@nfs/]# cat /root/.ssh/known_hosts

6. SSH 服务器认证类型

1、基于口令:
只要知道服务器的SSH连接账号和口令(当然也要知道对应服务器的IP及开放的SSH端口,默认22),就能通过客户端登录到远程主机。而联机过程中所有传输的数据都是加密的。

  1. [root@m01 ~]# ssh root@172.16.1.41
  2. root@172.16.1.41's password:
  3. Last login: Mon Nov 5 19:37:51 2018 from 172.16.1.61
  4. [root@backup ~]# logout
  5. Connection to 172.16.1.41 closed

2、基于密钥:
 这种方式需客户端事先建立一对密钥对(公钥对应的私钥),然后把公用密钥(Public key)放在需访问的目标目标服务器上,再把私有密钥(Private key)放到客户端或对应的客户端服务器上。

 如果想要连接到有公用秘钥的SSH服务器,客户端SSH软件或者客户端服务器就会向服务器发出请求,请求用联机的用户秘钥进行安全验证。服务器收到请求后,会先寻找事先放上去的公用密钥,然后对它和发送过来的密钥进行比较。如果两个密钥一致,服务器就用公用密钥加密“质询”并把它发送给客户端。SSH客户端收到“质询”后就用自己的私钥解密,再把它发送给服务器。而使用这种方式,需要知道联机用户的密钥文件。

7. SSH 服务配置

1.启动SSHD(默认开机自启动)

  1. [root@m01 ~]# /etc/init.d/sshd start

2.查看sshd的开机自启动项

  1. [root@m01 ~]# chkconfig --list sshd
  2. sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

3.将ssh加入开机自启动(默认开机自启动)

  1. [root@m01 ~]# chkconfig sshd on

4.查看sshd的服务状态

  1. [root@m01 ~]# netstat -lntup |grep sshd
  2. tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1207/sshd
  3. tcp 0 0 :::22 :::* LISTEN 1207/sshd

在生产环境一般不会用22端口,会设备成别的端口,为了增强安全性,因为22是众所周知的SSH端口,还可以用下面的方法查看22端口对应的服务

  1. netstat -lntup |grep "\b22\b"
  2. netstat -lntup |grep -w "22"
  3. lsof -i :22

SSH 默认登录配置 修改SSH服务的运行参数,通过修改配置文件/etc/ssh/sshd_config实现的。 一般来说默认的SSH服务使用的默认配置已经能够很好工作了,没有对安全有特定要求,可以保持默认配置。

更改sshd_config配置文件:

  1. [root@m01 ~]# cd /etc/ssh/
  2. [root@m01 ssh]# cp sshd_config sshd_config.ori #<==更改配置前先做备份
  3. [root@m01 ssh]# ll /etc/ssh/sshd_config*
  4. -rw-------. 1 root root 3907 Apr 11 2018 /etc/ssh/sshd_config
  5. -rw------- 1 root root 3907 Nov 5 19:54 /etc/ssh/sshd_config.ori
  6. [root@m01 ~]# vim /etc/ssh/sshd_config
  7. Port 52113 #修改ssh服务端口号(默认22)
  8. ListenAddress 172.16.1.61 #配置SSH侦听的本地网卡拥有的地址(默认 0.0.0.0)
  9. PermitRootLogin no #是否允许root用户ssh登录
  10. GSSAPIAuthentication no #是否进行GSSAPI认证(提升ssh远程连接效率)
  11. PermitEmptyPasswords no #是否允许空密码登录
  12. UseDNS no #是否进行DNS反向解析(提升ssh远程连接效率)
  13. #在ssh的配置文件里的 # 注释符号并不是注释的意思,而是ssh的默认配置

每次修改完配置文件后,重启sshd

[root@m01 ~]# /etc/init.d/sshd restart
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]

//查看sshd的端口
[root@m01 ~]# netstat -lntup |grep sshd
tcp        0      0 172.16.1.61:52113           0.0.0.0:*                   LISTEN      3539/sshd

可用sed直接做替换更改,然后在进入/etc/ssh/sshd_config修改监听地址
[root@m01 ~]# cd /etc/ssh/
[root@m01 ~]# sed -ri '13 iPort 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\n GSSAPIAuthentication no\n' /etc/ssh/sshd_config

2.测试配置的效果:
上述配置了ListenAddress 172.16.1.61 ,那么服务端只会接受数据包的目标地址是172.16.1.61:52113的请求连接,

//使用服务端的其它地址登录失败
[root@backup /]# ssh 10.0.0.61 -p 52113 #失败
ssh: connect to host 10.0.0.61 port 52113: Connection refused
[root@backup /]# ssh 172.16.1.61 -p 52113  #成功
root@172.16.1.61's password: 
Last login: Wed Nov 28 11:21:09 2018 from 172.16.1.41
[root@m01 ~]#
//客户端在ssh登录到服务端的时候就必须要指定172.16.1.61,端口52113

上述设置了PermitRootLogin no,因此客户端不能直接用root连,服务端需要创建普通用户

[root@m01 ssh]# useradd xiaowang   #创建xiaowang用户
[root@m01 ssh]# id xiaowang      
uid=1001(xiaowang) gid=1001(xiaowang) groups=1001(xiaowang)
[root@m01 ssh]# echo  "123456"|passwd --stdin  xiaowang          
Changing password for user xiaowang.
passwd: all authentication tokens updated successfully.
在客户端输入172.16.1.61,port 52113,user:xiaowang,passwd:123456
[root@web01 ~]# ssh -p52113  xiaowang@172.16.1.61
xiaowang@172.16.1.61's password: 
Last failed login: Mon Nov  5 20:25:23 CST 2018 from 172.16.1.7 on ssh:notty
There were 4 failed login attempts since the last successful login.
[xiaowang@m01 ~]$   #登录成功

8. SSH远程连接服务

8.1. Linux客户端通过SSH连接执行命令

ssh命令格式:

ssh -p22 xiaowang@10.0.0.61 [命令]
-p (小写)接端口,默认22端口时,可省略-p22
-@ 前面为用户名,如果用当前用户连接,可以不指定用户
-@ 后面为要连接的服务器的IP

服务端SSH连接到客户端执行命令

[root@m01 ~]# ssh 172.16.1.41 ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:A6:FA:1D
          inet addr:10.0.0.41  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fea6:fa1d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:36836 errors:0 dropped:0 overruns:0 frame:0
          TX packets:34129 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:6731813 (6.4 MiB)  TX bytes:4482003 (4.2 MiB)

出现报错字符串的可能问题:

no route to host #可能防火墙没关
Connection refused #可能防火墙没关
Connection refused

还可能是连接的对端的服务没开,或者端口号已经改变了

8.2. SSH客户端自带的远程scp命令

scp的基本语法使用:scp -secure copy(remote file copy program)

scp每次都是全量拷贝,增量拷贝->rsync

//推:PUSH
scp -P52113 /etc/hosts root@172.16.1.61:/tmp/

//拉:PULL
scp -P52113 root@172.16.1.61:/tmp/hosts /data

scp为远程拷贝文件或目录的命令
-P #接端口,默认22端口时刻省略-p22(大写,注意和ssh命令的不同)
-r #递归,表示拷贝目录
-p #表示在拷贝前后保持文件或目录属性
-l #limit 限制速度

9.3、SSH服务端自带的sftp功能

SSH服务除了有远程连接机器外,还有一个安全的FTP的功能,通过SSH加密数据后进行传输
get 下载
put 上传

[root@web01 /]# sftp -oPort=52113 xiaowang@172.16.1.61
xiaowang@172.16.1.61's password: 
Connected to 172.16.1.61.
sftp> pwd
Remote working directory: /home/xiaowang #相当于是进入到了服务端的xiaowang的家目录
sftp> put /etc/hosts #把/etc/hosts文件从客户端本地上传到sftp服务端当前连接的目录
Uploading /etc/hosts to /home/xiaowang/hosts
/etc/hosts                   100%  176   275.0KB/s   00:00    
sftp> put /etc/hosts /tmp/ #把/etc/hosts文件从客户端本地上传到sftp服务端指定的目录
Uploading /etc/hosts to /tmp/hosts
/etc/hosts                           100%  176   260.3KB/s   00:00    
sftp> cd /tmp/ #还可以像命令行一样,切换到目标的目录
sftp> pwd
Remote working directory: /tmp   
sftp> mkdir /tmp/ett #还可以创建目录
sftp> ls
ett               hosts             ks-script-jCEMGn  vmware-root       yum.log           
sftp> get hosts #会把hosts文件下载到客户端连接该sftp服务器之前所在的路径
Fetching /tmp/hosts to hosts
/tmp/hosts                                         100%  176   156.9KB/s   00:00    
sftp> get hosts /home/ #会把hosts文件下载到指定客户端的路径
Fetching /tmp/hosts to /home/hosts
/tmp/hosts                                         100%  176   167.9KB/s   00:00    
sftp> cd /home/

//连接到的远端家目录为默认目录,也可以切换到其它有权限的目录下。