好记性不如烂笔头, 网络基础知识备忘.
概览
OSI 7层模型
OSI/开放式系统互联通讯参考
- 7: 应用层: HTTP,FTP,Telnet, SSH, SMTP, POP3
- 6: 表达层
- 5: 会话层
- 4: 传输层: TCP
- 3: 网络层: IP
- 2: 数据链路层: 以太网,WiFi,GPRS
- 1: 物理层 : 数据帧传输,包括网卡,集线器,主机适配器等
注: OSI参考模型不是一个标准,也没有提供实现方法,而且概念性框架.
TCP/IP协议集
互联网基础协议, 可以被认为是简化版OSI模型
- 应用层: HTTP, FTP, SMTP, DNS, TELNET
- 传输层: TCP(可靠传输), UDP
- 网络互连层(internet): IP, ARP
- 基于IP的高层协议
- ICMP: IP发送诊断信息
- IGMP: 管理多播数据
- 基于IP的高层协议
- 网络接口层(link): 以太网等
每个应用层协议一般会使用到两个传输层协议之一:
- 面向连接的TCP传输控制协议
- 无连接的包传输的UDP用户数据报文协议
常用协议归类
- 运行于TCP协议上的协议: HTTP/HTTPS/FTP/POP3/SMTP/TELNET/SSH
- 运行于UDP协议上的协议: BOOTP/NTP/DHCP
- 运行于TCP和UDP的协议: DNS/ECHO
- 其他协议: SNMP(简单网络管理协议)/ARP(地址解析协议)
Socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.
常用协议
TCP
UDP
UDP 建立连接的开销很低。 为保证数据包流的连续性,需要通过窗口大小和RTT(round-trip time)做计算,同时需要ACK确认。
适用场景:
- 能容忍数据丢失或新数据替代旧数据
- 期望一次性响应数据包
- 自己能保证稳定性或支持数据重发(resend)
- UDP支持多路广播(Multicasts)到多主机
TCP V.S UDP
- TCP优势
- 拥塞控制(congestion control)
- 特定场景更快: 有特别多远小于MTU的数据包传输(small-sized writes),因为TCP会先缓存数据然后填充网络字段
- UDP优势
- 分组分发(比TCP点对点的ACK更高效)
- 无须分发(out-of-order)
DNS/域名系统
- 域名和IP地址互相映射的分布式数据库.
- 使用TCP和UDP的53端口.
- 每级域名长度限制63,域名总长度不超过253字符.
记录类型
- 主机记录/A记录: 将特定的主机名映射到对应主机的IP地址上
- 别名记录/CNAME记录: 将某个别名指向到A记录
- IPv6主机记录/AAAA记录: 与A记录对应, 映射到IPv6地址
- 服务位置记录/SRV记录: 定义提供特定服务的服务器位置,如hostname,端口等
实现
全球有13组,504个根域名服务器, 为层次结构.
常用软件实现:
WHOIS/域名数据库查询
新的规定,域名机构不能返回注册者隐私信息.
NAT/网络地址转换
IP数据包通过路由器/防火墙时重写来源/目的IP的技术.
重写源/目的IP和端口.
解决的问题:
- 局域网环境只有一个公网IP
- 负载均衡: 重定向到随机服务器
- 失效终极: 转换到备用服务器,提高可靠性
- 透明代理: 重定向到指定HTTP代理以缓存数据和过滤请求
HTTP/HTTP2
协议
客户端(用户)和服务器端(网站)请求和应答标准.
请求方法
GET/HEAD/POST/PUT/DELETE/TRACE/OPTIONS/CONNECT/PATCH
HTTP服务器至少应该实现GET和HEAD方法.
版本
- HTTP/1.1: 1999年制定. 默认保持连接(Keep-Alive)
- HTTP/2: 2015年发布, 基于SPDY(Google主导的替代HTTP的项目,已被HTTP2取代). 主要为性能改进, 主流浏览器只支持加密通讯(即h2).
状态码
HTTP响应的第一行都是状态行, 状态代码是3位数字:
- 1xx消息——请求已被服务器接收,继续处理
- 2xx成功——请求已成功被服务器接收、理解、并接受
- 3xx重定向——需要后续操作才能完成这一请求
- 4xx请求错误——请求含有词法错误或者无法被执行
- 5xx服务器错误——服务器在处理某个正确请求时发生错误
例子
# 请求信息:
# 1. 请求行:指定方法、资源路径、协议版本
# 2. 请求头(Host是必须项)
GET / HTTP/1.1
Host: www.google.com
# 服务器应答
HTTP/1.1 200 OK
Content-Length: 3059
Server: GWS/2.0
Date: Sat, 11 Jan 2003 02:44:04 GMT
Content-Type: text/html
Cache-control: private
Set-Cookie: PREF=ID=73d4aef52e57bae9:TM=1042253044:LM=1042253044:S=SMCc_HRPCQiqy
X9j; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Connection: keep-alive
IP/因特网协议
子网指具有相同的前半部分地址的一组ip地址.
子网掩码/subnet mask
目的: 用来指明一个IP地址的哪些位标识的是主机所在的网络地址以及哪些位标识的是主机地址的位掩码.
可以表示为同地址一样的形式,也可以使用更简短的CIDR/无类别域间路由表示法.
比如 192.0.2.96/28表示的是一个前28位被用作网络号的IP地址(和255.255.255.240的意思一样)
IPv4
IPv4地址分3个部分: 网络部分,子网部分和主机部分.
共有3类IP地址,分别指定各部分占多少位.
类别 | 起始位 | 开始 | 结束 | 点分十进制掩码 | CIDR |
---|---|---|---|---|---|
A | 0 | 0.0.0.0 | 127.0.0.0 | 255.0.0.0 | /8 |
B | 10 | 128.0.0.0 | 191.255.0.0 | 255.255.0.0 | /16 |
C | 110 | 192.0.0.0 | 223.255.255.0 | 255.255.255.0 | /24 |
IPv6
连通性测试和检查
说明: 如果v6访问不通,需要检查IPv6网关和v6 DNS是否配置正确.
# 查看网卡地址
ip addr
ip addr | grep inet6
# 查看域名的v6地址
host -t AAAA ipv6.ustc.edu.cn
# 连通性
ping 192.168.10.10 # v4
ping6 ipv6.ustc.edu.cn
ping6 2001:da8:d800:642::248
# Windows 等价于
ping -6 2001:da8:d800:642::248
# 网关检查
ip route # v4
ip -f inet6 route # v6
本地服务测试
# 使用Python自带的服务,Python3.8+
python -m http.server 8000 --bind fd00::251:186f:4fd8:a3fe:5b8d
python -m http.server 8000 --bind 192.168.10.10
python -m http.server 8000 --bind ::
HTTP和TCP测试
# 浏览器访问
http://[fd00::251:186f:4fd8:a3fe:5b8d]:8000/
# telnet 端口测试
telnet fd00::251:186f:4fd8:a3fe:5b8d 8000
实现服务的对外IPv6支持
- IPv6 web server: 通常用Nginx入口网关配置
- 添加域名 AAAA的 DNS 记录
- IPv6 DNS server
Nginx配置
listen [::]:80 ipv6only=on;
Ubuntu 18.04配置
# 修改 /etc/netplan/50-cloud-init.yaml 增加
# addresses 的v6 地址
# gateway6 网关地址
# 及DNS v6 地址
sudo netplan apply
云主机支持
阿里自身的服务虽然18年底就实现了v6支持,但阿里云主机的v6支持现在还在公测阶段。(截止3/10/2020)
- DigitalOcean: 支持最友好的厂商
- 阿里云: 需要提交公测,选择支持的区域,购买IPv6网关带宽才可以
- 微软云: 需要购买负载均衡
扩展阅读
Docker网络
Docker 网络实质上是操纵Network Namespace, 网桥, 虚拟网卡及iptables实现的.
OVS (Open vSwitch): 开源虚拟交换机
ip netns 管理Network Namespace
ip link 管理layer2网络
ip addr 管理layer3网络
sudo apt install bridge-utils
brctl show
# 内核IP路由表
route -n
软件定义网络
flannel: 虚拟网络,给每台主机划分一个子网用于容器运行时