网站开发使用技术第二版答案,cms网站管理系统制作,建设银行第三方网站鉴权,注册网站公司作者#xff1a;轩辕之风O来源#xff1a; 编程技术宇宙前言大家好#xff0c;我是轩辕。前几天#xff0c;我在读者群里提了一个问题#xff1a;这一下#xff0c;大家总算停止了灌水#xff08;这群人都不用上班的#xff0c;天天划水摸鱼#xff09;#xff0c;开… 作者轩辕之风O来源 编程技术宇宙前言大家好我是轩辕。前几天我在读者群里提了一个问题这一下大家总算停止了灌水这群人都不用上班的天天划水摸鱼开始讨论起这个问题来。有的说通过User-Agent可以看我直接给了一个狗头。然后发现不对劲改口说可以通过HTTP响应的Server字段看比如看到像这种的那肯定Windows无疑了。HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Fri, 23 Aug 2019 01:02:08 GMT
Accept-Ranges: bytes
ETag: e65855634e59d51:0
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Fri, 23 Jul 2021 06:02:38 GMT
Content-Length: 1375
还有的说可以通过URL路径来判断如果大小写敏感就是Linux不敏感就是Windows。于是我进一步提高了难度如果连Web服务也没有只有一个TCP Server呢这时又有人说可以通过ping这个IP查看ICMP报文中的TTL值如果是xxx就是xx系统如果是yyy就是yy系统···不过有些情况下也不是太准确从TCP重传说起今天想跟大家探讨的是另外一种方法这个方法的思路来源于前几天被删掉的那篇文章。就是日本网络环境下访问不了极客时间的问题当时抓包看到的情况是这个图的样子看到了服务器后面在不断的尝试重发了吗当时我就想到了一个问题服务器到底会重传好多次呢众所周知TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。其中可靠性的一个重要体现就是它的超时重传机制。TCP的通信中有一个确认机制我发给你了数据你得告诉我你收到没这样双方才能继续通信下去这个确认机制是通过序列号SEQ和确认号ACK来实现的。简单来说当发送方给接收方发送了一个报文而接收方在规定的时间里没有给出应答那发送方将认为有必要重发。那具体最多重发多少次呢关于这一点RFC中关于TCP的文档并未明确规定出来只是给了一些在总超时时间上的参考这就导致不同的操作系统在实现这一机制的时候可能会有一些差异。于是我进一步想到了另一个问题会不会不同操作系统重传次数不一样这样就能通过这一点来判断操作系统了呢然后我翻看了《TCP/IP详解·卷1》试图在里面寻找答案果然这本神书从来没有让我失望过这一段说了个什么事情呢大意是说RFC标准中建议有两个参数R1和R2来控制重传的次数Linux中这俩参数可以这样看cat /proc/sys/net/ipv4/tcp_retries1
cat /proc/sys/net/ipv4/tcp_retries2tcp_retries1默认值是3tcp_retries2默认值是15。但需要特别注意的是并不是最多重传3次或者15次Linux内部有一套算法这两个值是算法中非常重要的参数而不是重传次数本身。具体的重传次数还与RTO有关系具体的算法有兴趣的朋友可以看看这篇文章聊一聊重传次数http://perthcharles.github.io/2015/09/07/wiki-tcp-retries/总体来说在Linux上重传的次数不是一个固定值而是不同的连接根据tcp_retries2和RTO计算出来的一个动态值不固定。而在Windows上也有一个变量来控制重传次数可以在注册表中设定它键值路径
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters键值名
TcpMaxDataRetransmissions默认值5
我手里有一份Windows XP的源码在实现协议栈的驱动tcpip.sys的部分中也印证了这个信息从注册表中读取键值没有读到的默认值不过就目前的信息来看由于Linux的重传次数是不固定的还没法用这个重传次数来判断操作系统。TCP之SYNACK的重传就在我想要放弃的时候我再一次品读《TCP/IP详解·卷1》中的那段话发现另一个信息TCP的重传在建立连接阶段和数据传输阶段是不一样的上面说到的重传次数限制是针对的是TCP连接已经建立完成在数据传输过程中发生超时重传后的重传次数情况描述。而在TCP建立连接的过程中也就是三次握手的过程中发生超时重传它的次数限定是有另外一套约定的。Linux在Linux中另外还有两个参数来限定建立连接阶段的重传次数cat /proc/sys/net/ipv4/tcp_syn_retries
cat /proc/sys/net/ipv4/tcp_synack_retries
tcp_syn_retries限定作为客户端的时候发起TCP连接最多重传SYN的次数Linux3.10中默认是6Linux2.6中是5。tcp_synack_retries限定作为服务端的时候收到SYN后最多重传SYNACK的次数默认是5重点来关注这个tcp_synack_retries它指的就是TCP的三次握手中服务端回复了第二次握手包但客户端一直没发来第三次握手包时服务端会重发的次数。我们知道正常情况下TCP的三次握手是这个样子的但如果客户端不给服务端发起第三个包那服务端就会重发它的第二次握手包情况就会变成下面这样所以这个tcp_synack_retries实际上规定的就是上面这种情况下服务端会重传SYNACK的次数。为了进一步验证我使用Python写了一段代码用来手动发送TCP报文里面使用的发包库是scapy这个我之前写过一篇文章介绍它面向监狱编程就靠它了。下面的这段代码我向目标IP的指定端口只发送了一个SYN包def tcp_syn_test(ip, port):# 第一次握手发送SYN包# 请求端口和初始序列号随机生成# 使用sr1发送而不用send发送因为sr1会接收返回的内容ans sr1(IP(dstip) / TCP(dportport, sportRandShort(), seqRandInt(), flagsS), verboseFalse)
用上面这段代码向一台Linux的服务器发送抓包来看一下实际验证服务器确实重传了5次SYNACK报文。一台服务器说明不了问题我又多找了几个结果都是5次。再来看一下Linux的源码中关于这个次数的定义接下来看一下Windows上的情况。Windows前面说过在注册表HKLM\System\CurrentControlSet\Services\Tcpip\Parameters目录下有一个叫TcpMaxDataRetransmissions的参数可以用来控制数据重传次数不过那是限定的数据传输阶段的重传次数。根据MSDN上的介绍除了这个参数还有另一个参数用来限制上面SYNACK重传的次数它就是TcpMaxConnectResponseRetransmissions。而且有趣的是和Linux上的默认值不一样Windows上的默认值是2。这就有意思了通过这一点就能把Windows和Linux区分开来。我赶紧用虚拟机中的XP上跑了一个nginx测试了一下果然是2次随后我又换了一个Windows Server 2008依旧是2次。为了进一步验证我通过注册表把这个值设定成了4再来试一下重传次数果然变成了4次了。接下来在手中的Windows XP源码中去印证这个信息果然不管是从实验还是从源码中都得到了同一个结论Linux上SYNACK默认重传5次。Windows上SYNACK默认重传2次。总结如果一个IP开启了基于TCP的服务不管是不是HTTP服务都可以通过向其发送SYN包观察其回应来判断对方是一个Linux操作系统还是一个Windows操作系统。当然这种方法的局限性还是挺大的。首先本文只介绍了一些默认的情况但TCP的重传次数是可以更改的如果网络管理员更改了这个数值判断的结果就不准确了。其次对于有些网络服务器开启了防DDoS功能测试发现其根本不会重传SYNACK包比如我用百度的IP测试就得到了这样的结果。最后没有测试其他操作系统上的情况比如Unix和MAC OSX为什么呢因此文中介绍的这种方法只能作为一种辅助手段仅供参考大家能顺便了解一些关于TCP重传的知识也是很有意义的。