Crate nftables_json

Source
Expand description

Serde JSON model for interacting with the nftables nft executable

Provides Rust types that map directly to the nftables JSON object model, allowing serialization and deserialization of input and output from the nft --json command using Serde and serde_json.

§Example

Creating commands that can be piped into nft --json --file -

use nftables_json::{command::*, expression::*, statement::*};

let mut commands = Commands::default();
commands.extend([
    // flush rulesets for all families
    Command::Flush(Flush::Ruleset(None)),
    // create a new table called "default"
    Command::Add(Add::Table(AddTable {
        family: "inet".into(),
        name: "default".into(),
        ..AddTable::default()
    })),
    // attach a chain to the "default" table called "input"
    Command::Add(Add::Chain(AddChain {
        family: "inet".into(),
        table: "default".into(),
        name: "input".into(),
        r#type: Some("filter".into()),
        hook: Some("input".into()),
        prio: Some(0),
        policy: Some("accept".into()),
        ..AddChain::default()
    })),
    Command::Add(Add::Rule(AddRule {
        // attach a rule to the "input" chain in the "default" table that drops udp sport 53
        family: "inet".into(),
        table: "default".into(),
        chain: "input".into(),
        expr: Some(vec![
            Statement::Match(Match {
                left: Expression::Payload {
                    payload: Payload::Named { protocol: "udp".into(), field: "sport".into() },
                }
                .into(),
                right: Expression::Immediate(Immediate::Number(53)).into(),
                op: "==".into(),
            }),
            Statement::Drop(()),
        ]),
        ..AddRule::default()
    })),
]);

// not shown: how to invoke `nft` from Rust and pipe json to stdin
println!("{}", commands.to_string().unwrap());

/*
{"nftables":[
  {"flush":{"ruleset":null}},
  {"add":{"table":{"family":"inet","name":"default"}}},
  {"add":{"chain":{"family":"inet","table":"default","name":"input","policy":"accept","type":"filter","hook":"input","prio":0}}},
  {"add":{"rule":{"family":"inet","table":"default","chain":"input","expr":[
    {"match":{"left":{"payload":{"protocol":"udp","field":"sport"}},"right":53,"op":"=="}},
    {"drop":null}
  ]}}}
]}
*/

§Example

Parsing a ruleset produced by printf '{"nftables":[{"list":{"ruleset":null}}]}' | nft --json --file -

use nftables_json::{object::*, expression::*, statement::*};

// not shown: how to invoke `nft` from Rust and collect stdout
let output_str = r#"
{"nftables":[
  {"metainfo":{"version":"0.9.8","release_name":"E.D.S.","json_schema_version":1}},
  {"table":{"family":"inet","name":"default","handle":3}},
  {"chain":{"family":"inet","table":"default","name":"input","handle":1,"type":"filter","hook":"input","prio":0,"policy":"accept"}},
  {"rule":{"family":"inet","table":"default","chain":"input","handle":3,"expr":[
    {"match":{"op":"==","left":{"payload":{"protocol":"udp","field":"sport"}},"right":53}},
    {"drop":null}
  ]}},
  {"chain":{"family":"inet","table":"default","name":"output","handle":2,"type":"filter","hook":"output","prio":0,"policy":"accept"}}
]}
"#;

let objects = Objects::from_str(output_str).unwrap();

for object in objects.iter() {
    match object {
        Object::Metainfo(Metainfo { json_schema_version, .. }) => {
            eprintln!("[metainfo] schema version {json_schema_version}");
        }
        Object::Table(Table { family, name, .. }) => {
            eprintln!("[table] {family} {name}");
        }
        Object::Chain(Chain { family, table, name, hook: Some(hook), .. }) => {
            eprintln!("[chain] {family} {table} {name} hook {hook}");
        }
        Object::Rule(Rule { family, table, chain, .. }) => {
            eprintln!("[rule] {family} {table} {chain}");
        }
        _ => {}
    }
}

/*
schema version 1
table family inet name default
chain family inet table default name input hook input
rule family inet table default chain input
chain family inet table default name output hook output
*/

Modules§

command
Provides types related to inputting commands to nft --json
expression
Provides types related to specifying a rule’s match criteria
object
Provides types related to parsing output from nft --json
statement
Provides types related to specifying a rule’s construction