0%

计算机网络学习笔记

OSI七层模型

由于OSI(Open System Interconnect)是一个理想的模型,因此一般网络系统只涉及其中的几层,很少有系统能够具有所有的7层,并完全遵循它的规定。

在7层模型中,每一层都提供一个特殊的网络功能。从网络功能的角度观察:下面4层(物理层、数据链路层、网络层和传输层)主要提供数据传输和交换功能,即以节点到节点之间的通信为主;第4层作为上下两部分的桥梁,是整个网络体系结构中最关键的部分;而上3层(会话层、表示层和应用层)则以提供用户与应用程序之间的信息和数据处理功能为主。

简言之,下4层主要完成通信子网的功能,上3层主要完成资源子网的功能.OSI下3层的主要任务是数据通信,上3层的任务是数据处理。

Socket:是应用层与传输层之间的桥梁.

协议

OSI七层网络模型 TCP/IP四层概念模型 对应网络协议
应用层(Application) 应用层 HTTP、TFTP, FTP, NFS, WAIS、SMTP
表示层(Presentation) 应用层 Telnet, Rlogin, SNMP, Gopher
会话层(Session) 应用层 SMTP, DNS
传输层(Transport) 传输层 TCP, UDP
网络层(Network) 网络层 IP, ICMP, ARP, RARP, AKP, UUCP
数据链路层(Data Link) 数据链路层 FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
物理层(Physical) 数据链路层 IEEE 802.1A, IEEE 802.2到IEEE 802.11

物理层

  • 利用传输介质为数据链路层提供物理连接,实现比特流的传输(比特Bit).

  • 物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的

  • 把二进制转换成电流,把电流转换成二进制(单位是bit比特)

数据链路层

  • 将比特组装成帧和点到点的传递(帧Frame)
  • 通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路.
  • 在计算机网络中由于各种干扰的存在,物理链路是不可靠的。因此,这一层的主要功能是在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法
  • 数据链路层的具体工作是:接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层
  • 将二进制数据转换成标准帧格式(起始位、数据、地址、校验、结束位)
  • 与数据链路层有关的设备:交换机,也就是大家常说的猫(为数据帧从一个端口到另一个任意端口的转发提供了低时延、低开销的通路)
  • 如果把电脑比如成客户,数据链路比喻成物流,那么快递小哥通过电脑MAC地址(MAC地址由网卡决定)找到客户地址

网络层

  • 数据链路层的数据在这一层被转换为数据包(package).

  • 其主要任务是:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。该层控制数据链路层与传输层之间的信息转发,建立、维持和终止网络的连接。具体地说,数据链路层的数据在这一层被转换为数据包,然后通过路径选择、分段组合、顺序、进/出路由等控制,将信息从一个网络设备传送到另一个网络设备

  • 寻址:数据链路层中使用的物理地址(如MAC地址)仅解决网络内部的寻址问题。在不同子网之间通信时,为了识别和找到网络中的设备,每一子网中的设备都会被分配一个唯一的地址。由于各子网使用的物理技术可能不同,因此这个地址应当是逻辑地址(如IP地址)。

  • 交换:规定不同的信息交换方式。常见的交换技术有:线路交换技术和存储转发技术,后者又包括报文交换技术和分组交换技术。

  • 路由算法:当源节点和目的节点之间存在多条路径时,本层可以根据路由算法,通过网络为数据分组选择最佳路径,并将信息从最合适的路径由发送端传送到接收端。

  • 连接服务:与数据链路层流量控制不同的是,前者控制的是网络相邻节点间的流量,后者控制的是从源节点到目的节点间的流量。其目的在于防止阻塞,并进行差错检测

  • 网络层有关的设备:路由器(一个作用是连通不同的网络,另一个作用是选择信息传送的线路)

  • 网络层主要有两个作用

    选择数据传输的最优路径,解决网络阻塞问题(网络阻塞的原因主要是CPU需要处理数据有一定延迟)

    将大的数据切割成小的数据包,根据不同时间段的不同最优路径进行传输(可以联想看片时候的断点续传)

  • 互联网通过ip地址识别电脑.

传输层

  • 传输层是通信子网和资源子网的接口和桥梁,起到承上启下的作用
  • 该层的主要任务是:定义了一些传输数据的协议和端口号(如HTTP的端口80等),TCP,UDP。 主要是从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做报文段(Segment)
  • 电脑通过通过端口号识别某一个应用程序,每一个应用程序都有很多的服务,每一个服务对应着一个端口号

会话层

  • 建立、管理和终止会话(会话协议数据单元SPDU)
  • 会话层是用户应用程序和网络之间的接口,主要任务是:向两个实体的表示层提供建立和使用连接的方法。将不同实体之间的表示层的连接称为会话。因此会话层的任务就是组织和协调两个会话进程之间的通信,并对数据交换进行管理
  • 通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
  • 数据的传输是在会话层完成的,而不是传输层,传输层只是定义了数据传输的协议

表示层

  • 对数据进行翻译、加密和压缩(表示协议数据单元PPDU)
  • 表示层对来自应用层的命令和数据进行解释,对各种语法赋予相应的含义,并按照一定的格式传送给会话层。其主要功能是“处理用户信息的表示问题,如编码、数据格式转换和加密解密”等
  • 可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。例如,PC程序与另一台计算机进行通信,其中一台计算机使用扩展二一十进制交换码(EBCDIC),而另一台则使用美国信息交换标准码(ASCII)来表示相同的字符。如有必要,表示层会通过使用一种通格式来实现多种数据格式之间的转换
  • 表示层的任务:数据格式转换(可以理解成iOS中将c语言的char字符转换成OC语言的NSString)

应用层

  • 允许访问OSI环境的手段(应用协议数据单元APDU)
  • 应用层是计算机用户,以及各种应用程序和网络之间的接口,其功能是直接向用户提供服务,完成用户希望在网络上完成的各种工作
  • 是最靠近用户的OSI层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务

单工,半双工,全双工

  • 单工:单工就是指A只能发信号,而B只能接收信号,通信是单向的。
  • 半双工:指一个时间段内只有一个动作发生,举个简单例子,一天窄窄的马路,同时只能有一辆车通过,当目前有两量车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开,这个例子就形象的说明了半双工的原理。早期的对讲机、以及早期集线器等设备都是实行半双工的产品。随着技术的不断进步,半双工会逐渐退出历史舞台。
  • 全双工:指交换机在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。目前的交换机都支持全双工。

IP地址

IP地址

IP地址:<网络号><主机号>.

  • A类地址:以0开头,第一个字节范围:0~127(1.0.0.0 - 126.255.255.255);
  • B类地址:以10开头,第一个字节范围:128~191(128.0.0.0 - 191.255.255.255);
  • C类地址:以110开头,第一个字节范围:192~223(192.0.0.0 - 223.255.255.255);

私有(保留)地址

  • A类:10.0.0.0——10.255.255.255
  • B类:172.16.0.0——172.31.255.255
  • C类:192.168.0.0——192.168.255.255

子网划分

三级ip地址:<网络号><子网号><主机号>

TCP&UDP(传输层)

TCP三次握手与四次挥手

主要因为这是一次全双工的,双方都需要证明自己有发送和接收的能力。握手只需要三次是因为服务端的SYN和ACK可以一次发送给客户端。

为什么TCP客户端最后还要发一次确认呢?

防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

  1. 客户端进程发出连接释放报文,并且停止发送数据。
  2. 服务器收到连接释放报文,发出确认报文,服务端就进入了CLOSE-WAIT(关闭等待)状态。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文。
  5. 客户端收到服务器的连接释放报文后,必须发出确认。此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗ *∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。

为什么客户端最后还要等待2MSL?

  1. 保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
  2. 防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么建立连接是三次握手,关闭连接确是四次挥手呢?

  1. 当主机甲想要释放连接时会发FIN给主机B。
  2. 主机乙收到甲发送的FIN,表示收到了,就会发送ACK回复。
  3. 但这是乙可能还在发送数据,没有想要关闭数据口的意思,所以FIN与ACK不是同时发送的,而是等到乙数据发送完了,才会发送FIN给主机A.
  4. A收到B发来的FIN,知道B的数据也发送完了,回复ACK,A等待2MSL以后,没有收到B传来的任何消息,知道B已经收到自己的ACK了,A就关闭链接,B也关闭链接了。

TCP和UDP

UDP

  • 面向无连接
  • 有单播,多播,广播的功能:支持一对一,一对多,多对多,多对一的方式。
  • 面向报文:发送方对应用程序的报文添加首部后就向下交付IP层,既不合并,也不拆分,因此应用程序必须选择合适大小的报文。
  • 不可靠性:不需建立连接,不关心接收端是否接收到信息。适合实时性要求高的场景(比如电话会议)。
  • 头部开销小,传输数据报文时是很高效的。

TCP

  • 面向连接:三次握手四次挥手。
  • 仅支持单播传输:点对点。
  • 面向字节流
  • 可靠传输:给每个包一个序列号,接收端按序接收,然后发送确认ACK,发送端决定是否重传。
  • 拥塞控制

TCP流量控制

所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。利用滑动窗口实现流量控制。

发送窗口在连接建立时由双方商定。但在通信的过程中,接收端可根据自己的资源情况,随时动态地调整对方的发送窗口上限值(可增大或减小)。

TCP拥塞控制

所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。

慢开始和拥塞避免

  1. 在主机刚刚开始发送报文段时可先将拥塞窗口 cwnd 设置为一个最大报文段 MSS 的数值。
  2. 在每收到一个对新的报文段的确认后,将拥塞窗口增加至多一个 MSS 的数值。
  3. 用这样的方法逐步增大发送端的拥塞窗口 cwnd,可以使分组注入到网络的速率更加合理。

快重传和快恢复

  • 快重传:发送端只要一连收到三个重复的 ACK 即可断定有分组丢失了,就应立即重传丢失的报文段而不必继续等待为该报文段设置的重传计时器的超时
  • 快恢复:
    1. 当发送端收到连续三个重复的 ACK 时,就重新设置慢开始门限 ssthresh。
    2. 与慢开始不同之处是 swnd 不是设置为 1,而是设置为 ssthresh + 3 * MSS。
    3. 若收到的重复的 ACK 为 n 个(n > 3),则将 cwnd 设置为 ssthresh + n * MSS。
    4. 若发送窗口值还容许发送报文段,就按拥塞避免算法继续发送报文段。
    5. 若收到了确认新的报文段的 ACK,就将 swnd 缩小到 ssthresh。

http&https

Http码

  • 1xx (临时响应)请求正在处理,可能需要请求者执行某些操作。
  • 2xx (成功)表示成功处理了请求的状态代码。
  • 3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
  • 4xx (客户端错误) 这些状态代码表示客户端请求可能出错,服务器无法处理。
  • 5xx (服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。

http和https的区别与联系

HTTP协议传输的数据都是明文,因此使用HTTP协议传输隐私信息非常不安全。为了保证这些隐私数据能加密传输,于是通过 SSL 协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。

HTTPS和HTTP的区别主要如下:

  1. https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http是无状态(每个请求都是完全独立的,每个请求包含了处理这个请求所需的完整的数据,发送请求不涉及到状态变更,也不依赖之前的状态)的;HTTPS协议是由SSL+HTTP协议构建的,http是无状态的,ssl/tls是有状态的。

https

Http1.0, 1.1, 2.0

  • HTTP 1.1支持长连接,使用长连接的情况下,连接成功后客户端和服务器之间用于的TCP连接不会关闭,一段时间内如果客户端再次访问这个服务器,会继续使用这一条已经建立的连接(Connection:keep-alive)。HTTP 1.0规定浏览器与服务器只保持短暂的连接,每次请求都需要与服务器建立TCP连接,完成处理后立即断开TCP连接。
  • HTTP 1.0认为每台服务器都绑定一个唯一的IP地址,虚拟主机发展后一台物理服务器上可以存在多个虚拟主机,它们共享一个IP地址,因此添加了主机host参数。
  • HTTP 1.1在1.0的基础上加入了一些cache的新特性。HTTP 1.0使用Expires头标识缓存的有效期,其值是一个绝对时间,依赖客户端的本地时间。从HTTP 1.1 开始使用Cache-Control头表示缓存状态。
  • 新增了24个状态响应码,如 410 表示服务器上的某个资源被永久性的删除。
  • http 1.1在请求头引入了range头,支持断点续传。

HTTP 2.0:

  • HTTP 1.x的解析基于文本,HTTP 2.0在应用层和传输层之间增加一个二进制分帧层,它把原来 HTTP 1.x的header和body用二进制重新封装了一层。
  • HTTP 2.0多路复用基于二进制分帧,在同一域名下所有访问都从同一个tcp连接中走,http消息被分解为独立的帧,乱序发送,服务端根据帧id重新组装起来。
  • 头部压缩:HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0要求客户端和服务器同时维护和更新一个包含之前见过的头字段的索引列表(cache),之后传输的头信息会基于此表编码和解码。
  • 服务器推送:服务器可以额外的向客户端推送资源,而无需客户端明确的请求

HTTP是不保存状态的协议,如何保存用户状态?

HTTP 协议自身不对请求和响应之间的通信状态进行保存,使用Session可以服务端记录用户的状态。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。

  • Cookie: 浏览器的一种数据存储方式。
  • Session: 会话。服务器使用Session把用户的信息临时保存在服务器上,用户离开网站后Session会被销毁。客户端得到这个Session Id后可以存储在Cookie里。这里有个缺陷,如果Web服务器有许多台,那么下次请求如果请求到了另一个服务器上的时候就验证不了Session了。
  • Token: 也用来做身份验证,但是服务器不需要存储Token信息,服务器会在用户登录成功后返回一个签名后的Token回来,下次请求带上,服务器再解密验证即可。

浏览器访问http网址

  1. 客户端浏览器输入URL后,检查本地是否有DNS缓存,缓存的查找顺序为:浏览器缓存–>系统缓存–>路由器缓存,缓存中没有则查找系统的hosts文件中是否有记录,如果没有则查询DNS服务器。
  2. 应用层客户端浏览器根据ip及相应的端口号,构造一个http请求,包括请求头和请求体,封装在TCP包里。
  3. 然后传输层TCP通过三次握手建立连接(SYN–>ACK/SYN–>ACK),TCP进行分割数据包,输入到网络层。
  4. 网络层ip协议通过查找路由表决定通过哪个路径到达服务器,把数据包发送给服务器。
  5. 数据到达数据链路层,将数据发送给指定mac地址的服务器。

交换机、路由器、网关

交换机

交换机工作于数据链路层。交换机内部的CPU会在每个端口成功连接时,通过ARP协议学习它的MAC地址,保存成一张ARP表。在今后的通讯中,发往该MAC地址的数据包将仅送往其对应的端口,而不是所有的端口。因此,交换机可用于划分数据链路层广播,即冲突域;但它不能划分网络层广播,即广播域。

交换机被广泛应用于二层网络交换,俗称“二层交换机”。

交换机的种类有:二层交换机、三层交换机、四层交换机、七层交换机分别工作在OSI七层模型中的第二层、第三层、第四层和第七层,并因此而得名。

路由器

路由器(Router)是一种计算机网络设备,提供了路由与转送两种重要机制,可以决定数据包从来源端到目的端所经过的路由路径(host到host之间的传输路径),这个过程称为由;将路由器输入端的数据包移送至适当的路由器输出端(在路由器内部进行),这称为转 送。路由工作在OSI模型的第三层——即网络层,例如网际协议。

路由器的一个作用是连通不同的网络,另一个作用是选择信息传送的线路。

路由器与交换器的差别,路由器是属于OSI第三层(网络层)的产品,交换器是OSI第二层的产品(这里特指二层交换机)。

网关

网关(Gateway),网关顾名思义就是连接两个网络的设备,区别于路由器(由于历史的原因,许多有关TCP/IP 的文献曾经把网络层使用的路由器(Router)称为网关,在今天很多局域网采用都是路由来接入网络,因此现在通常指的网关就是路由器的IP),经常在家 庭中或者小型企业网络中使用,用于连接局域网和Internet。 网关也经常指把一种协议转成另一种协议的设备,比如语音网关。

在现代网络术语中,网关(gateway)与路由器(router)的定义不同。网关(gateway)能在不同协议间移动数据,而路由器(router)是在不同网络间移动数据,相当于传统所说的IP网关(IP gateway)。

网关是连接两个网络的设备,对于语音网关来说,他可以连接PSTN网络和以太网,这就相当于VOIP,把不同电话中的模拟信号通过网关而转换成数字信号,而且加入协议再去传输。在到了接收端的时候再通过网关还原成模拟的电话信号,最后才能在电话机上听到。

对于以太网中的网关只能转发三层以上数据包,这一点和路由是一样的。而不同的是网关中并没有路由表,他只能按照预先设定的不同网段来进行转发。网关最重要的一点就是端口映射,子网内用户在外网看来只是外网的IP地址对应着不同的端口,这样看来就会保护子网内的用户。

网桥

简单的说网桥就是个硬件网络协议翻译器,假设你有2台电脑,一台兼容机安装windows,一台是Apple安装OS2,那么两台电脑之间是默认网络协议是不同的,兼容机可能只会说TCP/IP,苹果机只会说Apple talk,就好象两个外国人都不会说对方的语言,怎么办?找个翻译,网桥就是翻译。

在386、486时代网桥可能是一台安装了协议转换程序的电脑,如今交换机也包含这个功能。今天的操作系统之间为了互相交流,支持更多的协议,操作系统自己就可以是网桥,现在网桥这个概念已经淡出了。更多是所谓的桥接、转发、协议二次封装。

网桥也可以说相当一个端口少的二层交换机,再者网桥主要由软件实现,交换机主要由硬件实现!

网络接口卡(网卡)

  1. 进行串行/并行转换。
  2. 对数据进行缓存。
  3. 在计算机的操作系统安装设备驱动程序。
  4. 实现以太网协议。

路由表

路由表是用来决定如何将一个数据包从一个子网传送到另一个子网的,换句话说就是用来决定从一个网卡接收到的包应该送到哪一个网卡上去。

路由表的每一行至少有目标网络号、子网掩码、到这个子网应该使用的网卡这三条信息。当路由器从一个网卡接收到一个包时,它扫描路由表的每一行,用里面的子网掩码与数据包中的目标IP地址做逻辑与运算(&)找出目标网络号。如果得出的结果网络号与这一行的网络号相同,就将这条路由表六下来作为备用路由。如果已经有备用路由了,就载这两条路由里将网络号最长的留下来,另一条丢掉(这是用无分类编址CIDR的情况才是匹配网络号最长的,其他的情况是找到第一条匹配的行时就可以进行转发了)。如此接着扫描下一行直到结束。如果扫描结束仍没有找到任何路由,就用默认路由。确定路由后,直接将数据包送到对应的网卡上去。在具体的实现中,路由表可能包含更多的信息为选路由算法的细节所用。

ssh

概述

SSH的英文全称为Secure Shell,是IETF(Internet Engineering Task Force)的Network Working Group所制定的一族协议,其目的是要在非安全网络上提供安全的远程登录和其他安全网络服务。用于在主机之间建立起安全连接, 并加密传输内容, 以达到安全的远程访问, 操作以及数据传输的目的。它只是一种协议,存在多种实现,既有商业实现,也有开源实现。比较常用的是OpenSSH,它是自由软件,应用非常广泛。

SSH协议目前有SSH1和SSH2两个主流版本,SSH2协议兼容SSH1,强烈建议使用SSH2版本。目前实现SSH1和SSH2协议的主要软件有OpenSSH 和SSH Communications Security Corporation 公司的SSH Communications 软件。前者是OpenBSD组织开发的一款免费的SSH软件,后者是商业软件,因此在linux、FreeBSD、OpenBSD 、NetBSD等免费类UNIX系统种,通常都使用OpenSSH作为SSH协议的实现软件。

SSH主要有两个特点: 1. 安全性 2. 传输速度快。与FTP、POP 和 Telnet 等传统网络服务使用明文传输数据、命令和口令不同,SSH可以对所有传输的数据进行加密,能够防止 DNS 欺骗和 IP 欺骗。

如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露。

SSH支持两种认证方式:密码认证和密钥认证。

中间人攻击

SSH之所以能够保证安全,原因在于它采用了公钥加密。

整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送回来。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。

可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的”中间人攻击”(Man-in-the-middle attack)。

密码认证

  1. 客户端向服务端发起登录请求,服务端将自己的公钥返回给客户端
  2. 客户端输入登录口令,口令经服务端公钥加密后发送到服务端
  3. 服务端接收到加密口令后使用私钥解密,如果密码正确则登录成功

第一次登录对方主机时,系统会出现下面的提示:

1
2
3
4
$ ssh user@host
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?

这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

所谓”公钥指纹”,是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。

远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

密钥认证

  1. 客户端发起密钥连接请求,并上传身份信息
  2. 服务端收到请求后,在可信列表中查询客户端,若无此客户端则断开连接,否则发送一串随机问询码,该问询码使用此客户端公钥加密处理
  3. 客户端收到加密问询码后,使用私钥解密出问询码再用通信session对问询码加密并传送给服务端
  4. 服务端解密问询码并判定客户端身份安全与否,安全则建立连接

登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

因此,密钥认证首要要将客户端的公钥放置在服务端的授权登录列表中。密钥认证一般不需要密码,但客户端可在生成密钥时指定密钥加密密码,这样在与服务端建立连接时需要输入加密密码来解密私钥,防止因私钥泄露带来的安全问题。

1
2
3
4
5
# 生成密钥对
$ ssh-keygen

# 将公钥传送到远程主机host
$ ssh-copy-id user@host

以后再登录,就不需要输入密码了。

如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面”#”注释是否取掉。

1
2
3
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

然后,重启远程主机的ssh服务。

1
2
3
4
5
# ubuntu系统
$ service ssh restart

# debian系统
$ /etc/init.d/ssh restart

authorized_keys文件

远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。

这里不使用上面的ssh-copy-id命令,改用下面的命令,解释公钥的保存过程:

1
$ ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
  1. $ ssh user@host表示登录远程主机;
  2. mkdir .ssh && cat >> .ssh/authorized_keys表示登录后在远程shell上执行的命令:
  3. $ mkdir -p .ssh的作用是,如果用户主目录中的.ssh目录不存在,就创建一个;
  4. cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub的作用是,将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾。

写入authorized_keys文件后,公钥登录的设置就完成了。

SSL、TLS、SSH&HTTPS

SSL(Secure Socket Layer)

  • SSL是传输层之上,对Socket连接的加密协议。
  • SSL多用于Internet上,在浏览器和服务器之间的安全传输。
  • OpenSSL是SSL/TLS的开源实现。

TLS(Transport Layer Security)

  • TLS也是传输层之上的加密协议。
  • TLS可用于任何两个应用程序之间的安全传输。
  • OpenSSL是SSL/TLS的开源实现。

SSH(Secure Shell)

  • SSH是应用层的通信加密协议,往往用于远程登录的会话。
  • OpenSSH是SSH的开源实现。

HTTPS

  • 在传输层使用SSL/TLS加密的HTTP
  • 与HTTP类似,HTTPS本身是应用层的协议。
  • 同一台Web服务器,往往同时支持HTTP和HTTPS,这是分别通过80端口和443端口实现的。