首页 > 其他分享 >Netfilter日志记录

Netfilter日志记录

时间:2023-10-27 15:34:59浏览次数:34  
标签:logger log 记录 nf loginfo 日志 net Netfilter struct

iptables -t raw -I PREROUTING -p tcp --dport 80 -j LOG

# iptables -t raw -I PREROUTING -p tcp --dport 80 -j LOG --log-level 3 --log-prefix "ipt-err:"  可以指定log级别

日志级别可通过syslog定义进行查看。另外LOG目标还可指定参数:–log-tcp-sequence,–log-tcp-options,–log-ip-options,–log-uid和–log-macdecode。

# man syslog
#define KERN_EMERG    "<0>"  /* system is unusable               */
#define KERN_ALERT    "<1>"  /* action must be taken immediately */
#define KERN_CRIT     "<2>"  /* critical conditions              */
#define KERN_ERR      "<3>"  /* error conditions                 */
#define KERN_WARNING  "<4>"  /* warning conditions               */
#define KERN_NOTICE   "<5>"  /* normal but significant condition */
#define KERN_INFO     "<6>"  /* informational                    */
#define KERN_DEBUG    "<7>"  /* debug-level messages             */

 

如果将IPv4协议(NFPROTO_IPV4=2)的logger设置为nf_log_ipv4。

modprobe ipt_LOG
modprobe nf_log_ipv4

sysctl net.netfilter.nf_log.2=nf_log_ipv4
#
# sysctl -a | grep nf_log
net.netfilter.nf_log.0 = NONE
net.netfilter.nf_log.1 = NONE
net.netfilter.nf_log.2 = nf_log_ipv4

内核由函数log_tg_init注册LOG目标,即结构log_tg_regs。

static struct xt_target log_tg_regs[] __read_mostly = {
	{
		.name		= "LOG",
		.family		= NFPROTO_IPV4,
		.target		= log_tg,
		.targetsize	= sizeof(struct xt_log_info),
		.checkentry	= log_tg_check,
		.destroy	= log_tg_destroy,
		.me		= THIS_MODULE,
	},
};

函数log_tg_check进行必要的参数合法性判断,之后查找系统中注册的logger,以上示例为nf_log_ipv4

static int log_tg_check(const struct xt_tgchk_param *par)
{
	const struct xt_log_info *loginfo = par->targinfo;
	int ret;

	if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
		return -EINVAL;

	if (loginfo->level >= 8) {
		pr_debug("level %u >= 8\n", loginfo->level);
		return -EINVAL;
	}

	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
		pr_debug("prefix is not null-terminated\n");
		return -EINVAL;
	}

	ret = nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
	if (ret != 0 && !par->nft_compat) {
		request_module("%s", "nf_log_syslog");

		ret = nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
	}

	return ret;
}

以下将匹配LOG规则的报文通过函数nf_log_packet进行日志输出,在使用日志nf_log_ipv4时,其日志输出函数为nf_log_ip_packet。函数返回值为XT_CONTINUE,继续下一跳规则匹配。

static unsigned int
log_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
	const struct xt_log_info *loginfo = par->targinfo;
	struct net *net = xt_net(par);
	struct nf_loginfo li;

	li.type = NF_LOG_TYPE_LOG;
	li.u.log.level = loginfo->level;
	li.u.log.logflags = loginfo->logflags;

	nf_log_packet(net, xt_family(par), xt_hooknum(par), skb, xt_in(par),
		      xt_out(par), &li, "%s", loginfo->prefix);
	return XT_CONTINUE;
}

 

系统内的logger按照协议和类型保存在全局二维数组loggers中。

int sysctl_nf_log_all_netns __read_mostly;
EXPORT_SYMBOL(sysctl_nf_log_all_netns);
    
static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;

参数nf_log_all_netns默认为零,仅记录init_net命名空间中的报文日志,参考函数nf_log_ip_packet

 

日志记录器注册

如果协议类型等于NFPROTO_UNSPEC,将日志logger赋值给所有的协议类型。否则,将logger赋值给对应的协议。

/* return EEXIST if the same logger is registered, 0 on success. */
int nf_log_register(u_int8_t pf, struct nf_logger *logger)
{
	int i;
	int ret = 0;

	if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers))
		return -EINVAL;

	mutex_lock(&nf_log_mutex);

	if (pf == NFPROTO_UNSPEC) {
		for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
			if (rcu_access_pointer(loggers[i][logger->type])) {
				ret = -EEXIST;
				goto unlock;
			}
		}
		for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
			rcu_assign_pointer(loggers[i][logger->type], logger);
	} else {
		if (rcu_access_pointer(loggers[pf][logger->type])) {
			ret = -EEXIST;
			goto unlock;
		}
		rcu_assign_pointer(loggers[pf][logger->type], logger);
	}

unlock:
	mutex_unlock(&nf_log_mutex);
	return ret;
}

ret = nf_log_register(NFPROTO_IPV4, &nf_ip_logger);

函数nf_log_set设置每个命名空间的日志记录logger。协议类型不能等于NFPROTO_UNSPEC。

int nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger)
{
	const struct nf_logger *log;

	if (pf == NFPROTO_UNSPEC || pf >= ARRAY_SIZE(net->nf.nf_loggers))
		return -EOPNOTSUPP;

	mutex_lock(&nf_log_mutex);
	log = nft_log_dereference(net->nf.nf_loggers[pf]);
	if (log == NULL)
		rcu_assign_pointer(net->nf.nf_loggers[pf], logger);

	mutex_unlock(&nf_log_mutex);

	return 0;
}


int ret = nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);

 

日志打印

如果参数loginfo不等于空,使用全局loggers中注册的日志记录器,否则,使用命名空间中设置日志记录器

void nf_log_packet(struct net *net,
		   u_int8_t pf,
		   unsigned int hooknum,
		   const struct sk_buff *skb,
		   const struct net_device *in,
		   const struct net_device *out,
		   const struct nf_loginfo *loginfo,
		   const char *fmt, ...)
{
	va_list args;
	char prefix[NF_LOG_PREFIXLEN];
	const struct nf_logger *logger;

	rcu_read_lock();
	if (loginfo != NULL)
		logger = rcu_dereference(loggers[pf][loginfo->type]);
	else
		logger = rcu_dereference(net->nf.nf_loggers[pf]);

	if (logger) {
		va_start(args, fmt);
		vsnprintf(prefix, sizeof(prefix), fmt, args);
		va_end(args);
		logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix);
	}
	rcu_read_unlock();
}

IPv4日志记录器

协议类型NFPROTO_IPV4注册了全局和命名空间日志记录器nf_log_ipv4,其输出函数为nf_log_ip_packet。

 

static struct nf_logger nf_ip_logger __read_mostly = {
    .name       = "nf_log_ipv4",
    .type       = NF_LOG_TYPE_LOG,
    .logfn      = nf_log_ip_packet,
    .me     = THIS_MODULE,
};
static int __net_init nf_log_ipv4_net_init(struct net *net)
{   
    return nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
}
static struct pernet_operations nf_log_ipv4_net_ops = {
    .init = nf_log_ipv4_net_init,
    .exit = nf_log_ipv4_net_exit,
};
static int __init nf_log_ipv4_init(void)
{
    ret = nf_log_register(NFPROTO_IPV4, &nf_ip_logger);

 只有在sysctl_nf_log_all_netns为真的情况下,才会生成其它命名空间的报文日志。函数nf_log_buf_close输出日志缓存中的内容。 

 

/* Guard against containers flooding syslog. */
static bool nf_log_allowed(const struct net *net)
{
	return net_eq(net, &init_net) || sysctl_nf_log_all_netns;
}
static void nf_log_ip_packet(struct net *net, u_int8_t pf,
			     unsigned int hooknum, const struct sk_buff *skb,
			     const struct net_device *in,
			     const struct net_device *out,
			     const struct nf_loginfo *loginfo,
			     const char *prefix)
{
	struct nf_log_buf *m;

	if (!nf_log_allowed(net))
		return;

	m = nf_log_buf_open();

	if (!loginfo)
		loginfo = &default_loginfo;

	nf_log_dump_packet_common(m, pf, hooknum, skb, in,
				  out, loginfo, prefix);

	if (in)
		dump_mac_header(m, loginfo, skb);

	dump_ipv4_packet(net, m, loginfo, skb, skb_network_offset(skb));

	nf_log_buf_close(m);
}

 

http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子



标签:logger,log,记录,nf,loginfo,日志,net,Netfilter,struct
From: https://blog.51cto.com/u_15404950/8058235

相关文章

  • ebtable 的日志log
    ebtables中有三张表filter,nat,broute,六条链INPUT,FORWARD,OUTPUT,PREROUTING,POSTROUTING和BROUTINGebtables-AINPUT--log-levelinfo--log-ip--log-ip6--log-arp--log-prefix'ebtable/input'#!/bin/bashinsert(){ebtables-tbroute-IBROUTING-pipv4......
  • [node]package入门---简单记录,日后补充
    参考:package入门:https://cloud.tencent.com/developer/article/1195063npm i 添加包:https://www.cnblogs.com/it-wwp/p/16719235.htmlnpm i 删除包:https://blog.csdn.net/m0_46149348/article/details/1308622181. 安装node.js自行百度,不作说明。 如果本地安装速度太慢,切......
  • 岩土工程监测利器:多通道振弦数据记录仪应用桥洞监测
    岩土工程监测利器:多通道振弦数据记录仪应用桥洞监测岩土工程是建筑工程中重要的一个分支领域,它主要涉及土石、岩石等地质物质的力学性质和变形特性,对于建筑工程的稳定性和安全性至关重要。在岩土工程中,监测是非常重要的一部分,能够帮助业主和工程师及时掌握工程现场的实际情况,以及......
  • mysql-日志管理
    一、mysql日志文件的作用1、能记录物理数据页面的修改的信息;2、能将数据从逻辑上恢复至事务之前的状态;3、能以二进制文件的形式记录了数据库中的操作;4、能记录错误的相关信息;5、能从主服务器中二进制文件取的事件等等。普通日志记录了服务器接收到的每一个查询或是命......
  • mysql-基于GTID的binlog日志
    一、什么是GTID从MySQL5.6.5开始新增了一种基于GTID的复制方式。通过GTID保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量pos值进行增量......
  • 学习过的网站记录
      https://www.jianshu.com/p/ba9d45b4e592?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes  IOS-地图之CLLocation的使用   https://blog.csdn.net/songzhuo1991/article/details/115626992 iOS-UIStackView布局详解   http://devce......
  • 常用hook记录
    1headershook当header中包含Authorization时,则插入断点varcode=function(){varorg=window.XMLHttpRequest.prototype.setRequestHeader;window.XMLHttpRequest.prototype.setRequestHeader=function(key,value){if(key=='Authorization'){debugg......
  • 小端模式和大端模式——踩坑记录
    大端小端1前言在做项目时,需要将报文发送给硬件端,报文打包我都是用的大端写入Bytebuf(使用的netty),老大审查代码时,说我写错了,说硬件那边要求是小端传输。不过改成小端写入也容易,重要的是牢记这个知识点。于是趁这个机会复习一下大端和小端。2概念大端(Big-Endian)和小端(Litt......
  • 记录mybatis的一点小坑(Invalid bound statement (not found))
    今天学习SSM的时候出的一个小错,写测试程序的时候mybatis一直报bindingexception Invalidboundstatement(notfound): xxx语句。我以为是xxx语句出问题了。一直找。检查了namespace、statementid、mapperScanner啥的,都没发现异常。回去翻笔记,原来是xml的路径错了。 ......
  • 业务日志打印规范
    业务日志打印规范参考文档Java开发手册https://github.com/alibaba/p3c内容【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架(SLF4J、JCL--JakartaCommonsLogging)中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一......