[linux] ebtables技术

news2024/11/25 19:41:58

Linux系统中使用ebtables技术
ebtables就是以太网桥防火墙,以太网桥工作在数据链路层(MAC层),ebtables主要过滤数据链路层数据包,ebtables能过滤桥接流量。ebtables每个阶段的过滤时机都比iptables早。
ebtables的配置分为表、链和规则三级。
表:内置固定的,共三种:filter,nat,broute,用-t选项指定。filter最常用,不设置-t默认就是这个表。filter过滤本机流入流出的数据包,是默认使用的表,nat用于地址转换-mac地址,broute用于以太网桥-产生一个桥路由器。
 

ebtables中的broute表功能:

用于控制进来的数据包是需要进行bridge转发还是进行route转发,即2层转发和3层转发。

BROUTING的ACCEPT/DROP和FORWARD中的区别:

 当在BROUTING中执行DROP时,它会在下图的broute/brouting点中直接将包转入iptables;

brouter:是(基于链路层信息)通过网桥转发一部分数据帧并能够(基于网络层信息)通过路由转发其他数据帧的设备。数据帧是被网桥转发还是被路由转发,取决于决策的配置信息。

例如,可以使用 brouter 充当 2 个网络之间 IP 流量互通的普通路由器,同时通过网桥转发这些网络之间的特定流量(NetBEUI,ARP 等)。IP 路由表不使用网桥逻辑设备,而是将 IP 地址分配给物理网络设备,这些物理网络设备也恰好是网桥端口(网桥绑定该网卡)。

BROUTING 链中的默认策略是网桥转发。
默认是ACCEPT,在BROUTE表中,ACCEPT的含义略有不同,就是桥接的意思,这个可以从ebtables的用法中找到。而DROP的含义是让帧被路由。还有一个决策时redirect,它相当于做了目的Mac地址转换,并将桥口的Mac地址作为目的Mac。这个redict的作用和DROP的作用效果一样,都会让帧走到三层,去做路由抉择,区别在于,DROP并没有进行目的Mac地址转换。
redirect可以用在broute表的BROUTING链和nat的PREROUNTING链,只是它们更换的Mac不一样,nat中使用的桥的的Mac地址(linux中桥设备默认有一个Mac地址,是桥口的某一个设备Mac地址)

当数据帧通过 PREROUTING 链时,在此链中,你可以更改数据帧的目标 MAC 地址(MAC-DNAT)。如果数据帧通过了 PREROUTING 链,则网桥通过查看数据帧的目的 MAC 地址(它不关心网络层信息)来决定将数据帧的发送到哪。

因此,一个被路由转发的 IP 数据包在逻辑上将会经过 ebtables 的 INPUT 链,而不会经过 ebtables 的 FORWARD 链。

在 Linux bridge 上 ebtables 与 iptables 如何进行交互 [译] - 知乎

broute表

用于产生一个桥路器(brouter),包含一个内建chain:
BROUTING 在最早的地方遍历,只能在帧以forwarding状态进入到bridge port的时候才会被遍历。
target DROP和ACCEPT在broute表中有特殊的含义。DROP表示帧已经被route;ACCEPT表示帧已经被bridge

当被绑定到网桥上的网卡接收到数据帧时,数据帧会首先通过 BROUTING 链。在这个特殊的链,你可以选择通过路由转发此数据帧或通过网桥转发此数据帧,这时候网桥将成为一个 brouter。

brouter:是(基于链路层信息)通过网桥转发一部分数据帧并能够(基于网络层信息)通过路由转发其他数据帧的设备。数据帧是被网桥转发还是被路由转发,取决于决策的配置信息。

brouteis used to make a brouter, it has one built-in chain: BROUTING.The targets DROP and ACCEPThave a special meaning in the broute table (these names are used instead ofmore descriptive names to keep the implementation generic). DROPactually means the frame has to be routed, while ACCEPTmeans the frame has to be bridged. The BROUTINGchain is traversed very early. However, it is only traversed by frames entering ona bridge port that is in forwarding state. Normally those frameswould be bridged, but you can decide otherwise here. The redirecttarget is very handy here.

Ebtables使用手册_mac address don't match_Jasonfang0118的博客-CSDN博客

NAT表

nat 经常用于改变MAC地址,包含三个内建的chains:

PREROUTING(为了改变帧当它们已进入)

OUTPUT(为了改变局部产生的或(b)routed 帧 ,在它们被bridge之前)

POSTROUTING(为了改变帧,在它们出去的时候)

filter表

filter 是默认的表,包含三个内建的chains:

INPUT(对于已经决定的帧,在MAC目的地址层)

OUTPUT(对于局部产生的或(b)routed 帧)

FORWARD(对于由bridge传输的帧)

ebtables 之 BROUTING 和 PREROUTING 的 redirect 的区别

ebtable的broute表的BROUTING链的redirect和nat表的PREROUTING的redirect的区别。

很多人不明白 ebtales 的 broute 表的 redirect 和 nat 表 PREROUTING 的 redirect 的区别,其实只要记住两点即可,那就是对于相同点,它们都将数据包导向了本地的 IP 层;对于不同点,broute 表的 redirect 将数据包的接收设备设置成了实际接收数据的物理网卡,而 nat 表将数据包的接收设备设置成了桥设备,这个可以在 Linux 协议栈的源代码中看个究竟。对于 broute 表的 redirect,可以在 br_handle_frame 这个 handle_bridge 调用的回调函数中看到以下的语句:

我们看一下 br_should_route_hook 这个回调函数 ebt_broute:

 它进入了我们都熟悉 xxx_do_table 函数,这也就是常规的 Netfilter 规则查找操作,最终在找到匹配规则时,进入 redirect 这个 target。如果没有 broute 表的规则,则会进入 NF_HOOK 这个 HOOK,其间将会遍 NF_BR_BROUTING 所有的规则,如果有 target 为 redirect 的规则命中,则也会进入 redirect 这个 target,这个 target 是什么呢?是 ebt_redirect_tg 这个函数:

从 br_handle_frame 可以看出,一旦 broute 表的匹配规则返回了 DROP,则 handle_bridge 直接返回这个 skb,不再向下执行,这意味着 skb 将在 handle_bridge 返回后沿着 netif_receive_skb 继续走下去,而如果没有匹配的 broute 表规则,则可能在 nat 表的 PREROUTING 链中命中,然后在执行了 ebt_redirect_tg 之后会调用 br_handle_frame_finish 继续下去,在 br_handle_frame_finish 中,由于目的 MAC 地址已经改成了本机网卡的 MAC 地址,因此会调用 br_pass_frame_up 将数据包向协议栈的上层发送: 

注意,在 broute 表中的 redirect 之后,数据包的接收设备是实际的物理网卡 ethX,目的 MAC 成了物理网卡 ethX 的 MAC 地址,而在 nat 的 PREROUTING 的 redirect 之后,数据包的接收设备是网桥设备,目的 MAC 地址成了网桥设备的 MAC 地址,知道了这个之后,我们再看一下一个和 iptables 的 nat 表的 redirect 的问题。 

设想一个配置,本机 S 的 eth0 的 IP 地址为 1.1.1.254/24,其上开启 tcp 的 88 端口,和本机直连的一台主机 H 的 IP 地址为 1.1.1.2/24,在 S 上配置:

brctl addbr br0
brctl addif eth0
ifconfig br0 1.1.1.254/24
ifcongig eth0 0.0.0.0  #为了防止路由乱掉,因此删除eth0的IP地址
iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j REDIRECT --to-ports 88

在 H 上执行

route add -host 2.2.2.2 gw 1.1.1.254
telnet 2.2.2.2 1234

结果呢?不通!连 syn-ack 都没有收到,然而在 S 上删除 REDIRECT 规则而执行以下规则则是可以的:

iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j DNAT --to-destination 1.1.1.254:88

难道 DNAT 和 REDIRECT 有什么区别吗?如果你不明白这两者有什么区别,那么如果你知道 SNAT 和 MASQUERADE 的区别也不错,起码能帮助你理解。DNAT 和 SNAT 能指定任意的源地址一样,可以指定任意的目的地址,那么 REDIRECT 则和 MASQUERADE 也类似,它只是内核根据自己的策略而选择出的一个目的地址,正如 MASQUERADE 也是内核根据 RFC 的建议以及自己的策略选择出的一个源地址一样。那么如何来选择 REDIRECT 的目的地址呢?看一下 iptables 的 man 手册就知道了:
REDIRECT

This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface (locally-generated packets are mapped to the 127.0.0.1 address).

特别要注意的是 “to the primary address of the incoming interface” 这一句。内核中的 REDIRECT 规则是如何做到这点的呢?这还要看一下代码才知道:

 这下我们就一切都明白了,既然 broute 表的 redirect 将接收设备设置为实际的物理网卡,而此网卡的 IP 地址已经被删除,那么上述函数的 newdst 当然不存在了,因此数据包就被 DROP 掉了,到此为止,问题就很清晰了。可见 ebtables 的 redirect 方式直接影响到了 iptables 的 redirect,为了让 iptables 的 redirect 在使用 bridge 时仍然随时可行,则必须为使能 broute redirect 的网卡上设置 IP 地址,为了不使路由冲突,考虑 127.0.0.2。

注:broute 表的意义
为何会有这样的问题?broute 是原因。所谓的 broute 则是 bridge or router,类似早先安装宽带时运营商送的那种猫,能作为桥设备也能作为路由器。如果作为路由器,根本不存在桥设备这一说,因此将接收设备设置为实际的物理网卡也是理所当然的啦。

linux netfilter--broute流程_osnet的博客-CSDN博客

\net\bridge
br_input.c
br_handle_frame 

如果一个以太网接口eth1,它并没有桥接到br-lan0中,此时,从eth1进来的数据包不会走到ebtables中。它会在下图中的bridge check点,检查数据包进入的接口是否属于某个桥,如果是则走ebtables,否则直接走iptables。

 在/net/bridge/br_if.c中的br_add_if中注册了桥口的处理函数:

 所以tap0口必须加入到桥中。桥口的处理函数就是br_handle_frame。

NFTABLES和iptables

之前一直耳闻 nftables 是下一代 iptables 。前段时间配了一台主机,折腾成家里的软路由。就一并来尝鲜一系列新东西,其中就包括 nftables 。nftables 和 iptables 、ebtables 等一样,都是对底层 xtables 的封装,目前看来 nftables 比 iptables 更简洁易用,更易读,更容易理解,扩展性和也更好。但是目前各个发行版中对 nftables 的支持还比较参差不齐,导致 nftables 很多功能比 iptables 还是有所缺失,所以个人感觉短期内还是替代不了 iptables。 nftables 所支持的功能列表及所以来的内核版本和内核模块可以在这里找到 Supported features compared to xtables - nftables wiki 。

openwrt 桥模式下ebtables转发所有流量到三层,导致DHCP无法获取IP解决方案 | 码农家园

配置如下记录Log规则:

iptables -t nat -I POSTROUTING -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-NAT-POSTROUTING: " --log-level 4
iptables -t nat -I PREROUTING -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-NAT-PREROUTING: " --log-level 4
iptables -I INPUT -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-FILTER" --log-level 4
ebtables -A INPUT --log-level info --log-ip --log-ip6  --log-arp --log-prefix BRIDGE_LOG

 发现报文从br0口出来又走了一次报文发送。此时关键是ebtable中没有配置任何规则。

而在PLC上抓包,发现源MAC不是网关的MAC,而是远程运维PC上的tap0口的MAC地址,而源IP地址又是网关br0口的IP地址。确定是走了Iptable的NAT表的PREROUTING和POSTROUTING链了。

 从可以到不可以,只修改了如下几个内核选项:

+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_LOG_COMMON=y
+CONFIG_NFT_LOG=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_NETMAP=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
+CONFIG_NF_LOG_ARP=y
+CONFIG_NF_LOG_IPV4=y

可能相关的选项为:CONFIG_NF_CONNTRACK=y和CONFIG_NETFILTER_XT_NAT=y,先将这两个选项去掉,看看能不能走到iptable的NAT链表。经测试发现和这两个宏无关。

但是打开CONFIG_BRIDGE_NETFILTER=y宏,可以让二层转发的报文走入iptable的NAT转换表。可以实现我们的目的。查看源码,打开该宏后会编译br_netfilter.c文件,该文件中有br_nf_post_routing()函数,该函数实现的功能是:

#define NF_HOOK(pf, hook, sk, skb, indev, outdev, okfn) (okfn)(sk, skb)

调用钩子函数的代码:

nf_hooks[pf][hook]

struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];

NFPROTO_NUMPROTO变量定义如下:

调用钩子时是根据pf(协议类型)和hooknum来调用的。 

 在net/bridge/br_device.c文件中的br_dev_xmit函数中,如果根据转发表找到了出端口,则调用br_deliver()函数。

在br_nf_post_routing()函数中,将pf类型由NFPROTO_BRIDGE修改为NFPROTO_IPV4或NFPROTO_IPV6,然后再走一遍

 这样就可以进入到IPV4转IP地址流程,但是源和目的MAC地址又不变。

netfilter日志打印

sysctl net.netfilter.nf_log.2=nf_log_ipv4
sysctl net.netfilter.nf_log.3=nf_log_arp
sysctl net.netfilter.nf_log.7=nf_log_bridge  
sysctl net.netfilter.nf_log.10=nf_log_ipv6


iptables -t nat -I POSTROUTING -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-NAT-POSTROUTING: " --log-level 4
iptables -t nat -I PREROUTING -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-NAT-PREROUTING: " --log-level 4
iptables -I INPUT -s 10.99.0.0/24 -d 192.168.0.100 -j LOG --log-prefix "Iptables-FILTER" --log-level 4
ebtables -A INPUT --log-level info --log-ip --log-ip6  --log-arp --log-prefix BRIDGE_LOG


iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos7.9修改ssh默认的端口号

多开几个ssh,防止配置文件错误,将自己关在服务器外面了 netstat -ntlp|grep ssh # ssh对应的端口号 修改sshd_config配置文件 /etc/ssh/sshd_config,重启sshd服务 #Port 22 Port 10011 # 端口号自己定义,不能超过65535&#xf…

基于Java+Swing+Mysql影院购票系统

基于JavaSwingMysql影院购票系统 一、系统介绍二、功能展示1.用户登陆2.用户订票管理3.电影售票中心4.电影上映管理4.退票记录查询 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看管理员登陆、用户订票管理、电影上映管理、电影售票中心、退票记录查询…

重定义/自定义printf到串口输出实现的三种方法(cubeide)

重定义/自定义printf到串口输出实现的三种方法(cubeide) 文章目录 重定义/自定义printf到串口输出实现的三种方法(cubeide)1.重写_write函数2.重定义PUTCHAR_PROTOTYPE宏3.va_list自定义printf总结: 1.重写_write函数 注释掉syscalls.c文件中…

Java中Map使用增强for循环和迭代器获取key和value

加油,新时代打工人! java中List集合三种获取集合元素方式 本文运行代码使用 jdk1.8 for 语句比较简单,用于循环数据。 Java迭代器(Iterator)是 Java 集合框架中的一种机制,是一种用于遍历集合&#xff08…

非线程安全问题

目录 实例变量共享导致的“非线程安全问题” 如何解决这个问题? i--与System.out.println()出现引起的“非线程安全问题” 非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流…

科目一速通技巧笔记,简记

常规 累计积分制度(12满)周期12月 虚假材料1年,假1吊二撤三醉五逃终身 假1500 骗三2k以下 初次领证1年实习期、实习标志,18~70岁 拼装车、报废车,吊销 200~2k 没有中心线(一条路)城市道路3…

路径规划算法:基于白鲸优化的路径规划算法- 附代码

路径规划算法:基于白鲸优化的路径规划算法- 附代码 文章目录 路径规划算法:基于白鲸优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法白鲸…

Python、STK、MATLAB的连接和使用

写在前面 预备知识: Python通过命令行调用MATLAB的简单实现。这篇文章讲明了如何使用 Python 调用 MATLAB 的原理和过程,并给出相应代码。 STK、MATLAB、SQL的连接和使用。这篇文章讲明了STK 11.2、MATLAB 2014a、SQL 2019的安装过程,以及…

超越99%的程序员,chatgpt用C++写个线程安全无锁环形队列

​肝了一个周末,我们一起来欣赏chatgpt写的代码吧。让其用C为我们写一个线程安全的环形队列,并逐步提出一些需求。 先看带锁的实现。 带锁版本 我对chatgpt的需求是: 用C实现线程安全的环形队列,提供代码注释,以及g…

Meetup 报名|07.22 StarRocks Friends 与你相约广州

夏日炎炎,经历了杭州和上海两站的成功活动后,社区开发者的热情依旧如火如荼!在更加炽热的七月,我们即将迎来 StarRocks & Friends 的第三站--广州! 社区依旧秉持连接 StarRocks 社区专家与用户共同探讨大数据领域…

MySQL数据库 - 基本数据类型

目录 一、数据类型分类 二、数据类型 1、tinyint 类型 有符号 tinyint 范围测试 无符号 tinyint 范围测试 2、bit 类型 3、float 类型 有符号 float 范围测试 无符号 float 范围测试 4、decimal 类型 5、char 类型 6、varchar 类型 7、日期类型 8、enum类型、set类型…

Codeforces Round 739 (Div. 3)

A.Dislike of Threes AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N2e510; int f[N]; int cnt; int main() {for(int i1;;i){if(i%3!0&&i%10!3) f[cnt]i;if(cnt>1000) break…

第一阶段-第六章 Python的数据容器

目录 一、数据容器入门  1.学习目标  2.为什么要学习数据容器  3.什么是数据容器  4.本小节的总结 二、数据容器&#xff1a;list&#xff08;列表&#xff09;  2.1列表的定义  1.学习目标  2.为什么需要列表  3.列表的定义  4.本节的代码演示  5.本小节的…

【Java练习题汇总】《第一行代码JAVA》面向对象基础篇,汇总Java练习题——面向对象:特性、类与对象、数组、String、内部类... ~

Java练习题 面向对象基础篇 1️⃣ 面向对象基础篇 1️⃣ 面向对象基础篇 一、填空题 面向对象的三大特征&#xff1a;_______ 、_______ 、_______。类由_______和_______组成。运算符_______的作用是根据对象的类型分配内存空间。当对象拥有内存空间时&#xff0c;会自动调…

oceanbase基础

与mysql对比 分布式一致性算法 paxos 存储结构&#xff08;引擎&#xff09;用的是两级的 数据库自动分片功能&#xff0c;提供独立的obproxy路由写入查询等操作到对应的分片 多租户 方便扩展 存储层 http://www.hzhcontrols.com/new-1391864.html LSM tree&#xff0c;is very…

CnOCR 使用教程

目录 一、 简介二、使用教程三、效果展示 一、 简介 CnOCR 是 Python 3 下的文字识别&#xff08;Optical Character Recognition&#xff0c;简称OCR&#xff09;工具包&#xff0c;支持简体中文、繁体中文&#xff08;部分模型&#xff09;、英文和数字的常见字符识别&#…

[COCI2010-2011#6]STEP

目录 1.题目&#xff1a; 题目描述 输入格式 输出格式 2.思路 1.ans数组的维护 2.L and R 的维护 3.ne数组与pr数组的维护 4.len数组&#xff1a; 3.代码&#xff1a; 1.有注释版&#xff1a; 2.copy版&#xff1a; 1.题目&#xff1a; 题目描述 给定一个长度为N的…

Java设计模式-责任链(Chain of Responsibility)模式

介绍 Java责任链&#xff08;Chain of Responsibility&#xff09;设计模式是指很多处理对象构成一个链&#xff0c;链中前一个对象指向后一个对象。请求在链中传递&#xff0c;一个请求可以被一个或者多个对象处理。调用方&#xff08;即客户端&#xff09;不知道请求会被链中…

【UniApp开发小程序】项目创建+整合UI组件(FirstUI和uView)

创建项目 下图为初始化的项目的文件结构 引入组件 俗话说&#xff1a;“工欲善其事&#xff0c;必先利其器”&#xff0c;为了更加方便地开发出页面较为美观的小程序&#xff0c;我们先引入成熟的UI组件&#xff0c;再开始开发之旅。&#xff08;如果你是前端高手&#xff0…

ardupilot IMU陀螺仪方向的重要性

目录 文章目录 目录摘要1.简介---BMI088 方向2.控制摘要 本节主要记录IMU陀螺仪方向的重要性,欢迎批评指正!!! 1.简介—BMI088 方向 注意这个BMI088 的IMU方向,特别是是那个左上角的黑色点点,他的坐标系满足右手坐标系,但是我们无人机坐标系是北东地坐标系,因此需要把…