iptables监控reset的连接信息 需求 如果连接被reset需要记录下reset包是哪边放出来的,并记录reset连接的四元组信息
iptables规则 1 2 3 4 5 6 7 8 9 10 11 12 # Generated by iptables-save v1.4.21 on Wed Apr 1 11:39:31 2020 *filter :INPUT ACCEPT [557:88127] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [527:171711] # 不监听3406上的reset,日志前面添加 [drds] -A INPUT -p tcp -m tcp ! --sport 3406 --tcp-flags RST RST -j LOG --log-prefix "[drds] " --log-level 7 --log-tcp-sequence --log-tcp-options --log-ip-options # -A INPUT -p tcp -m tcp ! --dport 3406 --tcp-flags RST RST -j LOG --log-prefix "[drds] " --log-level7 --log-tcp-sequence --log-tcp-options --log-ip-options -A OUTPUT -p tcp -m tcp ! --sport 3406 --tcp-flags RST RST -j LOG --log-prefix "[drds] " --log-level 7 --log-tcp-sequence --log-tcp-options --log-ip-options COMMIT # Completed on Wed Apr 1 11:39:31 2020
将如上配置保存在 drds_filter.conf中,设置开机启动:
1 2 3 //注意,tee 命令的 "-a" 选项的作用等同于 ">>" 命令,如果去除该选项,那么 tee 命令的作用就等同于 ">" 命令。 //echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid //sudo强行修改写入 echo "sudo iptables-restore < drds_filter.conf" | sudo tee -a /etc/rc.d/rc.local
单独记录到日志文件中 默认情况下 iptables 日志记录在 dmesg中不方便查询,可以修改rsyslog.d规则将日志存到单独的文件中:
1 2 # cat /etc/rsyslog.d/drds_filter_log.conf :msg, startswith, "[drds]" -/home/admin/logs/drds-tcp.log
将 [drds] 开头的日志存到对应的文件
将如上配置放到: /etc/rsyslog.d/ 目录下, 重启 rsyslog 就生效了
1 2 3 sudo cp /home/admin/drds-worker/install/drds_filter_log.conf /etc/rsyslog.d/drds_filter_log.conf sudo chown -R root:root /etc/rsyslog.d/drds_filter_log.conf sudo systemctl restart rsyslog
防止日志打满磁盘 配置 logrotate, 保留最近30天的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #cat /etc/logrotate.d/drds /home/admin/logs/drds-tcp.log { daily rotate 30 copytruncate compress dateext #size 1k prerotate /usr/bin/chattr -a /home/admin/logs/drds-tcp.log endscript postrotate /usr/bin/chattr +a /home/admin/logs/drds-tcp.log endscript } 执行: sudo /usr/sbin/logrotate --force --verbose /etc/logrotate.d/drds debug: sudo /usr/sbin/logrotate -d --verbose /etc/logrotate.d/drds 查看日志: cat /var/lib/logrotate/logrotate.status
logrotate操作的日志需要权限正常,并且上级目录权限也要对,解决方案参考:https://chasemp.github.io/2013/07/24/su-directive-logrotate/ 报错信息:
1 2 3 4 5 6 7 rotating pattern: /var/log/myapp/*.log weekly (4 rotations) empty log files are rotated, old logs are removed considering log /var/log/myapp/default.log error: skipping "/var/log/myapp/default.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation
最终效果 1 2 3 4 5 $tail -10 logs/drds-tcp.log Apr 26 15:27:36 vb kernel: [drds] IN= OUT=eth0 SRC=10.0.186.75 DST=10.0.175.109 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8182 DPT=9366 SEQ=0 ACK=1747027778 WINDOW=0 RES=0x00 ACK RST URGP=0 Apr 26 15:27:36 vb kernel: [drds] IN= OUT=eth0 SRC=10.0.186.75 DST=10.0.175.109 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8182 DPT=9368 SEQ=0 ACK=3840170438 WINDOW=0 RES=0x00 ACK RST URGP=0 Apr 26 15:27:36 vb kernel: [drds] IN= OUT=eth0 SRC=10.0.186.75 DST=10.0.175.109 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8182 DPT=9370 SEQ=0 ACK=3892381139 WINDOW=0 RES=0x00 ACK RST URGP=0 Apr 26 15:27:38 vb kernel: [drds] IN= OUT=eth0 SRC=10.0.186.75 DST=10.0.171.173 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8182 DPT=38225 SEQ=0 ACK=1436910913 WINDOW=0 RES=0x00 ACK RST URGP=0
NetFilter Hooks 下面几个 hook 是内核协议栈中已经定义好的:
NF_IP_PRE_ROUTING: 接收到的包进入协议栈后立即触发此 hook,在进行任何路由判断 (将包发往哪里)之前
NF_IP_LOCAL_IN: 接收到的包经过路由判断,如果目的是本机,将触发此 hook
NF_IP_FORWARD: 接收到的包经过路由判断,如果目的是其他机器,将触发此 hook
NF_IP_LOCAL_OUT: 本机产生的准备发送的包,在进入协议栈后立即触发此 hook
NF_IP_POST_ROUTING: 本机产生的准备发送的包或者转发的包,在经过路由判断之后, 将触发此 hook
IPTables 表和链(Tables and Chains) 下面可以看出,内置的 chain 名字和 netfilter hook 名字是一一对应的:
PREROUTING: 由 NF_IP_PRE_ROUTING hook 触发
INPUT: 由 NF_IP_LOCAL_IN hook 触发
FORWARD: 由 NF_IP_FORWARD hook 触发
OUTPUT: 由 NF_IP_LOCAL_OUT hook 触发
POSTROUTING: 由 NF_IP_POST_ROUTING hook 触发
tracing_point 监控 对于 4.19内核的kernel,可以通过tracing point来监控重传以及reset包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # grep tcp:tcp /sys/kernel/debug/tracing/available_events tcp:tcp_probe tcp:tcp_retransmit_synack tcp:tcp_rcv_space_adjust tcp:tcp_destroy_sock tcp:tcp_receive_reset tcp:tcp_send_reset tcp:tcp_retransmit_skb #开启本机发出的 reset 监控,默认输出到:/sys/kernel/debug/tracing/trace_pipe # echo 1 > /sys/kernel/debug/tracing/events/tcp/tcp_send_reset/enable #如下是开启重传以及reset的记录,本机ip 10.0.186.140 # cat trace_pipe //重传 <idle>-0 [002] ..s. 9520196.657431: tcp_retransmit_skb: sport=3306 dport=62460 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 Wisp-Root-Worke-540 [000] .... 9522308.074233: tcp_destroy_sock: sport=3306 dport=20594 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 sock_cookie=51a C2 CompilerThre-543 [002] ..s. 9522308.074296: tcp_destroy_sock: sport=3306 dport=20670 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 sock_cookie=574 // 被reset Wisp-Root-Worke-540 [002] ..s. 9522519.353756: tcp_receive_reset: sport=33822 dport=8080 saddr=10.0.186.140 daddr=10.0.171.193 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.193 sock_cookie=5dd // 主动reset DragoonAgent-28297 [002] .... 9522433.144611: tcp_send_reset: sport=8182 dport=61783 saddr=10.0.186.140 daddr=10.0.171.174 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.174 Wisp-Root-Worke-540 [002] ..s. 9522519.353773: tcp_send_reset: sport=33822 dport=8080 saddr=10.0.186.140 daddr=10.0.171.193 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.193 // 3306对端中断 cat-28727 [000] ..s. 9524341.650740: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23262 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_SYN_RECV newstate=TCP_ESTABLISHED <idle>-0 [000] .ns. 9524397.184608: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23262 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_ESTABLISHED newstate=TCP_CLOSE //8182 主动关闭 <idle>-0 [000] .Ns. 9525499.045236: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=8182 dport=25448 saddr=10.0.186.140 daddr=10.0.171.174 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.174 oldstate=TCP_SYN_RECV newstate=TCP_ESTABLISHED DragoonAgent-6240 [001] .... 9525499.118092: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=8182 dport=25448 saddr=10.0.186.140 daddr=10.0.171.174 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.174 oldstate=TCP_ESTABLISHED newstate=TCP_FIN_WAIT1 <idle>-0 [000] ..s. 9525499.159032: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=8182 dport=25448 saddr=10.0.186.140 daddr=10.0.171.174 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.174 oldstate=TCP_FIN_WAIT1 newstate=TCP_FIN_WAIT2 <idle>-0 [000] .Ns. 9525499.159056: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=8182 dport=25448 saddr=10.0.186.140 daddr=10.0.171.174 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.171.174 oldstate=TCP_FIN_WAIT2 newstate=TCP_CLOSE //3306 被动关闭 <idle>-0 [002] .Ns. 9524484.864509: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23360 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_SYN_RECV newstate=TCP_ESTABLISHED cat-28568 [002] ..s. 9524496.913199: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23360 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_ESTABLISHED newstate=TCP_CLOSE_WAIT Wisp-Root-Worke-540 [003] .... 9524496.915450: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23360 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_CLOSE_WAIT newstate=TCP_LAST_ACK Wisp-Root-Worke-539 [002] .Ns. 9524496.915572: inet_sock_set_state: family=AF_INET protocol=IPPROTO_TCP sport=3306 dport=23360 saddr=10.0.186.140 daddr=10.0.186.70 saddrv6=::ffff:10.0.186.140 daddrv6=::ffff:10.0.186.70 oldstate=TCP_LAST_ACK newstate=TCP_CLOSE
iptables 打通网络 1 2 //本机到 172.16.0.102 不通,但是和 47.100.29.16能通(阿里云弹性ip) iptables -t nat -A OUTPUT -d 172.16.0.102 -j DNAT --to-destination 47.100.29.16
参考资料 深入理解 iptables 和 netfilter 架构
NAT - 网络地址转换(2016)