feat(opnsense-config): Xml parsing now works great to parse a full production config. Only some element ordering that is not consistent across multiple elements of the same type sometimes does not match but moving some stuff around gets us easily to a 100% matching file

This commit is contained in:
Jean-Gabriel Gill-Couture 2024-11-06 16:23:08 -05:00
parent ab59923dae
commit 50ca6afb47
7 changed files with 261 additions and 195 deletions

View File

@ -170,13 +170,16 @@ impl Config {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::infra::yaserde::to_xml_str;
use super::*; use super::*;
use std::path::PathBuf; use std::path::PathBuf;
use pretty_assertions::assert_eq;
#[tokio::test] #[tokio::test]
async fn test_load_config_from_local_file() { async fn test_load_config_from_local_file() {
let mut test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
test_file_path.push("src/tests/data/config-structure.xml"); test_file_path.push("src/tests/data/config-full-1.xml");
let config_file_path = test_file_path.to_str().unwrap().to_string(); let config_file_path = test_file_path.to_str().unwrap().to_string();
println!("File path {config_file_path}"); println!("File path {config_file_path}");
@ -188,13 +191,9 @@ mod tests {
println!("Config {:?}", config); println!("Config {:?}", config);
let yaserde_cfg = yaserde::ser::Config { perform_indent: true, let serialized = to_xml_str(&config.opnsense).unwrap();
.. Default::default()
};
let serialized = yaserde::ser::to_string_with_config(&config.opnsense, &yaserde_cfg).unwrap();
fs::write("/tmp/serialized.xml", &serialized).unwrap(); fs::write("/tmp/serialized.xml", &serialized).unwrap();
std::process::Command::new("xmllint").arg("/tmp/serialized.xml").arg("--output").arg("/tmp/serialized.xmllint.xml").status().expect("xmllint failed");
assert_eq!(config_file_str, serialized); assert_eq!(config_file_str, serialized);
} }

View File

@ -118,7 +118,10 @@ impl YaSerializeTrait for RawXml {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::infra::yaserde::to_xml_str;
use super::*; use super::*;
use pretty_assertions::assert_eq;
use yaserde_derive::YaDeserialize; use yaserde_derive::YaDeserialize;
use yaserde_derive::YaSerialize; use yaserde_derive::YaSerialize;
@ -172,9 +175,46 @@ mod test {
#[test] #[test]
fn rawxml_should_serialize_complex_documents() { fn rawxml_should_serialize_complex_documents() {
let xml = r#"<?xml version="1.0" encoding="utf-8"?><xml><OpenVPN version="1.0.0"><Overwrites /><Instances /><StaticKeys /></OpenVPN><Gateways version="0.0.1" /><HAProxy version="4.0.0"><general><enabled>1</enabled><gracefulStop>0</gracefulStop><hardStopAfter>60s</hardStopAfter><closeSpreadTime /><seamlessReload>0</seamlessReload><storeOcsp>0</storeOcsp><showIntro>1</showIntro><peers><enabled>0</enabled><name1 /><listen1 /><port1>1024</port1><name2 /><listen2 /><port2>1024</port2></peers><tuning><root>0</root><maxConnections /><nbthread>1</nbthread><sslServerVerify>ignore</sslServerVerify><maxDHSize>2048</maxDHSize><bufferSize>16384</bufferSize></tuning></general></HAProxy></xml>"#; let xml = r#"<?xml version="1.0"?>
<xml>
<OpenVPN version="1.0.0">
<Overwrites/>
<Instances/>
<StaticKeys/>
</OpenVPN>
<Gateways version="0.0.1"/>
<HAProxy version="4.0.0">
<general>
<enabled>1</enabled>
<gracefulStop>0</gracefulStop>
<hardStopAfter>60s</hardStopAfter>
<closeSpreadTime/>
<seamlessReload>0</seamlessReload>
<storeOcsp>0</storeOcsp>
<showIntro>1</showIntro>
<peers>
<enabled>0</enabled>
<name1/>
<listen1/>
<port1>1024</port1>
<name2/>
<listen2/>
<port2>1024</port2>
</peers>
<tuning>
<root>0</root>
<maxConnections/>
<nbthread>1</nbthread>
<sslServerVerify>ignore</sslServerVerify>
<maxDHSize>2048</maxDHSize>
<bufferSize>16384</bufferSize>
</tuning>
</general>
</HAProxy>
</xml>
"#;
let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); let rawxml: RawXml = yaserde::de::from_str(xml).unwrap();
assert_eq!(yaserde::ser::to_string(&rawxml).unwrap(), xml); assert_eq!(to_xml_str(&rawxml).unwrap(), xml);
} }
#[test] #[test]

View File

@ -1,4 +1,4 @@
pub mod generic_xml; pub mod generic_xml;
pub mod maybe_string; pub mod maybe_string;
pub mod yaserde;

View File

@ -0,0 +1,20 @@
use yaserde::YaSerialize;
pub fn to_xml_str<T: YaSerialize>(model: &T) -> Result<String, String> {
let yaserde_cfg = yaserde::ser::Config {
perform_indent: true,
write_document_declaration: false,
pad_self_closing: false,
..Default::default()
};
let serialized = yaserde::ser::to_string_with_config::<T>(model, &yaserde_cfg)?;
// Opnsense does not specify encoding in the document declaration
//
// yaserde / xml-rs does not allow disabling the encoding attribute in the
// document declaration
//
// So here we just manually prefix the xml document with the exact document declaration
// that opnsense uses
Ok(format!("<?xml version=\"1.0\"?>\n{serialized}\n"))
}

View File

@ -67,6 +67,8 @@ pub struct DhcpRange {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::infra::yaserde::to_xml_str;
use super::*; use super::*;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
@ -75,19 +77,15 @@ mod test {
let dhcpd: Dhcpd = let dhcpd: Dhcpd =
yaserde::de::from_str(SERIALIZED_DHCPD).expect("Deserialize Dhcpd failed"); yaserde::de::from_str(SERIALIZED_DHCPD).expect("Deserialize Dhcpd failed");
let yaserde_cfg = yaserde::ser::Config {
perform_indent: true,
write_document_declaration: false,
..Default::default()
};
assert_eq!( assert_eq!(
yaserde::ser::to_string_with_config(&dhcpd, &yaserde_cfg) to_xml_str(&dhcpd)
.expect("Serialize Dhcpd failed"), .expect("Serialize Dhcpd failed"),
SERIALIZED_DHCPD SERIALIZED_DHCPD
); );
} }
const SERIALIZED_DHCPD: &str = "<dhcpd> const SERIALIZED_DHCPD: &str = "<?xml version=\"1.0\"?>
<dhcpd>
<lan> <lan>
<enable>1</enable> <enable>1</enable>
<gateway>192.168.20.1</gateway> <gateway>192.168.20.1</gateway>
@ -140,5 +138,5 @@ mod test {
</staticmap> </staticmap>
<pool/> <pool/>
</lan> </lan>
</dhcpd>"; </dhcpd>\n";
} }

View File

@ -73,9 +73,11 @@ pub struct Revision {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Options { pub struct Options {
pub path: MaybeString, pub path: Option<MaybeString>,
pub host: MaybeString, pub host: Option<MaybeString>,
pub code: MaybeString, pub code: Option<MaybeString>,
pub send: Option<MaybeString>,
pub expect: Option<MaybeString>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
@ -87,36 +89,39 @@ pub struct Filters {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Rule { pub struct Rule {
#[yaserde(attribute)] #[yaserde(attribute)]
pub uuid: MaybeString, pub uuid: Option<String>,
#[yaserde(rename = "associated-rule-id")] #[yaserde(rename = "associated-rule-id")]
pub associated_rule_id: MaybeString, pub associated_rule_id: Option<MaybeString>,
#[yaserde(rename = "type")] #[yaserde(rename = "type")]
pub r#type: MaybeString, pub r#type: Option<MaybeString>,
pub interface: String, pub interface: String,
pub ipprotocol: String, pub ipprotocol: String,
pub statetype: String, pub statetype: Option<MaybeString>,
pub descr: String, pub descr: Option<MaybeString>,
pub direction: MaybeString, pub direction: Option<MaybeString>,
pub category: MaybeString, pub category: Option<MaybeString>,
pub quick: MaybeString, pub quick: Option<MaybeString>,
pub protocol: String, pub protocol: Option<MaybeString>,
pub source: Source, pub source: Source,
pub icmptype: Option<MaybeString>,
pub destination: Destination, pub destination: Destination,
pub updated: Option<Updated>, pub updated: Option<Updated>,
pub created: Created, pub created: Option<Created>,
pub disabled: Option<u8>, pub disabled: Option<MaybeString>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Source { pub struct Source {
pub any: Option<u8>, pub any: Option<u8>,
pub network: Option<MaybeString>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Destination { pub struct Destination {
pub network: MaybeString, pub network: Option<MaybeString>,
pub address: MaybeString, pub address: Option<MaybeString>,
pub port: Option<u16>, pub port: Option<MaybeString>,
pub any: Option<MaybeString>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
@ -343,7 +348,7 @@ pub struct Snmpd {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Syslog { pub struct Syslog {
pub reverse: Option<u8>, pub reverse: Option<MaybeString>,
pub preservelogs: i32, pub preservelogs: i32,
} }
@ -368,10 +373,11 @@ pub struct NatRule {
pub ipprotocol: String, pub ipprotocol: String,
pub descr: MaybeString, pub descr: MaybeString,
pub tag: MaybeString, pub tag: MaybeString,
pub tagged: Option<u8>, pub tagged: Option<MaybeString>,
pub poolopts: PoolOpts, pub poolopts: PoolOpts,
#[yaserde(rename = "associated-rule-id")] #[yaserde(rename = "associated-rule-id")]
pub associated_rule_id: String, pub associated_rule_id: Option<MaybeString>,
pub disabled: Option<u8>,
pub target: String, pub target: String,
#[yaserde(rename = "local-port")] #[yaserde(rename = "local-port")]
pub local_port: i32, pub local_port: i32,
@ -439,7 +445,7 @@ pub struct OPNsenseConfig {
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
#[yaserde(rename = "IDS")] #[yaserde(rename = "IDS")]
struct IDS { pub struct IDS {
#[yaserde(attribute)] #[yaserde(attribute)]
version: String, version: String,
rules: MaybeString, rules: MaybeString,
@ -501,30 +507,30 @@ pub struct ConfigInterfaces {
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct Vxlan { pub struct Vxlan {
#[yaserde(attribute)] #[yaserde(attribute)]
version: String, version: String,
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct Loopback { pub struct Loopback {
#[yaserde(attribute)] #[yaserde(attribute)]
version: String, version: String,
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
#[yaserde(rename = "monit")] #[yaserde(rename = "monit")]
struct Monit { pub struct Monit {
#[yaserde(attribute)] #[yaserde(attribute)]
version: String, version: String,
general: GeneralMonit, general: GeneralMonit,
alert: Option<Alert>, alert: Option<Alert>,
service: Option<Service>, service: Vec<Service>,
test: Option<Test>, test: Vec<Test>,
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct GeneralMonit { pub struct GeneralMonit {
enabled: u8, enabled: u8,
interval: u32, interval: u32,
startdelay: u32, startdelay: u32,
@ -537,20 +543,30 @@ struct GeneralMonit {
sslverify: u8, sslverify: u8,
logfile: String, logfile: String,
statefile: MaybeString, statefile: MaybeString,
eventqueuePath: MaybeString, #[yaserde(rename = "eventqueuePath")]
eventqueueSlots: MaybeString, event_queue_path: MaybeString,
httpdEnabled: u8, #[yaserde(rename = "eventqueueSlots")]
httpdUsername: String, event_queue_slots: MaybeString,
httpdPassword: String, #[yaserde(rename = "httpdEnabled")]
httpdPort: u16, httpd_enabled: u8,
httpdAllow: MaybeString, #[yaserde(rename = "httpdUsername")]
mmonitUrl: MaybeString, httpd_username: String,
mmonitTimeout: u32, #[yaserde(rename = "httpdPassword")]
mmonitRegisterCredentials: u8, httpd_password: String,
#[yaserde(rename = "httpdPort")]
httpd_port: u16,
#[yaserde(rename = "httpdAllow")]
httpd_allow: MaybeString,
#[yaserde(rename = "mmonitUrl")]
mmonit_url: MaybeString,
#[yaserde(rename = "mmonitTimeout")]
mmonit_timeout: u32,
#[yaserde(rename = "mmonitRegisterCredentials")]
mmonit_register_credentials: u8,
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct Alert { pub struct Alert {
#[yaserde(attribute)] #[yaserde(attribute)]
uuid: String, uuid: String,
enabled: u8, enabled: u8,
@ -563,7 +579,7 @@ struct Alert {
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct Service { pub struct Service {
#[yaserde(attribute)] #[yaserde(attribute)]
uuid: String, uuid: String,
enabled: u8, enabled: u8,
@ -587,7 +603,7 @@ struct Service {
} }
#[derive(Debug, YaSerialize, YaDeserialize, PartialEq)] #[derive(Debug, YaSerialize, YaDeserialize, PartialEq)]
struct Test { pub struct Test {
#[yaserde(attribute)] #[yaserde(attribute)]
uuid: String, uuid: String,
name: String, name: String,
@ -635,7 +651,7 @@ pub struct Capture {
#[yaserde(rename = "interfaces")] #[yaserde(rename = "interfaces")]
pub interfaces: MaybeString, pub interfaces: MaybeString,
#[yaserde(rename = "egress_only")] #[yaserde(rename = "egress_only")]
pub egress_only: Option<u8>, pub egress_only: MaybeString,
#[yaserde(rename = "version")] #[yaserde(rename = "version")]
pub version: MaybeString, pub version: MaybeString,
#[yaserde(rename = "targets")] #[yaserde(rename = "targets")]
@ -725,7 +741,7 @@ pub struct Firewall {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct LvTemplate { pub struct LvTemplate {
#[yaserde(attribute)] #[yaserde(attribute)]
pub version: MaybeString, pub version: String,
#[yaserde(rename = "templates")] #[yaserde(rename = "templates")]
pub templates: Option<Templates>, pub templates: Option<Templates>,
} }
@ -733,7 +749,7 @@ pub struct LvTemplate {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Category { pub struct Category {
#[yaserde(attribute)] #[yaserde(attribute)]
pub version: MaybeString, pub version: String,
#[yaserde(rename = "categories")] #[yaserde(rename = "categories")]
pub categories: Option<Categories>, pub categories: Option<Categories>,
} }
@ -747,7 +763,7 @@ pub struct Categories {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct CategoryItem { pub struct CategoryItem {
#[yaserde(attribute)] #[yaserde(attribute)]
pub uuid: MaybeString, pub uuid: String,
#[yaserde(rename = "name")] #[yaserde(rename = "name")]
pub name: MaybeString, pub name: MaybeString,
#[yaserde(rename = "auto")] #[yaserde(rename = "auto")]
@ -759,7 +775,7 @@ pub struct CategoryItem {
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Alias { pub struct Alias {
#[yaserde(attribute)] #[yaserde(attribute)]
pub version: MaybeString, pub version: String,
#[yaserde(rename = "geoip")] #[yaserde(rename = "geoip")]
pub geoip: Option<GeoIP>, pub geoip: Option<GeoIP>,
#[yaserde(rename = "aliases")] #[yaserde(rename = "aliases")]
@ -786,13 +802,13 @@ pub struct AliasItem {
pub name: String, pub name: String,
#[yaserde(rename = "type")] #[yaserde(rename = "type")]
pub r#type: String, pub r#type: String,
pub proto: MaybeString,
pub interface: MaybeString, pub interface: MaybeString,
pub counters: String, pub counters: String,
pub updatefreq: MaybeString, pub updatefreq: MaybeString,
pub content: String, pub content: String,
pub categories: MaybeString, pub categories: MaybeString,
pub description: MaybeString, pub description: MaybeString,
pub proto: MaybeString,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
@ -1707,19 +1723,21 @@ pub struct HAProxyHealthCheck {
pub tcp_send_value: MaybeString, pub tcp_send_value: MaybeString,
#[yaserde(rename = "tcp_matchType")] #[yaserde(rename = "tcp_matchType")]
pub tcp_match_type: MaybeString, pub tcp_match_type: MaybeString,
pub tcp_negate: MaybeString,
#[yaserde(rename = "tcp_matchValue")] #[yaserde(rename = "tcp_matchValue")]
pub tcp_match_value: MaybeString, pub tcp_match_value: MaybeString,
pub tcp_negate: MaybeString,
#[yaserde(rename = "agentPort")]
pub agent_port: MaybeString, pub agent_port: MaybeString,
pub mysql_user: MaybeString, pub mysql_user: MaybeString,
pub mysql_post41: MaybeString, pub mysql_post41: MaybeString,
pub pgsql_user: MaybeString, pub pgsql_user: MaybeString,
#[yaserde(alias = "smtpDomain")]
pub smtp_domain: MaybeString, pub smtp_domain: MaybeString,
pub esmtp_domain: MaybeString, pub esmtp_domain: MaybeString,
#[yaserde(rename = "agentPort")]
pub agent_port_uppercase: MaybeString,
#[yaserde(rename = "dbUser")] #[yaserde(rename = "dbUser")]
pub db_user: MaybeString, pub db_user: MaybeString,
#[yaserde(rename = "smtpDomain")]
pub smtp_domain_uppercase: MaybeString,
} }
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]

View File

@ -28,28 +28,22 @@
<value>default</value> <value>default</value>
</item> </item>
<item> <item>
<descr> <descr>Source routing is another way for an attacker to try to reach non-routable addresses behind your box.
Source routing is another way for an attacker to try to reach non-routable addresses behind your box.
It can also be used to probe for information about your internal networks. These functions come enabled It can also be used to probe for information about your internal networks. These functions come enabled
as part of the standard FreeBSD core system. as part of the standard FreeBSD core system.</descr>
</descr>
<tunable>net.inet.ip.sourceroute</tunable> <tunable>net.inet.ip.sourceroute</tunable>
<value>default</value> <value>default</value>
</item> </item>
<item> <item>
<descr> <descr>Source routing is another way for an attacker to try to reach non-routable addresses behind your box.
Source routing is another way for an attacker to try to reach non-routable addresses behind your box.
It can also be used to probe for information about your internal networks. These functions come enabled It can also be used to probe for information about your internal networks. These functions come enabled
as part of the standard FreeBSD core system. as part of the standard FreeBSD core system.</descr>
</descr>
<tunable>net.inet.ip.accept_sourceroute</tunable> <tunable>net.inet.ip.accept_sourceroute</tunable>
<value>default</value> <value>default</value>
</item> </item>
<item> <item>
<descr> <descr>This option turns off the logging of redirect packets because there is no limit and this could fill
This option turns off the logging of redirect packets because there is no limit and this could fill up your logs consuming your whole hard drive.</descr>
up your logs consuming your whole hard drive.
</descr>
<tunable>net.inet.icmp.log_redirect</tunable> <tunable>net.inet.icmp.log_redirect</tunable>
<value>default</value> <value>default</value>
</item> </item>
@ -190,17 +184,14 @@
</item> </item>
<item> <item>
<descr>Enable/disable sending of ICMP redirects in response to IP packets for which a better, <descr>Enable/disable sending of ICMP redirects in response to IP packets for which a better,
and for the sender directly reachable, route and next hop is known. and for the sender directly reachable, route and next hop is known.</descr>
</descr>
<tunable>net.inet.ip.redirect</tunable> <tunable>net.inet.ip.redirect</tunable>
<value>0</value> <value>0</value>
</item> </item>
<item> <item>
<descr> <descr>Redirect attacks are the purposeful mass-issuing of ICMP type 5 packets. In a normal network, redirects
Redirect attacks are the purposeful mass-issuing of ICMP type 5 packets. In a normal network, redirects
to the end stations should not be required. This option enables the NIC to drop all inbound ICMP redirect to the end stations should not be required. This option enables the NIC to drop all inbound ICMP redirect
packets without returning a response. packets without returning a response.</descr>
</descr>
<tunable>net.inet.icmp.drop_redirect</tunable> <tunable>net.inet.icmp.drop_redirect</tunable>
<value>1</value> <value>1</value>
</item> </item>
@ -1039,10 +1030,10 @@
<direction>in</direction> <direction>in</direction>
<quick>1</quick> <quick>1</quick>
<protocol>icmp</protocol> <protocol>icmp</protocol>
<icmptype>echoreq</icmptype>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<icmptype>echoreq</icmptype>
<destination> <destination>
<network>wanip</network> <network>wanip</network>
</destination> </destination>
@ -1058,20 +1049,20 @@
</created> </created>
</rule> </rule>
<rule uuid="492b7596-d929-46cb-a6b9-c9cc34a0ca74"> <rule uuid="492b7596-d929-46cb-a6b9-c9cc34a0ca74">
<associated-rule-id>nat_618812d37b8193.31302503</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>x3690_3</address> <address>x3690_3</address>
<port>22</port> <port>22</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_618812d37b8193.31302503</associated-rule-id>
<created> <created>
<username>root@192.168.1.118</username> <username>root@192.168.1.118</username>
<time>1636307667.5059</time> <time>1636307667.5059</time>
@ -1079,20 +1070,20 @@
</created> </created>
</rule> </rule>
<rule uuid="eeba39a9-d0f6-4b1e-a785-7278b0b241ab"> <rule uuid="eeba39a9-d0f6-4b1e-a785-7278b0b241ab">
<associated-rule-id>nat_64fa19f4acba11.80049900</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.150</address> <address>192.168.20.150</address>
<port>7860</port> <port>7860</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_64fa19f4acba11.80049900</associated-rule-id>
<created> <created>
<username>root@172.12.0.10</username> <username>root@172.12.0.10</username>
<time>1694112244.7075</time> <time>1694112244.7075</time>
@ -1100,20 +1091,20 @@
</created> </created>
</rule> </rule>
<rule uuid="c19adc1c-fec2-4183-93ed-5e46efca1adf"> <rule uuid="c19adc1c-fec2-4183-93ed-5e46efca1adf">
<associated-rule-id>nat_64fb1fbba71e29.76190279</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.150</address> <address>192.168.20.150</address>
<port>7861</port> <port>7861</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_64fb1fbba71e29.76190279</associated-rule-id>
<created> <created>
<username>root@172.12.0.10</username> <username>root@172.12.0.10</username>
<time>1694179259.6845</time> <time>1694179259.6845</time>
@ -1121,20 +1112,20 @@
</created> </created>
</rule> </rule>
<rule uuid="c0831633-8c3b-408e-82d0-3e3f61d0ee3d"> <rule uuid="c0831633-8c3b-408e-82d0-3e3f61d0ee3d">
<associated-rule-id>nat_64fb1fcea6d8b7.62653343</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.150</address> <address>192.168.20.150</address>
<port>7862</port> <port>7862</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_64fb1fcea6d8b7.62653343</associated-rule-id>
<created> <created>
<username>root@172.12.0.10</username> <username>root@172.12.0.10</username>
<time>1694179278.6835</time> <time>1694179278.6835</time>
@ -1142,20 +1133,20 @@
</created> </created>
</rule> </rule>
<rule uuid="3f600791-1fa6-4cb4-877d-45fe2ea175a9"> <rule uuid="3f600791-1fa6-4cb4-877d-45fe2ea175a9">
<associated-rule-id>nat_64fb1fdb48ff18.28912920</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.150</address> <address>192.168.20.150</address>
<port>7863</port> <port>7863</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_64fb1fdb48ff18.28912920</associated-rule-id>
<created> <created>
<username>root@172.12.0.10</username> <username>root@172.12.0.10</username>
<time>1694179291.299</time> <time>1694179291.299</time>
@ -1163,20 +1154,20 @@
</created> </created>
</rule> </rule>
<rule uuid="7dd160f0-663e-465b-be94-a069df112a95"> <rule uuid="7dd160f0-663e-465b-be94-a069df112a95">
<associated-rule-id>nat_651ffc35e573d9.09092618</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.140</address> <address>192.168.20.140</address>
<port>22</port> <port>22</port>
</destination> </destination>
<descr/>
<category/>
<associated-rule-id>nat_651ffc35e573d9.09092618</associated-rule-id>
<created> <created>
<username>root@172.12.0.11</username> <username>root@172.12.0.11</username>
<time>1696594997.9399</time> <time>1696594997.9399</time>
@ -1185,19 +1176,19 @@
</rule> </rule>
<rule uuid="1e576704-da50-4dd9-a425-77fa5c4e563a"> <rule uuid="1e576704-da50-4dd9-a425-77fa5c4e563a">
<associated-rule-id>nat_65aed5a66c4f65.25454286</associated-rule-id> <associated-rule-id>nat_65aed5a66c4f65.25454286</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.140</address> <address>192.168.20.140</address>
<port>8081</port> <port>8081</port>
</destination> </destination>
<descr/>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1705956774.4437</time> <time>1705956774.4437</time>
@ -1206,19 +1197,19 @@
</rule> </rule>
<rule uuid="aa41dd13-9c5a-4048-8820-f9558cea8ba3"> <rule uuid="aa41dd13-9c5a-4048-8820-f9558cea8ba3">
<associated-rule-id>nat_65aed67d497580.58958916</associated-rule-id> <associated-rule-id>nat_65aed67d497580.58958916</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.160</address> <address>192.168.20.160</address>
<port>8080</port> <port>8080</port>
</destination> </destination>
<descr/>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1705956989.3009</time> <time>1705956989.3009</time>
@ -1227,19 +1218,19 @@
</rule> </rule>
<rule uuid="dfd53bf0-cea9-4254-8b0a-106f327d72e5"> <rule uuid="dfd53bf0-cea9-4254-8b0a-106f327d72e5">
<associated-rule-id>nat_65aed6961c4ea7.81903986</associated-rule-id> <associated-rule-id>nat_65aed6961c4ea7.81903986</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.160</address> <address>192.168.20.160</address>
<port>4000</port> <port>4000</port>
</destination> </destination>
<descr/>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1705957014.116</time> <time>1705957014.116</time>
@ -1248,19 +1239,19 @@
</rule> </rule>
<rule uuid="777bdd94-51b9-4daf-b744-70b9cb3c9f94"> <rule uuid="777bdd94-51b9-4daf-b744-70b9cb3c9f94">
<associated-rule-id>nat_65f4a5b928c9a7.52477383</associated-rule-id> <associated-rule-id>nat_65f4a5b928c9a7.52477383</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr/>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.115</address> <address>192.168.20.115</address>
<port>5000</port> <port>5000</port>
</destination> </destination>
<descr/>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1710532025.1671</time> <time>1710532025.1671</time>
@ -1269,19 +1260,19 @@
</rule> </rule>
<rule uuid="98f400f5-1a91-46aa-8d35-f78b34bc7a04"> <rule uuid="98f400f5-1a91-46aa-8d35-f78b34bc7a04">
<associated-rule-id>nat_662bb59baf7573.98640354</associated-rule-id> <associated-rule-id>nat_662bb59baf7573.98640354</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>Redirecting to someservice1 on somehost9</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.115</address> <address>192.168.20.115</address>
<port>11434</port> <port>11434</port>
</destination> </destination>
<descr>Redirecting to someservice1 on somehost9</descr>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1714140571.7187</time> <time>1714140571.7187</time>
@ -1290,19 +1281,19 @@
</rule> </rule>
<rule uuid="fef5ec47-f5e7-45cc-a9f7-f8eeb6d1160c"> <rule uuid="fef5ec47-f5e7-45cc-a9f7-f8eeb6d1160c">
<associated-rule-id>nat_663c3458b7b5e4.19986620</associated-rule-id> <associated-rule-id>nat_663c3458b7b5e4.19986620</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>Redirecting to someservice81 on somehost9</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.115</address> <address>192.168.20.115</address>
<port>27017</port> <port>27017</port>
</destination> </destination>
<descr>Redirecting to someservice81 on somehost9</descr>
<category/>
<created> <created>
<username>root@172.12.0.8</username> <username>root@172.12.0.8</username>
<time>1715221592.7525</time> <time>1715221592.7525</time>
@ -1311,19 +1302,19 @@
</rule> </rule>
<rule uuid="4170cf4e-4116-42e9-a3ec-eff6768bca9d"> <rule uuid="4170cf4e-4116-42e9-a3ec-eff6768bca9d">
<associated-rule-id>nat_663d85b2e3b364.53108170</associated-rule-id> <associated-rule-id>nat_663d85b2e3b364.53108170</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>Redirecting to someservice858 on somehost545</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.163</address> <address>192.168.20.163</address>
<port>8888</port> <port>8888</port>
</destination> </destination>
<descr>Redirecting to someservice858 on somehost545</descr>
<category/>
<created> <created>
<username>root@172.12.0.10</username> <username>root@172.12.0.10</username>
<time>1715307954.9327</time> <time>1715307954.9327</time>
@ -1332,19 +1323,19 @@
</rule> </rule>
<rule uuid="79e4325d-93af-4af2-9fa0-263c69545eb0"> <rule uuid="79e4325d-93af-4af2-9fa0-263c69545eb0">
<associated-rule-id>nat_666c8932142ed6.34062700</associated-rule-id> <associated-rule-id>nat_666c8932142ed6.34062700</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>Redirecting to someservice858 on somehost9</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.115</address> <address>192.168.20.115</address>
<port>8888</port> <port>8888</port>
</destination> </destination>
<descr>Redirecting to someservice858 on somehost9</descr>
<category/>
<created> <created>
<username>root@192.168.20.100</username> <username>root@192.168.20.100</username>
<time>1718389042.0827</time> <time>1718389042.0827</time>
@ -1353,19 +1344,19 @@
</rule> </rule>
<rule uuid="1b68a264-e475-4cc6-b852-0797154fdf2b"> <rule uuid="1b68a264-e475-4cc6-b852-0797154fdf2b">
<associated-rule-id>nat_667cd97504d870.57128970</associated-rule-id> <associated-rule-id>nat_667cd97504d870.57128970</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>Redirecting to someservice858 on somehost545</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.163</address> <address>192.168.20.163</address>
<port>8889</port> <port>8889</port>
</destination> </destination>
<descr>Redirecting to someservice858 on somehost545</descr>
<category/>
<created> <created>
<username>root@172.12.0.8</username> <username>root@172.12.0.8</username>
<time>1719458165.0199</time> <time>1719458165.0199</time>
@ -1401,9 +1392,9 @@
</rule> </rule>
<rule uuid="96d70c20-b78c-4e18-9823-79b71eba964c"> <rule uuid="96d70c20-b78c-4e18-9823-79b71eba964c">
<type>pass</type> <type>pass</type>
<interface>lan</interface>
<ipprotocol>inet</ipprotocol> <ipprotocol>inet</ipprotocol>
<descr>Default allow LAN to any rule</descr> <descr>Default allow LAN to any rule</descr>
<interface>lan</interface>
<source> <source>
<network>lan</network> <network>lan</network>
</source> </source>
@ -1413,9 +1404,9 @@
</rule> </rule>
<rule uuid="61194fb7-8916-4e30-a32b-a90495987c64"> <rule uuid="61194fb7-8916-4e30-a32b-a90495987c64">
<type>pass</type> <type>pass</type>
<interface>lan</interface>
<ipprotocol>inet6</ipprotocol> <ipprotocol>inet6</ipprotocol>
<descr>Default allow LAN IPv6 to any rule</descr> <descr>Default allow LAN IPv6 to any rule</descr>
<interface>lan</interface>
<source> <source>
<network>lan</network> <network>lan</network>
</source> </source>
@ -1474,19 +1465,19 @@
</rule> </rule>
<rule> <rule>
<associated-rule-id>nat_6709763b6a6748.85579760</associated-rule-id> <associated-rule-id>nat_6709763b6a6748.85579760</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>port forwarding for reconfig of someservice2 somehost3</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.132</address> <address>192.168.20.132</address>
<port>55555</port> <port>55555</port>
</destination> </destination>
<descr>port forwarding for reconfig of someservice2 somehost3</descr>
<category/>
<created> <created>
<username>root@172.12.0.12</username> <username>root@172.12.0.12</username>
<time>1728673339.4359</time> <time>1728673339.4359</time>
@ -1496,19 +1487,19 @@
</rule> </rule>
<rule> <rule>
<associated-rule-id>nat_670979b3279551.73601303</associated-rule-id> <associated-rule-id>nat_670979b3279551.73601303</associated-rule-id>
<interface>wan</interface>
<ipprotocol>inet</ipprotocol>
<statetype>keep state</statetype>
<descr>port forwarding for virtual ip for someservice2 servers</descr>
<category/>
<protocol>tcp</protocol>
<source> <source>
<any>1</any> <any>1</any>
</source> </source>
<interface>wan</interface>
<statetype>keep state</statetype>
<protocol>tcp</protocol>
<ipprotocol>inet</ipprotocol>
<destination> <destination>
<address>192.168.20.1</address> <address>192.168.20.1</address>
<port>55555</port> <port>55555</port>
</destination> </destination>
<descr>port forwarding for virtual ip for someservice2 servers</descr>
<category/>
<created> <created>
<username>root@172.12.0.12</username> <username>root@172.12.0.12</username>
<time>1728674227.1622</time> <time>1728674227.1622</time>