iptables通过raw表实现日志输出和调试

说明:iptables调试的最好方式应该是输出日志了。并且iptables有个raw的表,优先级别最好,且调试时针对icmp协议(ping)进行,那么日志输出就是整条链路串起来输出的,非常的清晰。

背景:

在配置folsom版openstack的quantum时出现vm无法ping通外网的问题,经过抓包分析确定问题是iptables中的snat规则不生效,需要调试iptables定位下有问题的iptables规则。 iptables有5个链: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING,4个表: filter, nat, mangle, raw,其工作流在下图表示的很清楚。

从图中可见raw拥有最高的优先级,raw表使用PREROUTING和OUTPUT两个链,因此raw可以覆盖所有包。在raw表中支持一个特殊的目标:TRACE,使内核记录下每条匹配该包的对应iptables规则信息。使用raw表内的TRACE target即可实现对iptables规则的跟踪调试。

配置:

假设需要对ipv4的ICMP包进行跟踪调试,抓取所有流经本机的ICMP包

iptables -t raw -A OUTPUT -p icmp -j TRACEiptables -t raw -A PREROUTING -p icmp -j TRACE

加载对应内核模组

modprobe ipt_LOG

调试信息记录在/var/log/kern.log文件(也可以查看/var/log/messages)。

示例调试:

在vm内对外部作ping操作,vm的ip为10.0.0.4

[[email protected]10-0-0-4 ~]# ping -c 1 192.168.0.19
PING 192.168.0.19 (192.168.0.19)56(84) bytes of data.

--- 192.168.0.19 ping statistics ---1 packets transmitted, 0 received, 100% packet loss, time 0ms

在/var/log/kern.log中的对应调试信息如下

Apr 1811:50:23 openstack-network kernel: [1038991.870882] TRACE: raw:PREROUTING:policy:2IN=tap5c42978b-ac OUT= MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=64ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870902] TRACE: nat:PREROUTING:rule:1IN=tap5c42978b-ac OUT= MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=64ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870909] TRACE: nat:quantum-l3-agent-PREROUTING:return:4IN=tap5c42978b-ac OUT= MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=64ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870915] TRACE: nat:PREROUTING:policy:2IN=tap5c42978b-ac OUT= MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=64ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870938] TRACE: filter:FORWARD:rule:1IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870944] TRACE: filter:quantum-filter-top:rule:1IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870950] TRACE: filter:quantum-l3-agent-local:return:1IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870957] TRACE: filter:quantum-filter-top:return:2IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870962] TRACE: filter:FORWARD:rule:2IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870969] TRACE: filter:quantum-l3-agent-FORWARD:return:1IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870974] TRACE: filter:FORWARD:policy:3IN=tap5c42978b-ac OUT=br-ex MAC=fa:16:3e:a7:0c:f3:fa:16:3e:a4:49:14:08:00 SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870979] TRACE: nat:POSTROUTING:rule:1IN= OUT=br-ex SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1
Apr 1811:50:23 openstack-network kernel: [1038991.870985] TRACE: nat:quantum-l3-agent-POSTROUTING:rule:1IN= OUT=br-ex SRC=10.0.0.4 DST=192.168.0.19 LEN=84TOS=0x00 PREC=0x00 TTL=63ID=0 DF PROTO=ICMP TYPE=8CODE=0ID=28976SEQ=1

可见数据包流在nat表的quantum-l3-agent-POSTROUTING的第一条规则处被截断了,查看iptables中的nat表的规则如下

*nat
:PREROUTING ACCEPT [99:21975]
:INPUT ACCEPT [74:20608]
:OUTPUT ACCEPT [181:30548]
:POSTROUTING ACCEPT [26:13022]
:quantum-l3-agent-OUTPUT - [0:0]
:quantum-l3-agent-POSTROUTING - [0:0]
:quantum-l3-agent-PREROUTING - [0:0]
:quantum-l3-agent-float-snat - [0:0]
:quantum-l3-agent-snat - [0:0]
:quantum-postrouting-bottom - [0:0]-A PREROUTING -j quantum-l3-agent-PREROUTING
-A OUTPUT -j quantum-l3-agent-OUTPUT
-A POSTROUTING -j quantum-l3-agent-POSTROUTING
-A POSTROUTING -j quantum-postrouting-bottom
-A quantum-l3-agent-OUTPUT -d 192.168.0.16/32-j DNAT --to-destination 10.0.0.4
-A quantum-l3-agent-OUTPUT -d 192.168.0.17/32-j DNAT --to-destination 10.0.0.3
-A quantum-l3-agent-POSTROUTING !-i qg-91757ded-c4 !-o qg-91757ded-c4 -m conntrack !--ctstate DNAT -j ACCEPT
-A quantum-l3-agent-POSTROUTING -s 10.0.0.0/24-d 192.168.1.1/32-j ACCEPT
-A quantum-l3-agent-PREROUTING -d 169.254.169.254/32-p tcp -m tcp --dport80-j DNAT --to-destination 192.168.1.1:8775-A quantum-l3-agent-PREROUTING -d 192.168.0.16/32-j DNAT --to-destination 10.0.0.4
-A quantum-l3-agent-PREROUTING -d 192.168.0.17/32-j DNAT --to-destination 10.0.0.3
-A quantum-l3-agent-float-snat -s 10.0.0.4/32-j SNAT --to-source 192.168.0.16
-A quantum-l3-agent-snat -j quantum-l3-agent-float-snat
-A quantum-l3-agent-snat -s 10.0.0.0/24-j SNAT --to-source 192.168.0.15
-A quantum-postrouting-bottom -j quantum-l3-agent-snat
COMMIT

确定有问题的规则为

-A quantum-l3-agent-POSTROUTING !-i qg-91757ded-c4 !-o qg-91757ded-c4 -m conntrack !--ctstate DNAT -j ACCEPT

把这条规则删掉后重启iptables,vm能顺利连接外网,问题解决。

参考:

http://blog.51cto.com/flymanhi/1276331(以上内容转自此篇文章)

http://backreference.org/2010/06/11/iptables-debugging/

原文地址:https://www.cnblogs.com/EasonJim/p/8413563.html

时间: 2024-10-24 20:44:40

iptables通过raw表实现日志输出和调试的相关文章

树莓派(Debian)系统开启iptables的raw表实现日志输出

说明:可能Debian默认不开启iptables的raw表,所以无法通过其实现日志跟踪. 日志跟踪:http://www.cnblogs.com/EasonJim/p/8413563.html 解决方法: modprobe ipt_LOG modprobe nf_log_ipv4 sysctl net.netfilter.nf_log.2=nf_log_ipv4 查看日志:/var/log/syslog或者/var/log/kern.log或者/var/log/messages 参考: http

DS之顺序表实现乱序输入顺序输出

顺序表的实例有很多,在学其他的编程语言时,肯定都学过要求输入一串乱序的数字,要求进行排序,实现升序或降序输出.今天就来用顺序表实现乱序输入,顺序输出(升序). 实现上述的功能需要用到的顺序表的基本操作有0基本操作前的准备,1初始化顺序表,6向顺序表插入数据元素. 自己只需写一个排序的函数,排序函数的代码为: <span style="font-size:18px;">//排序函数 void paixu(SqList &L) { for(int i=0;i<L.

SQL SERVER 2014--内存表实现秒杀场景

===================================== 网上针对“秒杀”的解决方案很多,数据拆分化解热点,READPASH解决锁问题,应用程序排队限制并发等等很多方式,各有优缺点,只为证明一句名言:条条大路通罗马. ===================================== 今天拿SQL SERVER 2014的内存表来试水“秒杀”,内存表使用“版本”解决了高并发下锁请求和阻塞的问题,使用HASH索引来处理数据页“热点”的问题,解决了PAGE_LATCH等待,

用顺序表实现一个循环队列

队列是一种先进先出的线性表,简称FIFO.允许插入的一端为队尾,允许出列的一端为队头. 比如一个队列q=(p1,p2,p3,p4...pn),p1就是那个队头,pn就是队尾.出列时总是从p1开始 向后,入列时总是从pn后面插入.就像敲键盘,依次敲qwr,屏幕上显示的就是qwr,先敲的先显 示. 以下代码是用顺序表实现一个循环队列 1 /** 2 * @filename queue.c 3 * @author haohaibo 4 * @data 2017/4/12 5 * @brief 用顺序表

DS之顺序表实现输入数据逆置

实现输入数据逆置和顺序表实现排序是两个极其相似的过程,因此使用的顺序表的基本操作也是一样的:0基本操作前的准备,1初始化顺序表,6向顺序表插入数据元素. 要想实现输入数据元素的逆置还需要一个逆置函数,逆置函数在C++,C#语言中早已接触过,因此不陌生,记得在做大量的C++的程序代码补充的大题就写过不下数十遍,挺简单的掌握技巧,就是你输入数据的个数的一半,前后进行交换,因此逆置函数的代码为: <span style="font-size:18px;">//逆置函数 void

9 个技巧,解决 K8s 中的日志输出问题

作者 | 元乙??阿里云存储服务技术专家 导读:近年来,越来越多的同学咨询如何为 Kubernetes 构建一个日志系统,或者是来求助在此过程中遇到一系列问题如何解决,授人以鱼不如授人以渔,于是作者想把这些年积累的经验以文章的形式发出来,让看到文章的同学少走弯路.K8s 日志系列文章内容偏向落地实操以及经验分享,且内容会随着技术的迭代而不定期更新,本文为该系列文章的第 3 篇. 第一篇:<6 个 K8s 日志系统建设中的典型问题,你遇到过几个?> 第二篇:<一文看懂 K8s 日志系统设计

log4j(五)——如何控制不同目的地的日志输出?

一:测试环境与log4j(一)--为什么要使用log4j?一样,这里不再重述 二:老规矩,先来个栗子,然后再聊聊感受 import org.apache.log4j.*; import java.io.*; public class UseLog4j { //日志记录器 private static Logger LOGGER = LogManager.getLogger(UseLog4j.class); //程序入口--主函数 public static void main(String[]a

python日志输出

import logging logger = logging.getLogger()  #生成一个日志对象,()内为日志对象的名字,可以不带,名字不给定就是root handler=logging.FileHandler("Log_test.txt")  #生成一个handler(处理器), #formatter 下面代码指定日志的输出格式 fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s' f

日志输出--C#

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; //添加引用,并导入命名空间 using System.Management; using System.Net.NetworkInformation; using System.IO; //日志输出类 public void SWriter(string ipname) { stri