#nftables #linux #netfilter #random

nftnl-rs

一个用于Linux Netlink Nftables客户端的Rust包,可以直接通过netlink套接字控制netfilter。

5个版本 (3个重大变更)

0.4.0 2024年3月31日
0.3.2 2024年3月28日
0.2.0 2024年3月20日
0.1.0 2024年3月18日

#3 in #nftables

Download history 456/week @ 2024-03-18 256/week @ 2024-03-25 103/week @ 2024-04-01 3/week @ 2024-04-08 2/week @ 2024-05-20

每月下载 318

MPL-2.0 许可证

165KB
4K SLoC

nftnl-rs (Nftables操作库)

这是一个正在开发中的包,它实现了与Linux Nftables防火墙通信的netlink协议。

此包处于早期开发阶段。没有计划扩展其功能!使用风险自担。

此包仅用于表/集操作,即添加/删除/获取!!!

目前此包允许对集进行以下操作

  • 对集进行操作,例如添加IP、删除IP、从列表中获取IP。

有关示例,请参阅/示例/目录。

从表的集中获取IP。例如执行以下命令

$ sudo nft list set ip table-test table-set
use nftnl_rs::{netlink::{netlink::{NetlinkCb, NetlinkResponseReader, Nlmsghdr, MnlNlmsgBatch, NlmFFlags, NetlinkResponse, NetlinkRespRes, NetlinkCbArr, Nlmsgerr}, MNL_SOCKET_BUFFER_SIZE, linux::Nfproto, socket::mnl_socket}, boxed::Boxed, error::NtflRes, set::{nftnl_set, NftnlSetFlags}, nf_tables::NfTablesMsgTypes};
use rand::Rng;

fn main()
{

    let seq = Sequence::new();

    let mut nl_set = NftnlSet::new();

    nl_set.nftnl_set_set_val(NftnlSetFlagData::SetTable("table-test"));
	nl_set.nftnl_set_set_val(NftnlSetFlagData::SetName("table-set"));
    nl_set.nftnl_set_set_val(NftnlSetFlagData::SetId(1));


    let mut batch = MnlNlmsgBatch::mnl_nlmsg_batch_start(*MNL_SOCKET_BUFFER_SIZE);

    // root
    let _nlh = 
        Nlmsghdr::nftnl_nlmsg_build_hdr(
            &mut batch, 
            NfTablesMsgTypes::NftMsgGetsetelem, 
            Nfproto::NFPROTO_IPV4,
            NlmFFlags::NLM_F_DUMP | NlmFFlags::NLM_F_REQUEST,
            seq
        )?;


    nl_set.nftnl_set_elems_nlmsg_build_payload(&mut batch)?;

    drop(nl_set);

    let mut nl = MnlSocket::mnl_socket_open(NETLINK_NETFILTER)?;

    nl.mnl_socket_bind(0, MNL_SOCKET_AUTOPID)?;

    let portid = nl.mnl_socket_get_portid();

    let len = batch.mnl_nlmsg_batch_size();
    nl.mnl_socket_sendto(batch.mnl_nlmsg_batch_msg(), len)?;

    let mut ret = nl.mnl_socket_recvfrom(*MNL_SOCKET_BUFFER_SIZE)?;

    let mut sets: Vec<NftnlSet> = Vec::new();

    while ret.len() > 0
    {
        let mut resp = NetlinkResponse::new(&ret);

        let lret =
            resp.mnl_parse_check(0, portid, &mut sets)?;

        if lret == NetlinkRespRes::MnlCbStop
        {
            break;
        }

        ret = nl.mnl_socket_recvfrom(*MNL_SOCKET_BUFFER_SIZE)?;
    }

    for set in sets
    {
        if set.is_ip_present(ip_check)? == true
        {
            return Ok(true);
        }
    }

    return Ok(false);
}

依赖项

~410–580KB
~10K SLoC