Skip to content

Commit

Permalink
feat: add synproxy statement and list object
Browse files Browse the repository at this point in the history
also mark some other statements that are missing.
compare with nftables json_parse_stmt:  https://git.netfilter.org/nftables/tree/src/parser_json.c?id=c4c740117f6fbf39dd67dd87635ea8b497718ad7#n2884
  • Loading branch information
jwhb committed Oct 21, 2024
1 parent 8a3cde1 commit b7e0423
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
29 changes: 29 additions & 0 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum NfListObject {
CTTimeout(CTTimeout),
#[serde(rename = "ct expectation")]
CTExpectation(CTExpectation),
SynProxy(SynProxy),
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -435,3 +436,31 @@ pub struct CTExpectation {
#[serde(skip_serializing_if = "Option::is_none")]
pub size: Option<u32>,
}

/// [SynProxy] intercepts new TCP connections and handles the initial 3-way handshake using
/// syncookies instead of conntrack to establish the connection.
///
/// Named SynProxy requires **nftables 0.9.3 or newer**.
///
/// [SynProxy]: https://wiki.nftables.org/wiki-nftables/index.php/Synproxy
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct SynProxy {
/// The table’s family.
pub family: NfFamily,
/// The table’s name.
pub table: String,
/// The synproxy's name.
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
/// The synproxy's handle. For input, it is used by the [delete command][NfCmd::Delete] only.
pub handle: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The maximum segment size (must match your backend server).
pub mss: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The window scale (must match your backend server).
pub wscale: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The synproxy's [flags][crate::types::SynProxyFlag].
pub flags: Option<HashSet<SynProxyFlag>>,
}
27 changes: 25 additions & 2 deletions src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};

use strum_macros::EnumString;

use crate::types::RejectCode;
use crate::types::{RejectCode, SynProxyFlag};
use crate::visitor::single_string_to_option_hashset_logflag;

use crate::expr::Expression;
Expand Down Expand Up @@ -36,8 +36,10 @@ pub enum Statement {
#[serde(rename = "quota")]
/// reference to a named quota object
QuotaRef(String),
// TODO: last
Limit(Limit),

// TODO: flow
FWD(Option<FWD>),
/// Disable connection tracking for the packet.
Notrack,
Expand All @@ -48,6 +50,7 @@ pub enum Statement {
Redirect(Option<NAT>), // redirect is subset of NAT options
Reject(Option<Reject>),
Set(Set),
// TODO: map
Log(Option<Log>),

#[serde(rename = "ct helper")]
Expand All @@ -57,6 +60,7 @@ pub enum Statement {
Meter(Meter),
Queue(Queue),
#[serde(rename = "vmap")]
// TODO: vmap is expr, not stmt!
VerdictMap(VerdictMap),

#[serde(rename = "ct count")]
Expand All @@ -73,9 +77,12 @@ pub enum Statement {
/// This represents an xt statement from xtables compat interface.
/// Sadly, at this point, it is not possible to provide any further information about its content.
XT(Option<serde_json::Value>),

/// A netfilter synproxy intercepts new TCP connections and handles the initial 3-way handshake using syncookies instead of conntrack to establish the connection.
SynProxy(SynProxy),
/// Redirects the packet to a local socket without changing the packet header in any way.
TProxy(TProxy),
// TODO: reset
// TODO: secmark
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -432,6 +439,22 @@ pub struct CTCount {
pub inv: Option<bool>,
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
/// Limit the number of connections using conntrack.
///
/// Anonymous synproxy was requires **nftables 0.9.2 or newer**.
pub struct SynProxy {
#[serde(skip_serializing_if = "Option::is_none")]
/// maximum segment size (must match your backend server)
pub mss: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
/// window scale (must match your backend server)
pub wscale: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The synproxy's [flags][crate::types::SynProxyFlag].
pub flags: Option<HashSet<SynProxyFlag>>,
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
/// Redirects the packet to a local socket without changing the packet header in any way.
Expand Down
11 changes: 11 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ pub enum RejectCode {
/// Address unreachable (ICMPv6)
AddrUnreach,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename_all = "lowercase")]
/// Describes a SynProxy's flags.
pub enum SynProxyFlag {
/// Pass client timestamp option to backend.
Timestamp,
#[serde(rename = "sack-perm")]
/// Pass client selective acknowledgement option to backend.
SackPerm,
}

0 comments on commit b7e0423

Please sign in to comment.