OpenSSH服务及其相关应用

Stella981
• 阅读 665

OpenSSH

早期主机使用远程登录的协议telnetTCP/23(telnet是基于TCP的23号端口的)

telnet有两大缺陷:

1、用户认证过程是明文的;

2、数据传输是明文的;

因此telnet不再使用了。于是就出现了ssh

1、ssh

ssh(Secure SHell,安全的shell),与telnet一样,也是一种远程登录协议,但其与telnet的实现机制不同,ssh为TCP/22(基于TCP协议的22号端口)。

与telnet一样,ssh是基于C/S架构的。在服务器端,需要运行服务器软件,监听在某个端口(套接字上)。客户端发起连接请求,服务器端在收到请求后响应客户端请求,双发建立数据传输的通道,并一直处于连接状态,当所有用户请求处理完成之后再退出。因此需要专门的客户端软件和服务器端软件。

ssh在刚刚诞生时,出现了一款软件,但后来商业化了。于是就出现了基于ssh运行在Linux/Unix上的开源软件OpenSSH(Open:开源的意思)。

ssh主要有v1,v2两个版本,通过验证发现,v1版本存在致命的缺陷,无法有效的拒绝中间人攻击,这个缺陷非常致命,到目前为止,v1处于废弃状态;最好是使用v2,但由于许多古老的设备上还在使用v1,因此不得不使得客户端能够访问v1的服务。(新购的设备尽量拒绝v1版本的协议)而OpenSSH对两种版本的协议都提供了支持。

1.1、ssh服务器端

SSH无法实现Windows上的服务器端,故此处的服务器端指的是工作在Unix/Linux的服务器端。名称为sshd(OpenSSH提供的)。

服务器端也是一个可执行程序,只不过这个可执行程序直接工作在后台。而且不会退出,一旦退出服务即终止。

1.2、OpenSSH包含的两个组件

ssh(客户端工具,命令行的)、sshd(服务器端工具)

2、SSH认证的实现和实现加密数据传输的简要概述

sshd:主机密钥

ssh服务器端需要一个主机密钥(第一次向服务器发送一个请求时,对方总是需要我们确认一个东西(对方发来一个东西,询问是否接受),这个信息就是主机密钥)。

那么那么为什么需要主机密钥呢?若通信的双方此前从来没有通信过,那么如何建立安全通信呢?此前我们讨论过,需要借助于CA证书,但SSH客户端和服务器端都未必有证书。因此没有办法验证对方身份的可靠性,在此前提下,服务器端会向客户端发送一个主机公钥,我们的客户端就会接收对方主机公钥的指纹信息,接下来客户端会被询问是否认可这个指纹,此时就需要客户端(用户)自己确认这个服务器是否是你认可的服务器(因为没有任何有效的措施能够确认对方身份,只能凭借用户自己的判断)。因此client回答yes就表示就此接受了对方主机公钥,这个公钥是主机上一对密钥的公钥信息。

具体过程如下所示:

OpenSSH服务及其相关应用

客户端通过远程连接进行身份认证时,需要将账号密码加密后传输至服务器端,在传输过程中,账号密码存在被窃取的风险。因此SSH还支持另外一种认证方式。SSH认证方式分为以下两种:

  • 基于口令的认证:默认情况下都是基于口令的认证;
  • 基于密钥的认证:客户端用户自身也生成一对密钥,它把公钥放在服务器上的某个家目录下(这个公钥信息必须严格保密,不能让任何第三方知道),私钥自己保留。以后远程登录这台服务器时,不再要求输入密码,而是传输数据时用对方的公钥加密数据,若对方能用私钥将数据解密即配对成功,此时不再需要口令。但基于密钥的认证需要事先配置

3、注意(基本安全技巧)

  1. 基于口令的认证存在风险,在认证时输入用户名root和密码之后,有可能被第三方暴力将密码破解,因此,一般不允许使用root用户直接在基于ssh的客户端登录,若一定要使用root用户,只能通过登录普通用户后再su过去的方式实现。口令认证时位于互联网上的服务器最后一道也是唯一一道防线;
  2. 并且为了安全起见,也需要对普通用户登录的主机进行限制,若一定要在不被信任的主机上远程登录,则需要通过一台VPN服务器,先连接到VPN服务器上,再由VPN服务器转连;
  3. 更重要的是,最好不要使用22号端口进行远程登录,因为22号端口默认为远程登录端口,易被监控暴力破解;可以换一个端口使得别人无从揣测;
  4. 远程登录与系统安全性密切相关,怎么强调其安全性都不为过;
  5. 经常换密码(一般一个月换一次,最好密码是随机的并且足够长)

4、OpenSSH配置详解

在RedHat系列的系统上,ssh是由多个rpm包组成的rpm服务。这多个rpm包有的是提供客户端的,有的是提供服务器端的,有的是提供通用组件的。如下所示:

OpenSSH服务及其相关应用

上图中:

openssh-server-...:服务器端

openssh-clients-...:客户端

openssh-5.3p2-...:通用组件库

openssh-askpass-...:建立会话时用到的工具和库文件

4.1、****获取服务的运行状态:(如果当前有22号端口表明,ssh服务处于已经启动并工作的状态)

netstat -tnl(-t表示当前主机上根TCP建立连接的所有会话,-n表示以数字的方式显示IP地址和端口,-l表示显示处于监听状态(客户端已经启动并等待与客户端连接的状态)的服务)

netstat

-r:显示路由表

-n:

-t:TCP connection

-u:UDP connection

-l:listening

-p:process,哪一个进程或程序监听了当前这个服务

       OpenSSH服务及其相关应用

OpenSSH服务及其相关应用

获取sshd服务运行状态的另外一种方法:

OpenSSH服务及其相关应用

4.2、配置文件详解

ssh客户端和ssh服务器端都需要配置文件:

/etc/ssh目录下:

OpenSSH服务及其相关应用

客户端ssh配置文件:**/etc/ssh/ssh_config**

服务器端sshd配置文件:**/etc/ssh/sshd_config**

moduli:ssh中用到的密钥交换的相关信息

v1版本主机密钥对:ssh_host_key,ssh_host_key.pub

v2版本主机密钥对

DSA算法:ssh_host_dsa_key,ssh_host_dsa_key.pub

RSA算法:ssh_host_rsa_key,ssh_host_rsa_key.pub

主机密钥是ssh会话建立的根本前提,至关重要。

此处也反映了Linux的哲学思想之一:使用文本文件保存程序的配置信息。

sshd_config配置文件解释:

man sshd_config  #获取帮助文档信息

sshd服务的任何改变配置要想其生效需重启服务(脚本服务在**/etc/init.d/sshd**)

      service sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}

OpenSSH服务及其相关应用

#后带空格表示注释,#后不带空格表示可用选项;

Port:指定服务的端口号;

Protocol:启用的协议版本(默认优先使用v2版本);

AddressFamily:表示若当前主机同时启用了IPv4和IPv6的地址,那么打算在哪一类地址上启用ssh服务,any表示IPV4,IPV6都可以;

ListenAddress:表示监听在哪一个地址上(若当前主机配置了两个个IP地址,只需要其中一个提供服务,需要手动指定,若不指定,默认两个都提供服务。0.0.0.0表示任意地址,当前主机配置了哪个地址,哪个地址就能提供服务,配置了多个地址就在每一个地址上提供服务,否则手动指定);

HostKey:指定密钥;

KeyRegenerationInterval:客户端临时密钥生成的间隔时间,间隔指定时间后重新生成密钥;

ServerKeyBits:服务器端密钥长度;

SyslogFacility:指定哪一个facility记录日志;

LogLevel:日志级别;

OpenSSH服务及其相关应用

LoginGraceTime:登录时的宽容时间(登录时等待登录的时间,不登录则强行退出);

LoginGraceTime:是否允许管理员直接登录;

StrictModes:是否使用严格限定模式(不重要);

MaxAuthTries:最大登录次数;

RSAAuthentication:是否支持RSA密钥认证(基于RSA机制的密钥认证);

PubKeyAuthentication:基于密钥的认证(如果启用,客户端会生成一对密钥,公钥会放在服务器端的某个家目录下);

AuthroizedKeysFile:指定客户端公钥文件存放的家目录的文件路径;

RhostRSAAuthentication:主机认证(指的是是否信任对方主机,接下来就不需要登录了而是直接使用,不安全);

PasswordAuthentication:是否允许基于口令的认证;

ChallengeResponseAuthentication:是否使用挑战式握手协议认证(不安全,一般不允许使用);

OpenSSH服务及其相关应用

UsePAM:是否使用UsePAM(这是一种可插入式认证模块,一般都是启用的);

X11Forwarding:是否转发X11请求;

PrintMotd:在用户登录是是否打印/etc/motd文件的内容;

PrintLastLog:在登录时是否显示哪个主机在什么时候登录过(不推荐显示,会为不法用户提供信息,在互联网上,这种信息越少出现越好,最好软件版本号都不应该提供);

OpenSSH服务及其相关应用

Banner:欢迎标语(用户登录SSH时会将指定文件的内容当做欢迎标语为用户打印一次,启用后建立一个文件,文件路径在此处指定,登录后会显示文件中的信息);

Subsystem:(将ftp基于SSH实现叫做sftp,将ftp基于SSL实现叫做ftps)指定sftp的服务器程序,只要指定的程序存在即可默认启动。

ssh客户端工具的使用:

    ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D  [bind_address:]port] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L
             [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-R  [bind_address:]port:host:hostport] [-S ctl_path]
             [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command]

常用命令组合:

    ssh -l USERNAME REMOTE_HOST ['COMMAND']

    ssh USERNAEM@REMOTE_HOST ['COMMAND']

-p port:指定端口

-X:登录到远程主机上,并且能够执行远程主机的窗口命令,因为这些窗口要在本地显示,因此,本地必须是图形化的

-Y:功能与-X一样,单比-X更安全

在第一次远程登录接受了密钥之后,系统会认为这是可信任的主机,因此它会将主机的密钥信息添加到可信任主机列表中。每个用户只要登录过远程主机,在当前用户的家目录下会生成一个.ssh文件夹,文件夹中有一个knows_host文件,任何时候接受了主机,哪个主机的公钥信息就会保存在这个文件中。因此当第二次进行远程登录时,会将文件中的公钥与远程主机的私钥一建立会话测试是否能匹配上,若配对成功,表示认可了对方主机,因此就不需要进行密钥接受了。(此过程信任是单向的

SSH支持不登录远程主机但却可以在远程主机上执行命令,并将命令的执行结果返回到本地。只需在命令的最后加上可执行命令即可。

5、基于密钥的认证的实现:

需要一台主机作为客户端(前提是基于某个用户实现):

(1).生成一对密钥

ssh-keygen

-t [指定加密算法rsa或dsa](生成的密钥默认保存在用户家目录下面的.ssh/id_rsa和.ssh/id_rsa.pub)

-f /path/to/keyfile:指定生成的私钥文件目录

-N 'password':指定密码为password

OpenSSH服务及其相关应用

OpenSSH服务及其相关应用

:.ssh的权限为700,若大于700,.ssh将无法使用。

(2).将生成的公钥传输至服务器端某用户及目录的**.ssh/authrorized_keys文件中(可与当前用户不一致**)

方法一:使用文件传输工具实现,专用命令:ssh-copy-id

ssh-copy-id -i /path/to/pubkey(公钥文件位置) USERNAME@ROMATE_HOST(既复制又能追加到文件尾部)

方法二:ssh另外一个重要的客户端工具scp(基于ssh的远程复制命令,能够在主机之间传输数据(因为是基于ssh传输,因此传输与过程是加密的))

scp [opetions] SRC DEST

-r:递归复制目录

-p:保存权限

-a:相当于-rp

SRC或DEST为REMOTE_MACHINE(远程主机)时的格式:

USERNAME@HOSTNAME:/path/to/somefile

scp的实现是需要先复制到临时文件中,再将临时文件使用cat 文件名 >> 目标文件 追加到文件中

(3).测试登录即可

sftp:基于SSH的ftp,既是客户端又是服务器端,数据传输过程是加密的;

sftp USERNAME@IP  #连接远程主机

下载文件到本地:get /path/to/somefile

多个文件使用mget;

总结:

1.密码应该经常切换且足够复杂;

2.使用非默认端口;

3.限制登录的客户端地址;

4.禁止管理员直接登录;

5.仅允许有限用户登录;

6.使用基于密钥的认证;

7.不要使用版本1;

嵌入式系统专用的ssh软件:dropbear(可安装测试使用)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这