TCP 连接状态

TCP,全称Transfer Control Protocol,中文名为传输控制协议,它工作在OSI的传输层,提供面向连接的可靠传输服务,TCP的工作主要是建立连接,然后从应用层程序中接收数据并进行传输。TCP采用虚电路连接方式进行工作,在发送数据前它需要在发送方和接收方建立一个连接,数据在发送出去后,发送方会等待接收方给出一个确认性的应答,否则发送方将认为此数据丢失,并重新发送此数据。

在建立连接的时候,所谓的客户端与服务端是相对应的,即要看是谁主动连接的谁,如果A主动连接B那 么A就是客户端而B是服务端,如果返过来B主动连接A,那么B就是客户端而A就成了服务端。

TCP端口的十一种连接状态

CLOSED:端口默认是关闭状态。 

LISTEN: 服务器程序开始监听一个端口,就是LISTEN状态。 

SYN_RCVD:三次握手的第二次握手后的端口状态,是收到了客户端发送的SYN_SENT数据包之后的状态,这 个状
态很短暂,正常在服务器上是很少看到的,除非服务器故意不发送最后一次握手数据包,服务器返回给客 户端
SYN确认之后就会将在自己的端口置为SYN_RCVD。

SYN_SENT:SYN_SENT状态表示客户端已发送SYN=1的请求连接报文,发送之后客户端就会将自己的端口状 态置
为SYN_SENT。 

ESTABLISHED:表示已经连接成功,客户端收到服务器的确认报文会回复服务器,然后就将端口置为 
ESTABLISHED,服务器第三次收到客户端的Ack确认就会将端口置为ESTABLISHED并开始传输数据。 

FIN_WAIT_1:出现在主动关闭方,FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,当任意一 方
想主动关闭连接,向对方发送了FIN=1的断开连接请求报文,此时该SOCKET即 进入到FIN_WAIT_1状态。 而当
对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上
回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用 netstat看到。 

FIN_WAIT_2:出现在主动关闭方,当被动方回应FIN_WAIT_1的ACK报文后,则进入到FIN_WAIT_2状态 

TIME_WAIT:出现在主动关闭方,表示收到了对方的FIN请求关闭报文,并发送出了ACK报文,就等2MSL后即 可
回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以 直接
进入到 TIME_WAIT状态,而无须经过FIN_WAIT_2状态。 

CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当 你
发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是
 CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下
 会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那
 么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

CLOSE_WAIT: 表示在等待关闭端口,这种状态存在于被动关闭的一方。 LAST_ACK: 是被动关闭方在主动关
闭一方在发送FIN报文后,最后等待对方的ACK报文,当再次收到ACK报 文后,也即可以进入到CLOSED可用状态了。

LAST_ACK: 是被动关闭方在主动关闭一方在发送FIN报文后,最后等待对方的ACK报文,当再次收到ACK报文
后,也即可以进入到CLOSED可用状态了。

端口状态转换

安装服务端与客户端将端口状态区分:

主动端口方:SYN_SENT、FIN_WAIT1、FIN_WAIT2、CLOSING、TIME_WAIT
被动断开方:LISTEN、SYN_RCVD、CLOSE_WAIT、LAST_ACK
都具有的:CLOSED 、ESTABLISHED

blackbox端口监控 zabbix监控tcp端口_linux

TCP 三次握手

blackbox端口监控 zabbix监控tcp端口_linux_02

TCP 四次挥手

blackbox端口监控 zabbix监控tcp端口_TCP_03

监控 TCP 连接状态

为了测试效果,在主动模式下,因为主动模式获取数据比较快一些

编写获取 TCP 状态的脚本

在机器172.20.32.105上面编写脚本
一般脚本放在/etc/zabbix/zabbix_agentd.d/这个文件目录下

root@Mysql-slave:~# cd /etc/zabbix/zabbix_agentd.d/
root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# vim linux_tcp_status.sh
#!/bin/bash
# 
# Edited on 20200501 by likai.tech
#
tcp_conn_status(){
         TCP_STAT=$1
         ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}' > /tmp/tcp_conn.txt
         TCP_NUM=$(grep "$TCP_STAT" /tmp/tcp_conn.txt | cut -d ' ' -f2)
         if [ -z $TCP_NUM ];then
                TCP_NUM=0
         fi
        echo $TCP_NUM 
}

main(){
        case $1 in
                tcp_status)
                         tcp_conn_status $2;
                         ;;
        esac
}

main $1 $2

root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# chmod a+x linux_tcp_status.sh

测试

root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# bash linux_tcp_status.sh tcp_status LISTEN
24
root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# bash linux_tcp_status.sh tcp_status ESTAB
3
root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# bash linux_tcp_status.sh tcp_status TIME-WAIT
34

在 agent 配置文件添加自定义监控项

zabbix agent 添加自定义监控项并调用脚本获取到监控项数据

root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# vim /etc/zabbix/zabbix_agentd.conf 
### Option: UserParameter
#       User-defined parameter to monitor. There can be several user-defined parameters.
#       Format: UserParameter=<key>,<shell command>
#       See 'zabbix_agentd' directory for examples.
#
# Mandatory: no
# Default:
# UserParameter=
# 添加监控项和调用的脚本
UserParameter=linux_tcp_status[*],bin/bash /etc/zabbix/zabbix_agentd.d/linux_tcp_status.sh "$1" "$2"
......
root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# systemctl restart zabbix-agent.service

测试自定义监控项

在172.20.32.101 zabbix server主机上面进行测试:

root@Zabbix-server:~# 
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_tcp_status["tcp_status","LISTEN"]"
26
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_tcp_status["tcp_status","ESTAB"]"
4
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_tcp_status["tcp_status","TIME-WAIT"]"
34

创建模板

在 web 添加自定义监控项

blackbox端口监控 zabbix监控tcp端口_sql_04

blackbox端口监控 zabbix监控tcp端口_linux_05


添加自定义监控

添加自定义监控项:

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_06

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_07

blackbox端口监控 zabbix监控tcp端口_linux_08

创建图形

图形是来自监控项的

blackbox端口监控 zabbix监控tcp端口_linux_09


blackbox端口监控 zabbix监控tcp端口_TCP_10


blackbox端口监控 zabbix监控tcp端口_sql_11


blackbox端口监控 zabbix监控tcp端口_linux_12

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_13


同理添加time-wait的监控图形:

blackbox端口监控 zabbix监控tcp端口_linux_14

blackbox端口监控 zabbix监控tcp端口_sql_15

查看监控数据

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_16

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_17

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_18

导入模板自定义监控

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_19

blackbox端口监控 zabbix监控tcp端口_linux_20

blackbox端口监控 zabbix监控tcp端口_linux_21

点击上图中的监控项11,可以看到具体的监控项

blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_22


在172.20.32.105的agent服务器中配置文件中添加新的一个自定义项,其中的key键值要和模板中的键值保持一致

如上图的键值为linux_status

root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# vim /etc/zabbix/zabbix_agentd.conf 
### Option: UserParameter
#       User-defined parameter to monitor. There can be several user-defined parameters.
#       Format: UserParameter=<key>,<shell command>
#       See 'zabbix_agentd' directory for examples.
#
# Mandatory: no
# Default:
# UserParameter=
UserParameter=linux_tcp_status[*],bin/bash /etc/zabbix/zabbix_agentd.d/linux_tcp_status.sh "$1" "$2"
#新增加导入模板的键值以及关联的脚本
UserParameter=linux_status[*],bin/bash /etc/zabbix/zabbix_agentd.d/linux_tcp_status.sh "$1" "$2"
······
root@Mysql-slave:/etc/zabbix/zabbix_agentd.d# systemctl restart zabbix-agent.service

在172.20.32.101的server服务器中先测试单个命令是否能够获取对应的监控项资源

root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_status["tcp_status","TIME-WAIT"]"
34
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_status["tcp_status","ESTAB"]" 
5
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_status["tcp_status","SYN-RECV"]"
0
root@Zabbix-server:~# /apps/zabbix_server/bin/zabbix_get -s 172.20.32.105 -p10050 -k "linux_status["tcp_status","TIME-WAIT"]"
34

成功返回资源监控数据就可以关联主机了

导入监控模板关联主机

blackbox端口监控 zabbix监控tcp端口_linux_23

blackbox端口监控 zabbix监控tcp端口_sql_24

blackbox端口监控 zabbix监控tcp端口_TCP_25


blackbox端口监控 zabbix监控tcp端口_blackbox端口监控_26

数据检测

blackbox端口监控 zabbix监控tcp端口_sql_27


监控项创建基础的模板,然后对主机和模板的关联即可,最大限度的对模板进行复用,减少重复对主机单个监控项的添加