Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netmanager:改名、更改架构、增加macfilter和路由优化及文档 #878

Merged
merged 16 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ebpf_net_manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ jobs:
cd testenv
sudo ./testenv.sh setup --name veth-basic02
cd ..
cd net_manager
sudo timeout -s SIGINT 5 ./xdp_loader -d eth0 -S || if [[ $? != 124 && $? != 0 ]];then exit $?;fi
sudo ./xdp_loader -d eth0 -S
sudo timeout -s SIGINT 5 ./netmanager -d eth0 -S || if [[ $? != 124 && $? != 0 ]];then exit $?;fi
sudo ./netmanager -d eth0 -S



Expand Down
139 changes: 127 additions & 12 deletions eBPF_Supermarket/Network_Subsystem/net_manager/Makefile
Original file line number Diff line number Diff line change
@@ -1,36 +1,152 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)

# Compiler and Tools
LLC ?= llc
CLANG ?= clang
CC ?= gcc

# Targets
XDP_TARGETS := netmanager_kern
USER_TARGETS := netmanager

XDP_C = ${XDP_TARGETS:=.c}
XDP_OBJ = ${XDP_C:.c=.o}
USER_C := ${USER_TARGETS:=.c}
USER_OBJ := ${USER_C:.c=.o}

# Directories
COMMON_DIR = ./common
LIB_DIR ?= ./lib
LOADER_DIR ?= $(LIB_DIR)/xdp-tools/xdp-loader
STATS_DIR ?= $(COMMON_DIR)/../basic-solutions

# Common Objects and Dependencies
COMMON_OBJS += $(COMMON_DIR)/common_user_bpf_xdp.o $(COMMON_DIR)/common_params.o
EXTRA_DEPS := $(COMMON_DIR)/parsing_helpers.h
COMMON_H := ${COMMON_OBJS:.o=.h}

include $(LIB_DIR)/defines.mk
KERN_USER_H ?= $(wildcard common_kern_user.h)
COMMON_MK = $(COMMON_DIR)/common.mk

# Extra Linker/Compiler Flags
CFLAGS += -I$(LIB_DIR)/install/include $(EXTRA_CFLAGS) -g
BPF_CFLAGS += -I$(LIB_DIR)/install/include $(EXTRA_CFLAGS) -g
LDFLAGS += -L$(LIB_DIR)/install/lib

# Verbosity Control
ifeq ("$(origin V)", "command line")
VERBOSE = $(V)
VERBOSE = $(V)
endif
ifndef VERBOSE
VERBOSE = 0
VERBOSE = 0
endif

ifeq ($(VERBOSE),0)
MAKEFLAGS += --no-print-directory -s
Q = @
MAKEFLAGS += --no-print-directory -s
Q = @
endif

PROJ := xacl_ip router xacl_mac xstate net_manager



# Projects and Cleaning
PROJ := xacl_ip router xacl_mac xstate
PROJ_CLEAN = $(addsuffix _clean,$(PROJ))

.PHONY: clean clobber distclean $(PROJ) $(PROJ_CLEAN)
.PHONY: clean clobber distclean $(PROJ) $(PROJ_CLEAN) $(CLANG) $(LLC)

# Default Target
all: lib $(PROJ) net_manager

all: lib $(PROJ)
# Clean Target
clean: $(PROJ_CLEAN)
@echo; echo common; $(MAKE) -C common clean
@echo; echo lib; $(MAKE) -C lib clean

$(Q)rm -f $(USER_TARGETS) $(XDP_OBJ) $(USER_OBJ) $(COPY_LOADER) $(COPY_STATS) *.ll $(XLB_OBJS)

# Build Library
lib: config.mk check_submodule
@echo; echo $@; $(MAKE) -C $@

# Project Build Targets
$(PROJ):
@echo; echo $@; $(MAKE) -C $@

# Main Target
net_manager: llvm-check $(USER_TARGETS) $(XDP_OBJ) $(COPY_LOADER) $(COPY_STATS)

# Copy Loader
ifdef COPY_LOADER
$(LOADER_DIR)/$(COPY_LOADER):
$(Q)make -C $(LOADER_DIR)

$(COPY_LOADER): $(LOADER_DIR)/$(COPY_LOADER)
$(QUIET_COPY)cp $(LOADER_DIR)/$(COPY_LOADER) $(COPY_LOADER)
endif

# Copy Stats
ifdef COPY_STATS
$(STATS_DIR)/$(COPY_STATS): $(STATS_DIR)/${COPY_STATS:=.c} $(COMMON_H)
$(Q)make -C $(STATS_DIR) $(COPY_STATS)

$(COPY_STATS): $(STATS_DIR)/$(COPY_STATS)
$(QUIET_COPY)cp $(STATS_DIR)/$(COPY_STATS) $(COPY_STATS)
EXTRA_DEPS += $(COMMON_DIR)/xdp_stats_kern.h $(COMMON_DIR)/xdp_stats_kern_user.h
endif

# LLVM Tool Check
llvm-check: $(CLANG) $(LLC)
@for TOOL in $^ ; do \
if [ ! $$(command -v $${TOOL} 2>/dev/null) ]; then \
echo "*** ERROR: Cannot find tool $${TOOL}" ;\
exit 1; \
else true; fi; \
done

$(OBJECT_LIBBPF):
@if [ ! -d $(LIBBPF_DIR) ]; then \
echo "Error: Need libbpf submodule" $(LIBBPF_DIR); \
echo "May need to run git submodule update --init"; \
exit 1; \
else \
cd $(LIBBPF_DIR) && $(MAKE) all OBJDIR=.; \
mkdir -p build; $(MAKE) install_headers DESTDIR=build OBJDIR=.; \
fi

$(OBJECT_LIBXDP):
@if [ ! -d $(LIBXDP_DIR) ]; then \
echo "Error: Need libxdp submodule" $(LIBXDP_DIR); \
echo "May need to run git submodule update --init"; \
exit 1; \
else \
cd $(LIBXDP_DIR) && $(MAKE) all OBJDIR=.; \
fi

# Create dependency: detect if C-file change and touch H-file, to trigger
# target $(COMMON_OBJS)
$(COMMON_H): %.h: %.c
touch $@

# Detect if any of common obj changed and create dependency on .h-files
$(COMMON_OBJS): %.o: %.h
$(Q)$(MAKE) -C $(COMMON_DIR)

$(USER_TARGETS): %: %.c $(OBJECT_LIBBPF) $(OBJECT_LIBXDP) Makefile $(COMMON_MK) $(COMMON_OBJS) $(KERN_USER_H) $(EXTRA_DEPS) $(XLB_OBJS)
$(QUIET_CC)$(CC) -Wall $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(XLB_OBJS) $(LIB_OBJS) \
$< $(LDLIBS)

$(XDP_OBJ): %.o: %.c Makefile $(COMMON_MK) $(KERN_USER_H) $(EXTRA_DEPS) $(OBJECT_LIBBPF)
$(QUIET_CLANG)$(CLANG) -S \
-target bpf \
-D __BPF_TRACING__ \
$(BPF_CFLAGS) \
-Wall \
-Wno-unused-value \
-Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Werror \
-O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
$(QUIET_LLC)$(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll}


$(PROJ_CLEAN):
@echo; echo $@; $(MAKE) -C $(subst _clean,,$@) clean

Expand All @@ -51,4 +167,3 @@ check_submodule:
echo " consider running: git submodule update" ;\
echo "" ;\
fi\

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void parse_cmdline_args(int argc, char **argv,
goto error;
}
// 设置文件路径
cfg->mac_filter_file = (char *)&cfg->mac_filter_file_buf; //初始化ip_filter_file
cfg->mac_filter_file = (char *)&cfg->mac_filter_file_buf; //初始化mac_filter_file
strncpy(cfg->mac_filter_file, optarg, FILE_MAXSIZE);
break;
case 'k':
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

二进制文件不要提交仓库

Binary file not shown.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

二进制文件不要提交仓库

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,18 @@ struct rules_ipv4 {
__u16 next_rule;
};

struct conn_mac {
unsigned char dest[ETH_ALEN];
unsigned char source[ETH_ALEN];
};

struct rules_mac {
unsigned char dest[ETH_ALEN];
unsigned char source[ETH_ALEN];
__u16 action;
__u16 prev_rule;
__u16 next_rule;
};
// 转发表项
struct rt_item {
__u32 saddr;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
00:0c:29:57:00:4d 00:00:00:00:00:00 ALLOW
00:0c:29:00:00:00 00:00:00:00:00:00 DENY
00:00:00:00:00:00 00:00:00:00:00:00 ALLOW
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### 实现

![image-20240726104526418](./pic/ip_filter1.png)
![image-20240726104526418](./image/ip_filter1.png)

#### 输入参数优化

Expand All @@ -25,7 +25,7 @@
因此其使用的方法十分固定,要求路径必须在相应的位置,如:

```
sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t
sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t
```

将其绑定到-i参数上
Expand All @@ -40,7 +40,7 @@ strncpy(cfg->ip_filter_file, optarg, FILE_MAXSIZE);
去掉这种限制

```
sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t
sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t
```

#### 增添输出格式
Expand All @@ -52,7 +52,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con
本功能的使用命令为

```
sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf
sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf
```

也可以在其中加入-t/T选项,t参数会定时统计所有策略对应的报文数,T参数会输出所有匹配条目与策略
Expand All @@ -63,7 +63,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con
sudo xdp-loader status
```

![image-20240726114124092](./pic/ip_filter2.png)
![image-20240726114124092](./image/ip_filter2.png)

其中可以看到对应网卡上挂载的XDP程序

Expand Down Expand Up @@ -131,7 +131,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con

可以发现已经drop了所有报文

![image-20240726110021447](./pic/ip_filter3.png)
![image-20240726110021447](./image/ip_filter3.png)


### 输出分析
Expand All @@ -144,6 +144,6 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con
sudo cat /sys/kernel/debug/tracing/trace_pipe
```

![image-20240726153912838](./pic/ip_filter4.png)
![image-20240726153912838](./image/ip_filter4.png)

其中可以看到符合匹配的相关报文信息,其中包括四元组、协议类型、XDP策略行为以及匹配条目的序号。
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
## MAC过滤

### 概述

​ 本工具通过XDP技术,在内核层实现了高效的MAC地址过滤,专注于基于设备物理地址的流量控制。MAC地址过滤能够在网络层面上直接识别和控制特定设备的访问权限,无需依赖上层协议的验证机制。通过配置特定设备的MAC地址黑白名单,能够有效防止未经授权的设备接入网络,确保网络安全性。

其主要应用在于

1. **硬件级别过滤**: MAC地址是网络接口卡的唯一标识,不会像IP地址那样频繁变化,因此在底层网络设备上做过滤更有效。
2. **物理位置绑定**: 在局域网中,MAC地址通常和设备物理位置绑定,有助于对物理设备进行精确控制。
3. **隔离内外网**:通过限制外部设备基于MAC地址接入本地网络,可以强化内外网隔离的策略,从而间接提高内部网络的安全性。

MAC地址仅在局域网中有效,跨路由器的网络(如广域网)无法通过MAC地址进行过滤

### 实现

总体框架流程如下:

![image-20240825133247633](./image/mac_filter1.png)

具体匹配策略如下:

```c
int mac_match(__u8 *conn_mac, __u8 *rule_mac) {
__u8 zero_mac[ETH_ALEN] = {0}; // 全零的MAC地址

// 如果rule_mac全为零,匹配所有MAC地址
if (bpf_memcmp(rule_mac, zero_mac, ETH_ALEN) == 0) {
return 1;
}

// 如果rule_mac的后三个字节为零,且前三个字节与conn_mac相同
if (bpf_memcmp(&rule_mac[3], zero_mac, 3) == 0) {
if (bpf_memcmp(conn_mac, rule_mac, 3) == 0) {
return 1; // 匹配前三字节
}
}

// 检查规则MAC与连接MAC是否完全匹配
if (bpf_memcmp(rule_mac, conn_mac, ETH_ALEN) == 0) {
return 1; // 完全匹配
}

return 0; // 不匹配
}
```

### 使用方法

本功能的使用命令为

```c
sudo ./netmanager -d ens33 -S --progname=xdp_entry_mac -m conf.d/mac_load.conf -t
```

之后可以使用xdp-loader查看挂载程序及卸载

在 ./conf.d 目录里有样例规则文件 mac_load.conf 代表条目名单。程序会按顺序逐行加载进BPF Map,同样,XDP程序执行时也会逐行匹配规则,所以写在前面的规则具有更高的优先级。每行规则的格式为:

```
[SOURCE_MAC] [DEST_MAC] [ALLOW/DENY]
```

其中分别为源MAC地址、目的MAC地址及条目策略。

需要注意,**XDP只对收包路径上的数据有效,因此此处的源为另一端,而目的为本机**。

**当某段字段为0时,代表不进行此处的过滤,为全部匹配**。

若要实现黑名单,根据匹配的优先级顺序,则需要在规则的最后⼀条写上(也可不加),默认为ALLOW,当匹配不到其余规则时会默认进行PASS策略(但仍建议增添)

```c
00:00:00:00:00:00 00:00:00:00:00:00 ALLOW
```

若要实现白名单,需要将最后⼀条规则写为(必须增添,否则没有实际效果)

```c
00:00:00:00:00:00 00:00:00:00:00:00 DENY
```

我们还对某一厂商的MAC地址进行泛化匹配,当前三字节不为0(固定厂商)且后三字节为0时,可以对其进行泛化,匹配到所有改厂商的MAC地址,如

```
00:0c:29:00:00:00 00:00:00:00:00:00 ALLOW
```

最终给出实例,我们在规则配置文件中写入

```c
00:0c:29:57:00:4d 00:00:00:00:00:00 ALLOW
00:0c:29:00:00:00 00:00:00:00:00:00 DENY
00:00:00:00:00:00 00:00:00:00:00:00 ALLOW
```

其中,00:0c:29开头的MAC地址是VMware虚拟网卡固定分配的前缀

之后加载到程序中

```shell
sudo ./netmanager -d ens33 -S --progname=xdp_entry_mac -m conf.d/mac_load.conf -t
```

之后通过不同虚拟机使用ping/curl来连接该主机

当MAC地址为00:0c:29:57:00:4d(特定主机),其可以正常连接

![image-20240825132436960](./image/mac_filter2.png)

而其余虚拟机进行访问时会被拒绝

![image-20240825132526078](./image/mac_filter3.png)

可以看到,相应报文已经被DROP

![image-20240825132551308](./image/mac_filter4.png)
Loading
Loading