我正在尝试为我的网络脚本设置单元测试。由于单元测试由非root用户(通常是“jenkins”)运行,我希望能够设置一个网络接口,jenkins可以使用它来测试从我的网络发送的数据包脚本。我正在测试的程序以“混杂”模式使用网络接口,最终在root用户下作为Linux服务运行。但是,我希望在不需要root登录或交互式输入的情况下测试功能单元 - jenkins“user”不是系统上的交互式用户。
我可以通过以下方式设置一个分接界面(CentOS 7.x):
sudo ip tuntap add tap0 mode tap user jenkins
sudo ifconfig tap0 promisc up
这会打开一个界面,我可以使用ifconfig
看到它,但它不是“RUNNING”。
我可以通过使用sudo XXXX
运行我的程序来发送数据,所以我的程序正在按预期工作。但是,如果我通过jenkins帐户运行程序,数据包不会通过 - 我可以暂时将jenkins用户帐户切换为“交互式”以尝试此操作。我正在使用Wireshark查看此接口上的吞吐量。
我使用自己的用户帐户和其他帐户尝试了这一点,但只有root帐户有效。
我觉得我可以使用一些命令行调用来允许非root用户使用(私有的,用户拥有的)网络接口,但我什么都找不到。
我可以使用sudo
和/或suid(chmod 4755 XXX
)权限来制定一个允许单元测试以root权限运行的系统,但似乎我应该能够运行自动化测试,而不必经历这个有点曲折的过程。
有人知道如何利用用户帐户的点击界面吗?
注意:最终,我的程序使用libpcap
的pcap_inject
将数据包注入接口。如果有人知道不同的程序化解决方案,那就是解决这个问题的另一种方法。
此外,我可以将作为非root用户的数据包注入到我的真实网络接口上并且可以正常工作,但是让我的数据包(可能是错误的)松散到真实网络上有点危险。用户可以利用真实界面但不利用“轻敲”界面进行测试似乎是不协调的。
似乎libpcap库不允许以这种方式访问tap接口设置。
为了解决这个问题,我需要在系统中编写C / C ++代码,使用以下代码直接写入网络接口的文件描述符:
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>
...
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, "tap0", IFNAMSIZ);
int fd = open("/dev/net/tun", O_RDWR);
int err = ioctl(fd, TUNSETIFF, (void*) &ifr);
...
int rc = write(fd, packetData, length);
最终,这是通过程序化解决方案解决的。我真的不认为有一个sys-admin解决方案来继续使用libpcap库。
注意:在继续使用libpcap之前,我首先尝试以这种方式打开tap设备(这对其他情况很有用)。这是因为libpcap在尝试相同时可以无声地失败并且不返回任何错误,但是根本不起作用。