linux-tcp,http, curl, dns

· 3221 words · 7 minute read

udp 🔗

光速:30万千米/s
中美具体大约:1.5万千米
光纤网络耗时的理论极值约是:0.05s=50ms
实际耗时在140ms以上。
第一宇宙速度7.9km/s 环绕速度
第二宇宙速度11.2km/s脱离速度
第三宇宙速度16.7km/s逃逸速度

quic 🔗


http2 优点:多路复用,头部压缩,服务器推送。 缺点:基于 tcp 时连接握手,多路复用时存在队头阻塞,丢包后导致后续其他包不可用,优化 tcp 和 tls 遥遥无期。

tcp 🔗

用寄明信片的方式传送一本书

明文, 乱序,丢包

  • 可靠: 带重传的累积正向应答
    • 编号
    • 累计的正向应答(ack number1, number1 之前均收到)
    • 超时没收到 ack 则重传。
  • flow control 滑动窗口
  • congestion control 拥塞控制

tcp 中最主要消耗 cpu 的状态是 established

学的时候教 handshake, byebye status。学车是教倒车入库,但是路上开车是主要点

tcp 报文结构图

  • URG: 表示紧急指针(urgent pointer)是否有效
  • PSH: 提示接收端应该立即从 TCP 接收缓冲区中读走数据,为接收后续数据腾出空间
  • RST:复位报文段,用来关闭异常的 TCP 连接 (重要) (4 种情况会出现: 端口未打开,请求超时,提前关闭,已经的 socket 上收到数据)
    • A 想 B 发起 tcp 连接,但是 B 上未监听相应的端口,此时 B 的 os 的网络模块会发送 RST 包给 A 端
    • syn 攻击时防火墙设置,向服务器发送 RST 包,清除未连接队列的数据包,保证避免 server 出现拒绝服务的情况
    • RST 攻击场景,攻击则伪装为客户端向 server 发送 RST 包,导致连接被强制关闭
  • window:是 TCP 流量控制的一个手段, 告诉对方本端的 TCP 接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度(sender 在未收到 ack 时最大发送的字节数)
  • checkSum: 校验数据包是否损坏

两个线程如何同时监听一个端口,SO_REUSEPORT 参数

  • 4 次挥手: A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束

tcp 握手与挥手过程图(基本图,实际中可以不是这样,例如关闭时双方同时发起关闭,双方都会到达 time_wait 状态)



⚠️ wireshake 上的 seq 和 ack number 是 relative number,0 和 1 是为了方便查看,实际情况是其他数值

TIME-WAIT 状态的理解:

  • 持续时间未 2MSL,一个数据包在网络中的最长生存时间为 MSL(30S)
  • 客户端回复的 ACK 丢失,服务器端会在超时时间到来时,重传最后一个 FIN 包
  • ACK 和 FIN 在网络中的最长生存时间就为 2MSL,这样就可以可靠的断开 TCP 的双向连接

服务器解决 TIME——WAIT(占用端口过多,导致无可用的端口)的方式 3 种:

  • 保证客户端主动关闭
  • 关闭时使用 RST 方式
  • 对于处于 TIME-WAIT 状态的 tcp 允许重用,修改内核参数(java 服务器访问 mysql 集群,主动关闭,time-wait 状态在服务器,他是发起方,可以复用 tcp 连接)
  • 当利用 http 发送请求时,keep-alive 减少 tcp 连接数,进而减少 time-wait 状态的出现

TCP 如何实现可靠传输(数据应答机制+数据超时重传)

  • 数据包都序列号,保证接收方能恢复数据包的顺序,去重等
  • 超时重传(确认和重传), 也有快速重传,不用等待超时时间
    • 超时时间大于 RTT(一次往返时间)
    • 每个被发送的数据包均有计时器,只有超过计时器的重传时间后,才会重发数据包
    • 1988 最早的超时重传 RTO = min(ubound, max(lbound, beta _ SRTT)); SRTT= (alph _ SRTT) + (1- alpha) * RTT ; alpha=0.8, 0.9 beta=1.2, 1.3
    • RTO 比 RTT 大很多时,若出现网络丢包,重传速度很慢; RTO 假设比 RTT 小时,会出现大量的重传; 所以 RTO 的时间比较考量

TCP 如何实现流量控制

  • 当接受方处理不过来时,接受方缩小窗口,告知发送方
  • 以字节为单位的滑动窗口技术
    • recv 的窗口大小决定 sender 的窗口大小(窗口以字节为单位)
    • sender 缓存中的数据包必须收到 recv 的确认数据包后才能删除
  • 当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失

TCP 如何实现拥塞控制

  • 当网络拥塞时,动态改变发送窗口大小,减少数据的发送

基于 TCP 的攻击

  • SYN 泛洪攻击
    • 发送大量的 SYN 包,导致 server 上未连接队列满,导致拒绝正常的连接服务
    • 解决方法:
      • SYN 网关, 防火墙收到 SYN 包转给 server,防火墙收到 server 的 ack/syn 后,转给 client;同时防火墙以 client 的名义直接给 server 发送 ack,完成 3 次握手。 server 上连接数远大于未连接数。
      • 被动式 SYN 网关,防火墙设置小的超时时间,超时时向 server 发送 RST 包,导致关闭半连接
      • SYN 中继, 完全有防火墙做代理,防火墙与 client 握手完成表明正常后,在于 server 完成 3 次握手
  • RST 攻击 (ip 头+tcp 头 40 字节)
    • 场景: A--》B, C(伪装 A)--》B, 发送 RST 包,或者正在连接时发送 SYN 包,B 会清空 A 请求过来的数据包,强制关闭连接
    • C 如何伪装 A (tcp 四要素:源 ip(容易知道),源 port,目的 ip(容易知道),目的 port(容易知道))
      • 关键是知道源 port(发现 os 分配时的规律)和序列号(需要在 B 的滑动窗口内,不然会被丢弃)
      • 大量发送数据包(带宽不是问题,RST 包很小)保证一个落在 B 的滑动窗口内 ,sequence number 为 32 位,滑动窗口为 65535,相除为 65537 个数据包就有一个落在区间内

http 🔗

http header 常用字段:

  • content-type (如何解析 body)
    • application/x-www-form-urlencoded
    • multipart/from-data, 上传文件
    • application/json, text/plain
    • text/xml, XML 格式 (post 请求的 4 种格式)
  • connection: keep-alive, 持久连接(相对于用完就关闭的短连接而言)
  • keep-alive-time: 300, 指连接维持的时间
  • content-length: 120, 指明响应的内容有 120 字节 (出现等于-1,但是 body 有数据的情况?)
  • transfer-encoding: chunked, 响应内容采用分块传输,最后一个分块为 0 表示传输结束

http keep-alive 与 tcp keep alive 区别与联系:http 用于连接复用, tcp 用于保证连接存活,发送探测包确认连接是否存活。

有时 ping url 结果为 unkown host,但是 curl url 可以通, 有可能对方防火墙屏蔽 ping 的 ICMP 协议。

CORS, CSRF 🔗

CORS(跨域资源共享): 一种浏览器安全机制,它允许受信任的域对其他域的资源进行访问。

curl 模拟跨域访问。

curl -H 'Origin: 123' ip:port/uri --verbose 发起跨域 http 请求, 当 http 的响应 header 中出现Access-Control-Allow-Origin: * 时证明后端允许跨域访问。


CSRF(跨站请求伪造): http 的 header 里 referer 过滤跨站点请求。 csrf token。

curl 命令 🔗

发 get 请求: 不带参数 curl xx.com。发 post 请求: curl -X POST xx.com。

  • -I only response header

  • -v 显示 http 通信过程 --trace

  • curl -u username :password URL

  • curl 查询单词

    • curl dict://dict.org/d:xxx 查询 xxx 的含义
    • curl dict://dict.org/show:db 列出可用的词典
    • curl dict://dict.org/d:xx:foldoc 利用 foldoc 查询 xx 的含义
  • 给 curl 设置代理

    • curl -x proxyserver.test.com:9090 google.com
  • 将 cookie 保存到本地

    • curl -D localCookie google.com
    • curl -b localCookie google.com 使用上次的 cookie
    • curl -c cookie url 保存 cookie 到文件
  • 默认 curl 使用 get 方式 发送表单

    • curl -u username github.com
  • 可以通过--data/-d 方式使用 post

    • curl -u username --data "param1=value1&param2=value2" github.com
    • curl --data @filename github.com 将文件中的数据传给服务器
  • User Agent (-A , -H)

    • curl --user-agent "user-agent" url
  • cookie (-b)

    • curl --cookie "name=xx" url
    • cookie 值可以从 response header 的·Set-Cookie·字段得到
  • 自行加 request header 信息

    • curl --header "" url
  • curl -d '{"key1":"value1", "data":{"data1":"value1", "data2":"value2"}}' 'https://xxx.com/a/b'

  • curl -F 'business_type=one' -F 'data=@/Users/kk/a.csv' x.x.x.x:xx/a/b curl 发送文件

  • curl -G -d 'q=xx' xx.com -d ''//xx.com?q=xx

  • ping icmp 协议 封装在 IP 包里

    • 类型 0 8 请求与响应
    • 3 是不可达 后面有代码号
      • 5 种情况
        • ip 中的网络号-网络不可达
        • ip 中的主机号-主机不可达
        • 防火墙不允许 tcp 连接-协议不可达
        • 端口没有进程监听-端口不可达

dns 🔗

dig 查询 DNS 相关信息的工具,显示 internet 上 13 个根域服务器,dig @dnsserver name querytype,用 google 的 dns 查询 baidu 的 A 记录, dig @8.8.8.8 www.baidu.com A。

  • DNS 记录的类型
    • A 记录 指定域名对应的 IP 地址
    • AAAA 记录 指定域名对应的 IPV6 地址
    • CNAME 记录 别名解析 域名 1(CDN 加速域名) -》域名 2 -》IP
    • NS 记录 域名服务器记录 将域名解析交给其他 DNS 服务器

访问 github.com 时与 DNS 解析有关的一个问题 🔗

问题:fatal: unable to access 'https://github.com/brettKK/shell.git/': Failed to connect to github.com port 443: Operation timed out
方法:vim /etc/hosts ==> find github.com to delete

网络常用工具命令(文件夹 network) 🔗

  • ss = socket statistics
    • 用来显示处于活动状态的套接字信息
    • 快,利用到了 TCP 协议栈中 tcp_diag
    • ss -t 显示 tcp 连接
  • nc 网络发包工具
  • netstat
    • netstat -an
  • tcpdump
常见命令:
#netstat -antp [n是ip显示,不用域名,t是tcp, ]
recv-q, send-q。
#cat /proc/net/netstat 计数器 netstat -st
  TCPListenOverflows 全连接队列,没处理accept。
#netstat -nr 看路由表 route -n
#ss -antp -m -i
listen状态下 send-q表示backlog的长度。
#ifconfig, txqueuelen 发送队列的包数量
#sar -n DEV 1
#查看有些路由表 vim /etc/iproute2/rt_tables
# ip rule show table all 查看所有路由
# telnet
# nmap
# tcpdump

traffic control 流量控制 入门:

#tc qdisc show 显示网卡的排队规则
# tc qd add dev ens33 root netem delay 200ms

socket option: socket ,bind, listen, accpet man 7 socket 两个进程监听同一个端口,so_reuseport(since linux 3.9)。