计算机网络基本知识
计算机网络基本知识
计算机网络需要掌握的不仅仅是书本上的理论知识,更多的应该是实践知识,脱离实践也无法理解理论,看不到计算机网络的全面。这里仅仅列出计算机网络的基本知识,不涉及任何高深的理论,作为网络实践的基础来看即可。
网络的结构
有OSI七层结构、TCP/IP四层结构,以及五层体系结构,OSI七层结构是理论上的,TCP/IP四层结构是实际广泛使用的,五层体系结构是两者的折中,其实与TCP/IP四层结构并无差别。
TCP/IP四层结构:应用层、运输层、网际层、网络接口层。 五层体系结构:物理层、数据链路层、网络层、运输层、应用层。
其中,网际层就是网络层,网络接口层细分为数据链路层和物理层。
- 应用层:直接为用户的应用进程提供服务,比如HTTP、DNS、SMTP协议。
- 运输层:为两台主机中进程提供通信服务,主要有TCP和UDP协议。
- 网络层:为网络中不同主机提供通信服务,有网际IP协议和许多路由选择协议。
- 数据链路层:简称链路层,其将网络层交下来的IP数据报组装成帧,在链路上透明地传送帧中的数据。
- 物理层:实现透明地传送比特流。
TCP/IP协议及结构
端口(port):位于运输层,主机进程与端口对应,端口号是16位整型,一个端口号仅能被一个进程占用。
套接字(socket):是抽象接口,应用以之收发数据,可进行类似文件的操作;网络套接字使应用可将I/O作用于网络通信,是IP地址与端口的组合,例如"192.168.0.1:1088"。
各层数据包封装结构
详见:计算机网络各层数据包的结构。
数据包的封装过程如下:
C语言相关结构体详见:TCP/IP编程常用C语言头文件。
以太网帧结构
Ethernet II帧格式:
- 前同步码:以使接收端适配器能迅速调整时钟频率和发送端相同,为1和0交替的七字节。
- 帧开始符:帧的起始符。注意,MAC帧又称以太网帧,不包括前同步码和帧开始符。
- 类型:上次协议的类型,为0x0800时,数据交付IP协议处理,为0x0806则ARP协议。
- 帧检验序列(FCS):帧信息CRC32校验,校验数据不包括FCS码。
Ethernet II帧本身不包含长度信息,物理网卡通过编码方案来确认MAC帧的结束。
struct ethhdr结构详见头文件"linux/if_ether.h"。
常用的是Ethernet II帧格式,此外,还有IEEE 802.3帧格式,此处不举。
IP数据报结构
- 片偏移:过长IP数据报被切片,该片在原分组中的相对位置。
- 生存时间(TTL):即跳数限制,IP数据报转发限制。
- 协议:IP数据报使用的上层协议,如TCP=6,ICMP=1,UDP=17等。
struct iphdr结构详见头文件"linux/ip.h"。
TCP/UDP数据包结构
TCP数据包结构如下:
- 数据序号(seq):作为發送方的当前数据包的首序号(TCP为發送数据的每个字节编号)。
- 确认序号(ack):作为接收方的下个数据包的首序号(表示之前的数据都接收成功)。
- 窗口:作为接收方告知發送方其可接收窗口大小,建立TCP连接时可设置窗口比例。
struct tcphdr结构详见头文件"linux/tcp.h"。
UDP数据包结构如下:
struct udphdr结构详见头文件"linux/udp.h"。
TCP/UDP协议
UDP协议是无连接、不可靠、面向报文(应用可控制报文长度,最大64K,超出则需分包)。UDP协议是全双工的,支持多个主机之间交互通信,只需接收缓冲区,不需要發送缓冲区。
TCP协议是有连接、端到端、可靠交付、全双工通信、面向字节流。TCP连接的端口称为套接字(socket)。
详见:TCP协议详解。
- TCP三次握手(连接建立):
- TCP四次挥手(连接释放):
- TCP滑动窗口机制(数据传输):
TCP协议中收發双方各自维护其相应的缓存和窗口,采用以字节为单位的可变滑动窗口进行数据传输,若發送方在规定时间内没有收到相应的确认报文,则需重传对应的报文段,超时重传时间(RTO)是以报文段的往返时间(RTT)采用动态算法计算而得。
- 發送方的發送窗口受限于接收方确认报文中设置的窗口字段,接收方可通过此字段控制發送方的發送速率。
- 接收方收到的报文段可能会失序,可以通过选择确认(SACK)机制主动告知發送方收到了不连续的字节块。
- 为减少传输开销,接收方需具有累计确认功能,即在确认报文中确认序号之前的所有字节都已正确收到,从而接收方可以在有数据發送时捎带确认,也允许延迟确认。
TCP接收方通过窗口字段来进行流量控制,为避免死锁,若發送方收到了接收方的零窗口通知,则需定时發送一个零窗口探测报文段。
Nagle算法:TCP發送小包时,第一个小包(报文段)直接發送出去,後续字节流缓存起来,当收到上一个报文段的确认报文後,才将缓存的字节流组装成一个报文段發送出去,以此往复,此外,当到达的数据已达到發送窗口大小的一半或报文段最大长度时,就立即發送一个报文段(无需等待上一个报文段的确认,适用于大量数据的發送)。
注意:Nagle算法与延迟确认机制共存会导致可能的死锁,从而产生不必要的延时。
- TCP拥塞控制(防止过载):
發送方维持一个拥塞窗口(Cwnd),發送窗口必须不大于拥塞窗口,通过控制拥塞窗口的值以防止网路过载,即拥塞控制。
- 慢开始:每一轮拥塞窗口大小都会翻倍,如果出现超时重传,也会进行慢开始算法。
- 拥塞避免:每一轮拥塞窗口大小都自增。收到确认报文後,才会调整拥塞窗口。
- 快重传:發送方收到三个重复确认则立即重传接收方未收到的报文段。
- 快恢复:快重传的同时将拥塞窗口减半并作为新的拥塞窗口阈值并进行拥塞避免算法。
网络硬件
计算机网络硬件主要有十种,组成计算机网络的硬件也可由虚拟设备代替。
- 网卡,又称网络适配器,是主机和网络的接口,拥有MAC地址,是网络接口层组件。
- 交换机,通常是二层交换机,工作在数据链路层,相当于多端口网桥;也有三层交换机,可通过MAC地址表和IP地址表进行转发,是有基本路由功能的交换机。
- 路由器,工作在网络层,根据路由选择算法,通过IP地址进行转发。
- 中继器,工作在物理层,对衰减的信号进行放大,以扩大传输距离。
- 网桥,工作在数据链路层,通过记录其端口映射的MAC地址的转发表,根据MAC帧的源地址更新转发表,根据MAC帧的目的地址对其进行转发和过滤,通常有两个端口。
- 集线器,工作在物理层,相当于多端口中继器,某个端口接收到的信号广播到其他端口。
- 网关,是网络的关口,通常视为路由器和调制解调器的组合,在运输层上作为协议转换器,连接两个不同类型网络;路由器是常见的网关,网关不一定是路由器。
- 调制解调器,工作在物理层,调制即将数字信号翻译为模拟信号进行传输,反之为解调。
- 防火墙,是位于主机和网络之间的软件或硬件以隔离控制,通常工作在网络层以上。
- 传输介质,网络的物理通路,常见的有双绞线、同轴电缆、光纤等等。
网络软件
计算机网络软件主要有虚拟网络软件和网络服务软件。
虚拟网络
计算机硬件大部分可以虚拟化,有些硬件甚至直接支持虚拟化访问。虚拟机可以借由操作系统虚拟出一个网络设备给虚拟机使用而无需借由实际物理设备,如果虚拟机需要访问Internet,有两种方式,直通物理网卡或者虚拟网卡与物理网卡交换数据。
VMware虚拟网卡
VMware Workstation虚拟机通过主机网卡上网的方式有:
桥接模式,物理机提供虚拟网卡给虚拟机,物理机提供服务作为虚拟交换机,再通过虚拟网桥与物理网卡交换数据,从而实现虚拟机上网,如下图:
其中,如果物理网卡工作在非混杂模式(仅监听其唯一的mac地址),虚拟网桥需要有IP路由功能(不带NAT的路由);如果物理网卡工作在混杂模式,虚拟网桥可以去掉。NAT模式,物理机的物理网卡与虚拟路由交换数据,而这个虚拟路由又与虚拟机的虚拟网卡交换数据,如下图:
与桥接模式的差别是虚拟路由替代了虚拟网桥,IP地址的分配由内部的DHCP服务完成而无需借由物理网卡。仅主机模式,物理机连接到一块虚拟网卡,这块虚拟网卡与虚拟机的虚拟网卡交换数据,物理机和虚拟机可以互访,但是虚拟机无法访问物理机的物理网卡所在网段,可以通过配置,使虚拟机可以访问Internet,如下图:
虚拟机与物理机的网卡是相互隔离的,物理机上的软件可控制其上虚拟网卡与物理网卡的数据交换,以控制虚拟机访问外部网络。
Linux抽象网络设备
Linux网络设备驱动程序遵循通用的接口,其体系可分为四层:网络协议接口层、网络设备接口层、设备驱动功能层和网络设备与媒介层。这些通用网络接口可视为Linux抽象网络设备,通过操作这些通用接口以使用网络功能。
主要有:网桥(Bridge)、虚拟网络(VLAN)、虚拟网口(VETH)、阀门(TUN/TAP)等等。
这里补充说明TUN/TAP接口:
TUN/TAP设备是一种让用户态程序向内核协议栈注入数据的设备,TAP等同于一个以太网设备,工作在二层;而TUN则是一个虚拟点对点设备,工作在三层。
其内核模块是tun(Universal TUN/TAP device
driver),可使用ip taptun和tunctl来操作的TAP/TUN设备,例如:
1 | |
TUN/TAP设备的工作原理一致,其区别有:
| 类型 | TAP接口 | TUN接口 |
|---|---|---|
| 协议栈 | 二层设备 | 三层设备 |
| 数据包 | 以太网数据包 | IP数据包 |
| MAC地址 | 有MAC地址 | 无MAC地址,有IP地址 |
详见:Linux tun:tap 详解。
Linux虚拟网卡
Linux网络虚拟化提供了对虚拟机技术和net namespace技术的支持。
Linux
namespace(命名空间)用以对全局资源虚拟化,Linux系统开机後有一个默认的root namespace,namespace具有隔离性,进程认为其享有所在namespace的独立资源。
轻量级的net namespace技术,用以隔离网络环境,在network namespace中,网络设备、端口、套接字、网络协议栈、路由表、防火墙规则等都是独立的。
为了简便,以下讨论Linux虚拟网卡,是基于net namespace技术(当然也可以虚拟机技术)。
vETH网卡
这其实就是Linux桥接网卡,如果需要访问外部网络,需将物理网卡绑定到Linux Bridge。
macvlan网卡
用于虚拟机的是macvtap网卡(macvlan与tap设备结合),macvlan要求物理网卡监听多个MAC地址,这需要物理网卡处于混杂模式(Promiscuous Model)。
详见:理解 macvlan。
ipvlan网卡
用于虚拟机的是ipvtap网卡(ipvlan与tap设备结合),ipvlan无需物理网卡监听多个MAC地址,无线网卡通常不工作在监听模式(Monitor Mode)而使用ipvaln更合适。
网络服务
限于篇幅,此处简述常见的网络服务的原理或配置,详细需查相关资料。
DNS
DNS服务通常使用UDP连接,端口号53,详解见:真正的「DNS」是啥。
域名系统(DNS)是因特网使用的命名系统,有顶级域名、二级域名、三级域名等等。
- 根域名服务器:管辖顶级域名,存储所有顶级域名服务器的IP地址。
- 顶级域名服务器:管辖其下所有二级域名。
- 权限域名服务器:仅负责一个区的域名服务器,总能将其管辖的域名转换为对应主机IP,每一个完整域名和其对应的主机IP都需要在所属权限域名服务器登记。
- 本地域名服务器:又称默认域名服务器,主机与其本地域名服务器通信以解析域名。
域名解析有两种方式:递归查询和迭代查询,如下图:
DNS查询方式取决于最初查询请求的报文设置。
DHCP
DHCP服务使用UDP连接,端口号于服务端67、客户端68,详解见:DHCP协议详解。
动态主机配置协议(DHCP)用以动态分配主机IP地址,可为客户端配置IP地址、子网掩码、默认网关、本地域名服务器。
DHCP工作流程如下:
注:DHCP报文都是以广播方式發送的。
HTTP/HTTPS
- 超文本传输协议(HTTP)基于TCP连接(80端口),用以传输超文本标记语言(HTML)及数据。
万维网(WWW):使用统一资源定位符(URL)来标志万维网上的各种文档,以HTTP/HTTPS协议传输文档,是一个大规模、分布式的超媒体系统。
HTTP协议特点:明文传输、面向事务、无记忆无状态、HTTP本身是无连接的。
HTTP的报文结构:
| 响应状态码 | 类别说明 |
|---|---|
| 1XX | 通知信息 |
| 2XX | 成功 |
| 3XX | 重定向 |
| 4XX | 客户端错误 |
| 5XX | 服务端错误 |
| 200 | 请求成功 |
| 301 | 资源重定向 |
| 302 | 临时跳转 |
| 400 | 错误请求 |
| 404 | 资源不存在 |
| 500 | 服务内部错误 |
| 503 | 服务不可用 |
- 超文本传输安全协议(HTTPS)以SSL证书验证服务器身份并为两端通信做加密(443端口)。
HTTPS是HTTP和SSL(安全套接字层)或TLS(传输层安全)的结合,解决了HTTP的不安全问题。
HTTPS传输流程(建立安全连接):
HTTPS加密原理:
非对称加密:有公钥和私钥,公钥加密内容仅能用私钥解开,私钥加密也仅能用公钥解开。
对称加密:通信双方持有同一个密钥,以之进行加密和解密操作。
HTTPS服务端持有私钥,公钥(CA证书)通过明文發送给客户端,客户端以之加密一个对称密钥并發回服务端,有私钥的服务端才可解密获取对称密钥,从而建立加密通信。
HTTPS利用非对称加密传递对称密钥,然後使用对称加密进行通信。如此,还需公钥安全。
网站使用HTTPS前,需向CA机构申领一份数字证书,CA证书包含公钥、持有者信息等。使用数字签名(用私钥签名),确保CA证书的完整性,通过根证书(或已信任证书)确保证书可信。
SMTP/POP3/IMAP4
SSH
详见:网道SSH教程
SSH(Secure Shell)是用于加密计算机通信的协议,保障远程登录和通信的安全。
通常使用开源的openssh软件包,登录ssh服务器的常用命令如下:(SSH默认端口是22)
ssh user@hostname -p port # 例如:ssh yang@192.168.0.6 -p 122
ssh登录後将连接到远程服务器的一个Shell环境并可与之交互,也可直接执行命令:
ssh hostname command # 或者将脚本重定向到ssh的输入,如:ssh hostname < 1.sh
以上命令执行不会生成交互式Shell环境,因此某些命令会报错,可以使用"-t"参数让ssh分配一个交互式Shell环境。
SSH默认以密码登录,每次登录都要输入密码,不仅麻烦也不太安全,推荐使用密钥登录。
执行命令生成rsa密钥:
ssh-keygen -t rsa -f ./id_rsaid_rsa为私钥,id_rsa.pub为公钥,注意不要覆盖原有的密钥。
将私钥存放在本地客户端的指定位置(通常是
"~/.ssh/"),并导入公钥到服务器:cat ./id_rsa.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"然後就可以直接免密登录,此外,SSH还可以使用证书登录(此处不讲)。
SSH服务器的开启,只需要安装openssh相应软件包,开启sshd服务即可。
NFS
网络文件系统(NFS)是分布式文件系统协议,允许客户端上的用户像访问本地文件一样访问网络文件。目前使用的版本有NFS v3和NFS v4,前者兼容性更好,後者提供有状态的连接。
这里讲的是NFS v3版本(无状态连接的),无用户名和密码验证也决定了其更适合内网使用。
配置nfs服务:(全局配置文件"/etc/nfs.conf",简单配置无需编辑此文件)
编辑文件"/etc/exports",添加内容示例如下:
1 | |
然後,重新导出并启用nfs服务:
exportfs -arv
systemctl enable --now nfs-server
- 查看rpcbind绑定的端口:
"rpcinfo -p" - 查看远程主机的NFS共享目录:
"showmount -e servername" - 挂载NFS文件系统:
"mount -t nfs servername:/exportpath mountpoint"
接下来说明"/etc/exports"的配置:
每行导出一个共享目录,行首是共享目录的绝对路径,其後接导出说明。导出说明由"Machine Name"和"RPCSEC_GSS security","User ID Mapping"组成,详见:Linux man: NFS server export
table
前者一般是一个IP地址网络号,以允许匹配的客户机访问该nfs服务。後者紧接着且用小括号包括,不同配置项以逗号分隔,常用的有:
"ro","rw"前者是默认选择,此项为读写权限"sync","async"前者默认,同步和异步"root_squash","no_root_squash"前者默认,客户端root用户是否映射到匿名用户"no_all_squash","all_squash"前者默认,是否将客户端所有用户映射到匿名用户"anonuid=uid","anongid=gid"设置匿名用户的uid(用户id)和gid(组id)
exports匹配的客户端才能挂载其共享目录(用IP或主机名来匹配)。
nfs的工作机制:nfsd服务监听连接(端口2049),idmapd处理用户映射,mountd验证客户端,portmapper处理RPC请求(远过程调用,端口111)。
客户端对其挂载的共享目录可以设置其创建文件的权限(要注意此权限不是服务端设置的,服务端的文件权限会限制客户端的访问)。NFS也继承了Linux文件系统访问权限的设计。
SMB
SMB是Windows的文件和打印机共享协议,Samba是Linux上实现的SMB/CIFS兼容协议,该协议在各平台有广泛支持,是较优的局域网文件共享协议。
Samba服务的配置文件是"/etc/samba/smb.conf",详细文档见smb.conf(5)和
smb.conf配置详细说明
Linux配置SMB服务:(采用standalone模式,tdbsam存储用户信息,user方式验证用户身份)
修改"/etc/samba/smb.conf"为如下内容:(修改後,运行"testparm"命令验证配置)
1 | |
Samba需要Linux账户才能使用,以已有Linux账户创建Samba账户:"smbpasswd -a yang"
查询Samba账户的命令:"pdbedit -L -v";更改Samba账户密码:"smbpasswd smbuser"
开启SMB服务:"systemctl enable --now smbd nmbd"或"systemctl enable --now smb nmb"
挂载SMB共享目录:"mount -t cifs //w.x.y.z/path/to/share mountpoint -o guest"
FTP
文件传输协议(FTP),服务器有一个主进程(用于接收新请求,对应着控制连接,默认端口21)和多个从属进程(用于处理单个请求,对应着数据连接,其他端口),采用TCP连接,明文传输。有主动模式(数据连接端口20)和被动模式(数据连接端口随机)。
Linux配置FTP服务:(需先安装vsftpd软件包)
更改"/etc/vsftpd.conf"为以下内容: vsftpd.conf配置详细说明
1 | |
执行以下命令以启用ftp服务:(可使用"ftp IP_address"命令连接ftp服务)
1 | |
如此,配置了共享目录"/home/anon"并允许匿名和本地用户访问。注意,vsftpd出于安全考虑,匿名共享根目录不能设置为完全访问权限。