3 releases (breaking)
0.3.0 | Dec 26, 2022 |
---|---|
0.2.0 | Dec 25, 2022 |
0.1.0 | Dec 12, 2022 |
#685 in Unix APIs
85 downloads per month
65KB
1.5K
SLoC
nftables-json
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
.
Contributing
This library is made available under the terms of either the Apache License, Version 2.0 or the MIT License, at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this library by you shall be dual licensed as above, without any additional terms or conditions.
Copyright (c) nftables-json Developers
SPDX-License-Identifier: MIT OR Apache-2.0
Note that the tests for this library are made available under a different
license. See the README in the tests/
directory for more
information.
lib.rs
:
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
*/
Dependencies
~1.2–2MB
~43K SLoC