之前我们在讲tcp模块时讲了匹配条件--dport 等,没有讲到--tcp-flags这个匹配条件,这节我们单独来讲讲这个匹配条件的含义及用法。在讲之前 我们来聊聊关于tcp 头信息及三次握手的相关知识
上图展示了tcp头信息的结构,其中source port,destination port就是我们之前讲过的tcp模块的匹配条件中的--sport,--dport,其中在中间位置我-们发现有个位置,列出了7位由大写字母组成的字符,分别是,CWR,ECE,URG,ACK,PSH,RST,SYN,FIN,这些吗其实就是我们今天要讲的--tcp-flags匹配条件。
下面我们再来看看这些状态码在tcp三次握手中的作用及值的变化情况。
为了更加具象化的描述这个过程,我们可以抓包查看ssh建立连接的过程,如下图所示(使用wireshark在ssh客户端抓包,跟踪对应的tcp流):
上图为tcp三次握手中的第一次握手,客户端(IP为98)使用本地的随机端口54808向服务端(IP为137)发起连接请求,tcp头的标志位中,只有SYN位被标识为1,其他标志位均为0。
在上图的下方可以看到"[TCP Flags: ··········S·]",其中的"S"就表示SYN位,整体表示只有SYN位为1。
上图为tcp三次握手中第一次握手的tcp头中的标志位,下图是第二次握手的,服务端回应刚才的请求,将自己的tcp头的SYN标志位也设置为1,同时将ACK标志位也设置为1,如下图所示。
上图中的下方显示的标志位列表也变成了,[TCP Flags: ·······A··S·],表示只有ACK标志位与SYN标志位为1,如上图所示,第三次握手我就不再截图了,说到这里,就已经能够引出我们今天要说的话题了,就是"--tcp-flags"选项,假设,我现在想要匹配到上文中提到的"第一次握手"的报文,则可以使用如下命令:
iptables -t filter -I INPUT -p tcp -m tcp --dport --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
上例中的"SYN,ACK,FIN,RST,URG,PSH SYN"表示,需要匹配报文tcp头中的"SYN、ACK、FIN、RST、URG、PSH"这些标志位,其中SYN标志位必须为1,其他的5个标志位必须为0,这与上文中wireshark抓包时的情况相同,正是tcp三次握手时第一次握手时的情况,上文中第一次握手的报文的tcp头中的标志位.
好了 --tcp-flags 匹配条件就讲到这里了