From 7a9ed8fa1af350a760131bf52357fbea69f5a62f Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 11:16:12 -0800 Subject: [PATCH 01/12] Update files via octoaide 29 files changed, 2388 insertions(+), 68 deletions(-) Automated changes made by octoaide bot. --- CHANGELOG.md | 8 + src/backup.rs | 2 + src/event.rs | 74 + src/event/bootp.rs | 6 +- src/event/common.rs | 63 + src/event/conn.rs | 24 +- src/event/dcerpc.rs | 6 +- src/event/dhcp.rs | 6 +- src/event/dns.rs | 18 +- src/event/ftp.rs | 16 +- src/event/http.rs | 24 +- src/event/kerberos.rs | 6 +- src/event/ldap.rs | 12 +- src/event/malformed_dns.rs | 7 +- src/event/mqtt.rs | 6 +- src/event/nfs.rs | 6 +- src/event/ntlm.rs | 6 +- src/event/radius.rs | 7 +- src/event/rdp.rs | 12 +- src/event/smb.rs | 6 +- src/event/smtp.rs | 6 +- src/event/ssh.rs | 6 +- src/event/tls.rs | 6 +- src/event/tor.rs | 2 + src/event/unusual_destination_pattern.rs | 7 +- src/migrate.rs | 5 +- src/migration.rs | 321 +++- src/migration/migration_structures.rs | 1791 +++++++++++++++++++++- 28 files changed, 2389 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1d2459..753c2607 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,14 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Added +- Added `src_country_code` and `dst_country_code` fields to all event-specific + `*Fields` structs. These fields store 2-letter ISO country codes as + `Option<[u8; 2]>`, enabling geographic filtering and analysis of security + events. Country codes can be resolved from IP addresses using an ip2location + database during event creation. +- Updated `migrate_data_dir` function signature to accept an optional + `ip2location::DB` parameter for resolving country codes during migration + from older database formats. - Added `BackupConfig` entity to configure RocksDB backup settings (interval, execution time, retention). The configuration can be saved, updated, and read from persistent storage, with default values applied if none exist. diff --git a/src/backup.rs b/src/backup.rs index 01ce9da5..7560c94a 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -109,9 +109,11 @@ mod tests { let codec = bincode::DefaultOptions::new(); let fields = DnsEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 53, proto: 17, start_time: Utc diff --git a/src/event.rs b/src/event.rs index efe23d77..850a9f75 100644 --- a/src/event.rs +++ b/src/event.rs @@ -2964,8 +2964,10 @@ mod tests { fn example_message(kind: EventKind, category: EventCategory) -> EventMessage { let fields = DnsEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -3079,8 +3081,10 @@ mod tests { fn syslog_for_dga() { let fields = DgaFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3231,8 +3235,10 @@ mod tests { let fields = HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3302,8 +3308,10 @@ mod tests { fn syslog_for_nonbrowser() { let fields = HttpEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3368,8 +3376,10 @@ mod tests { fn syslog_for_blocklist_http() { let fields = BlocklistHttpFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3435,8 +3445,10 @@ mod tests { fn syslog_for_lockyransomware() { let fields = DnsEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 4)), resp_port: 53, proto: 17, @@ -3496,7 +3508,9 @@ mod tests { fn syslog_for_portscan() { let fields = PortScanFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc @@ -3543,7 +3557,9 @@ mod tests { fn syslog_for_multihostportscan() { let fields = MultiHostPortScanFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + dst_country_codes: vec![None, None], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -3593,10 +3609,12 @@ mod tests { fn syslog_for_externalddos() { let fields = ExternalDdosFields { sensor: String::new(), + src_country_codes: vec![None, None], orig_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3640,8 +3658,10 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 67, proto: 17, @@ -3771,8 +3791,10 @@ mod tests { fn syslog_for_blocklist_conn() { let fields = BlocklistConnFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3823,8 +3845,10 @@ mod tests { fn syslog_for_blocklist_dcerpc() { let fields = BlocklistDceRpcFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 135, proto: 6, @@ -3874,8 +3898,10 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::from_str("127.0.0.1").unwrap(), orig_port: 68, + dst_country_code: None, resp_addr: IpAddr::from_str("127.0.0.2").unwrap(), resp_port: 67, proto: 17, @@ -4012,8 +4038,10 @@ mod tests { fn syslog_for_dnscovertchannel() { let fields = DnsEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4078,8 +4106,10 @@ mod tests { fn syslog_for_cryptocurrencyminingpool() { let fields = CryptocurrencyMiningPoolFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4140,8 +4170,10 @@ mod tests { fn syslog_for_blocklist_dns() { let fields = BlocklistDnsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4199,7 +4231,9 @@ mod tests { fn syslog_for_ftpbruteforce() { let fields = FtpBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4264,8 +4298,10 @@ mod tests { let fields = FtpEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4328,8 +4364,10 @@ mod tests { }; FtpEventFields { + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4458,8 +4496,10 @@ mod tests { .unwrap(); let fields = RepeatedHttpSessionsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -4497,8 +4537,10 @@ mod tests { fn syslog_for_blocklist_kerberos() { let fields = BlocklistKerberosFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 88, proto: 17, @@ -4555,7 +4597,9 @@ mod tests { fn syslog_for_ldapbruteforce() { let fields = LdapBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4607,8 +4651,10 @@ mod tests { fn syslog_for_ldapplaintext() { let fields = LdapEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4662,8 +4708,10 @@ mod tests { fn ldapeventfields() -> LdapEventFields { LdapEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4789,8 +4837,10 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1812, proto: 17, @@ -4922,8 +4972,10 @@ mod tests { fn syslog_for_blocklist_mqtt() { let fields = BlocklistMqttFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1883, proto: 6, @@ -5020,8 +5072,10 @@ mod tests { fn syslog_for_blocklist_nfs() { let fields = BlocklistNfsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 2049, proto: 6, @@ -5071,8 +5125,10 @@ mod tests { fn syslog_for_blocklist_ntlm() { let fields = BlocklistNtlmFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5154,8 +5210,10 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -5286,7 +5344,9 @@ mod tests { fn syslog_for_rdpbruteforce() { let fields = RdpBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + dst_country_codes: vec![None, None], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -5336,8 +5396,10 @@ mod tests { fn syslog_for_blocklist_rdp() { let fields = BlocklistRdpFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 3389, proto: 6, @@ -5386,8 +5448,10 @@ mod tests { fn syslog_for_blocklist_smb() { let fields = BlocklistSmbFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5446,8 +5510,10 @@ mod tests { fn syslog_for_blocklist_smtp() { let fields = BlocklistSmtpFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 25, proto: 6, @@ -5502,8 +5568,10 @@ mod tests { fn syslog_for_blocklist_ssh() { let fields = BlocklistSshFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 22, proto: 6, @@ -5618,8 +5686,10 @@ mod tests { fn syslog_for_blocklist_tls() { let fields = BlocklistTlsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5697,8 +5767,10 @@ mod tests { resp_pkts: 0, orig_l2_bytes: 0, resp_l2_bytes: 0, + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5827,8 +5899,10 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + dst_country_code: None, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, diff --git a/src/event/bootp.rs b/src/event/bootp.rs index 4d49569e..2b8e45d0 100644 --- a/src/event/bootp.rs +++ b/src/event/bootp.rs @@ -40,7 +40,7 @@ macro_rules! find_bootp_attr_by_kind { }}; } -pub type BlocklistBootpFields = BlocklistBootpFieldsV0_42; +pub type BlocklistBootpFields = BlocklistBootpFieldsV0_43; impl BlocklistBootpFields { #[must_use] @@ -81,11 +81,13 @@ impl BlocklistBootpFields { } #[derive(Serialize, Deserialize)] -pub struct BlocklistBootpFieldsV0_42 { +pub struct BlocklistBootpFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/common.rs b/src/event/common.rs index 470b7651..4edae345 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -1604,9 +1604,11 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 67, proto: 17, start_time: Utc @@ -1638,9 +1640,11 @@ mod tests { fn blocklist_conn_fields() -> BlocklistConnFields { BlocklistConnFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, conn_state: "SAF".to_string(), @@ -1665,9 +1669,11 @@ mod tests { fn blocklist_dcerpc_fields() -> BlocklistDceRpcFields { BlocklistDceRpcFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 135, proto: 6, start_time: Utc @@ -1692,9 +1698,11 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 67, proto: 17, start_time: Utc @@ -1734,9 +1742,11 @@ mod tests { fn blocklist_dns_fields() -> BlocklistDnsFields { BlocklistDnsFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 53, proto: 17, start_time: Utc @@ -1769,9 +1779,11 @@ mod tests { fn blocklist_http_fields() -> BlocklistHttpFields { BlocklistHttpFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, start_time: Utc @@ -1812,9 +1824,11 @@ mod tests { fn blocklist_kerberos_fields() -> BlocklistKerberosFields { BlocklistKerberosFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 88, proto: 17, start_time: Utc @@ -1844,9 +1858,11 @@ mod tests { fn blocklist_mqtt_fields() -> BlocklistMqttFields { BlocklistMqttFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 1883, proto: 6, start_time: Utc @@ -1873,9 +1889,11 @@ mod tests { fn blocklist_nfs_fields() -> BlocklistNfsFields { BlocklistNfsFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 2049, proto: 6, start_time: Utc @@ -1898,9 +1916,11 @@ mod tests { fn blocklist_ntlm_fields() -> BlocklistNtlmFields { BlocklistNtlmFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 445, proto: 6, start_time: Utc @@ -1926,9 +1946,11 @@ mod tests { fn blocklist_rdp_fields() -> BlocklistRdpFields { BlocklistRdpFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 3389, proto: 6, start_time: Utc @@ -1950,9 +1972,11 @@ mod tests { fn blocklist_smb_fields() -> BlocklistSmbFields { BlocklistSmbFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 445, proto: 6, start_time: Utc @@ -1984,9 +2008,11 @@ mod tests { fn blocklist_smtp_fields() -> BlocklistSmtpFields { BlocklistSmtpFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 25, proto: 6, start_time: Utc @@ -2014,9 +2040,11 @@ mod tests { fn blocklist_ssh_fields() -> BlocklistSshFields { BlocklistSshFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 22, proto: 6, start_time: Utc @@ -2050,9 +2078,11 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 443, proto: 6, start_time: Utc @@ -2094,9 +2124,11 @@ mod tests { fn ldap_event_fields() -> LdapEventFields { LdapEventFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 389, proto: 6, start_time: Utc @@ -2139,9 +2171,11 @@ mod tests { FtpEventFields { sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 21, proto: 6, start_time: Utc @@ -2165,8 +2199,10 @@ mod tests { fn port_scan_fields() -> PortScanFields { PortScanFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2187,11 +2223,13 @@ mod tests { fn multi_host_port_scan_fields() -> MultiHostPortScanFields { MultiHostPortScanFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], + dst_country_codes: vec![], resp_port: 80, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2216,7 +2254,9 @@ mod tests { IpAddr::V4(Ipv4Addr::LOCALHOST), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], + src_country_codes: vec![], resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2236,9 +2276,11 @@ mod tests { fn crypto_miining_pool_fields() -> CryptocurrencyMiningPoolFields { CryptocurrencyMiningPoolFields { sensor: "sensro".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 53, proto: 17, start_time: Utc @@ -2272,8 +2314,10 @@ mod tests { fn ftp_brute_force_fields() -> FtpBruteForceFields { FtpBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 21, proto: 6, user_list: vec!["user1".to_string(), "user_2".to_string()], @@ -2297,9 +2341,11 @@ mod tests { let now = chrono::Utc::now().timestamp_nanos_opt().unwrap(); RepeatedHttpSessionsFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 443, proto: 6, start_time: now, @@ -2312,9 +2358,11 @@ mod tests { fn dga_fields() -> DgaFields { DgaFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, start_time: Utc @@ -2355,9 +2403,11 @@ mod tests { fn http_event_fields() -> HttpEventFields { HttpEventFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, start_time: Utc @@ -2398,8 +2448,10 @@ mod tests { fn ldap_brute_force_fields() -> LdapBruteForceFields { LdapBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 389, proto: 6, user_pw_list: vec![ @@ -2424,11 +2476,13 @@ mod tests { fn rdp_brute_force_fields() -> RdpBruteForceFields { RdpBruteForceFields { sensor: String::new(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], + dst_country_codes: vec![], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2448,9 +2502,11 @@ mod tests { fn dns_event_fields() -> DnsEventFields { DnsEventFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 53, proto: 17, start_time: Utc @@ -2552,9 +2608,11 @@ mod tests { HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, start_time: Utc @@ -2599,9 +2657,11 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 1812, proto: 17, start_time: Utc @@ -2636,9 +2696,11 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 53, proto: 17, start_time: Utc @@ -2682,6 +2744,7 @@ mod tests { .timestamp_nanos_opt() .unwrap(), destination_ips: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))], + dst_country_codes: vec![], count: 1, expected_mean: 0.0, std_deviation: 0.0, diff --git a/src/event/conn.rs b/src/event/conn.rs index de8adeae..0267714f 100644 --- a/src/event/conn.rs +++ b/src/event/conn.rs @@ -35,13 +35,15 @@ macro_rules! find_conn_attr_by_kind { } pub(crate) use find_conn_attr_by_kind; -pub type PortScanFields = PortScanFieldsV0_42; +pub type PortScanFields = PortScanFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct PortScanFieldsV0_42 { +pub struct PortScanFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_ports: Vec, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -186,14 +188,16 @@ impl Match for PortScan { } } -pub type MultiHostPortScanFields = MultiHostPortScanFieldsV0_42; +pub type MultiHostPortScanFields = MultiHostPortScanFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct MultiHostPortScanFieldsV0_42 { +pub struct MultiHostPortScanFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_port: u16, pub resp_addrs: Vec, + pub dst_country_codes: Vec>, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -338,13 +342,15 @@ impl Match for MultiHostPortScan { } } -pub type ExternalDdosFields = ExternalDdosFieldsV0_42; +pub type ExternalDdosFields = ExternalDdosFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct ExternalDdosFieldsV0_42 { +pub struct ExternalDdosFieldsV0_43 { pub sensor: String, pub orig_addrs: Vec, + pub src_country_codes: Vec>, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -484,14 +490,16 @@ impl Match for ExternalDdos { } } -pub type BlocklistConnFields = BlocklistConnFieldsV0_42; +pub type BlocklistConnFields = BlocklistConnFieldsV0_43; #[derive(Deserialize, Serialize)] -pub struct BlocklistConnFieldsV0_42 { +pub struct BlocklistConnFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub conn_state: String, diff --git a/src/event/dcerpc.rs b/src/event/dcerpc.rs index bebc81ff..8382ea1a 100644 --- a/src/event/dcerpc.rs +++ b/src/event/dcerpc.rs @@ -7,14 +7,16 @@ use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; use crate::event::common::{AttrValue, triage_scores_to_string}; -pub type BlocklistDceRpcFields = BlocklistDceRpcFieldsV0_42; +pub type BlocklistDceRpcFields = BlocklistDceRpcFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistDceRpcFieldsV0_42 { +pub struct BlocklistDceRpcFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/dhcp.rs b/src/event/dhcp.rs index 480a53bb..8b3b7844 100644 --- a/src/event/dhcp.rs +++ b/src/event/dhcp.rs @@ -58,14 +58,16 @@ macro_rules! find_dhcp_attr_by_kind { }}; } -pub type BlocklistDhcpFields = BlocklistDhcpFieldsV0_42; +pub type BlocklistDhcpFields = BlocklistDhcpFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistDhcpFieldsV0_42 { +pub struct BlocklistDhcpFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/dns.rs b/src/event/dns.rs index d41a6ce6..ef1873a5 100644 --- a/src/event/dns.rs +++ b/src/event/dns.rs @@ -47,14 +47,16 @@ macro_rules! find_dns_attr_by_kind { }}; } -pub type DnsEventFields = DnsEventFieldsV0_42; +pub type DnsEventFields = DnsEventFieldsV0_43; #[derive(Deserialize, Serialize)] -pub struct DnsEventFieldsV0_42 { +pub struct DnsEventFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -463,14 +465,16 @@ impl Match for LockyRansomware { } } -pub type CryptocurrencyMiningPoolFields = CryptocurrencyMiningPoolFieldsV0_42; +pub type CryptocurrencyMiningPoolFields = CryptocurrencyMiningPoolFieldsV0_43; #[derive(Deserialize, Serialize)] -pub struct CryptocurrencyMiningPoolFieldsV0_42 { +pub struct CryptocurrencyMiningPoolFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -711,14 +715,16 @@ impl Match for CryptocurrencyMiningPool { } } -pub type BlocklistDnsFields = BlocklistDnsFieldsV0_42; +pub type BlocklistDnsFields = BlocklistDnsFieldsV0_43; #[derive(Deserialize, Serialize)] -pub struct BlocklistDnsFieldsV0_42 { +pub struct BlocklistDnsFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/ftp.rs b/src/event/ftp.rs index d4cfec2b..757f0089 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -159,7 +159,7 @@ macro_rules! find_ftp_attr_by_kind { }}; } -pub type FtpBruteForceFields = FtpBruteForceFieldsV0_42; +pub type FtpBruteForceFields = FtpBruteForceFieldsV0_43; impl FtpBruteForceFields { #[must_use] @@ -187,10 +187,12 @@ impl FtpBruteForceFields { } #[derive(Serialize, Deserialize)] -pub struct FtpBruteForceFieldsV0_42 { +pub struct FtpBruteForceFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub user_list: Vec, @@ -203,12 +205,14 @@ pub struct FtpBruteForceFieldsV0_42 { pub category: Option, } -impl From for FtpBruteForceFieldsV0_42 { +impl From for FtpBruteForceFieldsV0_43 { fn from(value: FtpBruteForceFieldsV0_41) -> Self { Self { sensor: String::new(), + src_country_code: None, orig_addr: value.src_addr, resp_addr: value.dst_addr, + dst_country_code: None, resp_port: value.dst_port, proto: value.proto, user_list: value.user_list, @@ -353,7 +357,7 @@ impl Match for FtpBruteForce { } } -pub type FtpEventFields = FtpEventFieldsV0_42; +pub type FtpEventFields = FtpEventFieldsV0_43; impl FtpEventFields { #[must_use] @@ -393,11 +397,13 @@ impl FtpEventFields { } #[derive(Debug, Deserialize, Serialize)] -pub struct FtpEventFieldsV0_42 { +pub struct FtpEventFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/http.rs b/src/event/http.rs index f035cf54..fcd2d320 100644 --- a/src/event/http.rs +++ b/src/event/http.rs @@ -59,14 +59,16 @@ macro_rules! find_http_attr_by_kind { } pub(super) use find_http_attr_by_kind; -pub type HttpEventFields = HttpEventFieldsV0_42; +pub type HttpEventFields = HttpEventFieldsV0_43; #[derive(Deserialize, Serialize)] -pub struct HttpEventFieldsV0_42 { +pub struct HttpEventFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -147,14 +149,16 @@ impl HttpEventFields { } } -pub type RepeatedHttpSessionsFields = RepeatedHttpSessionsFieldsV0_42; +pub type RepeatedHttpSessionsFields = RepeatedHttpSessionsFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct RepeatedHttpSessionsFieldsV0_42 { +pub struct RepeatedHttpSessionsFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -303,17 +307,19 @@ impl Match for RepeatedHttpSessions { } } -pub type HttpThreatFields = HttpThreatFieldsV0_42; +pub type HttpThreatFields = HttpThreatFieldsV0_43; #[derive(Debug, Deserialize, Serialize)] #[allow(clippy::module_name_repetitions)] -pub struct HttpThreatFieldsV0_42 { +pub struct HttpThreatFieldsV0_43 { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -652,14 +658,16 @@ impl Match for HttpThreat { } } -pub type DgaFields = DgaFieldsV0_42; +pub type DgaFields = DgaFieldsV0_43; #[derive(Debug, Deserialize, Serialize)] -pub struct DgaFieldsV0_42 { +pub struct DgaFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/kerberos.rs b/src/event/kerberos.rs index bc74c8ba..c06900d6 100644 --- a/src/event/kerberos.rs +++ b/src/event/kerberos.rs @@ -42,14 +42,16 @@ macro_rules! find_kerberos_attr_by_kind { }}; } -pub type BlocklistKerberosFields = BlocklistKerberosFieldsV0_42; +pub type BlocklistKerberosFields = BlocklistKerberosFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistKerberosFieldsV0_42 { +pub struct BlocklistKerberosFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/ldap.rs b/src/event/ldap.rs index 015056e2..82e4d69d 100644 --- a/src/event/ldap.rs +++ b/src/event/ldap.rs @@ -47,13 +47,15 @@ macro_rules! find_ldap_attr_by_kind { }}; } -pub type LdapBruteForceFields = LdapBruteForceFieldsV0_42; +pub type LdapBruteForceFields = LdapBruteForceFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct LdapBruteForceFieldsV0_42 { +pub struct LdapBruteForceFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub user_pw_list: Vec<(String, String)>, @@ -213,14 +215,16 @@ impl Match for LdapBruteForce { } } -pub type LdapEventFields = LdapEventFieldsV0_42; +pub type LdapEventFields = LdapEventFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct LdapEventFieldsV0_42 { +pub struct LdapEventFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/malformed_dns.rs b/src/event/malformed_dns.rs index b0de4ffe..6424b565 100644 --- a/src/event/malformed_dns.rs +++ b/src/event/malformed_dns.rs @@ -31,14 +31,19 @@ macro_rules! find_malformed_dns_attr_by_kind { }}; } +pub type BlocklistMalformedDnsFields = BlocklistMalformedDnsFieldsV0_43; + #[derive(Serialize, Deserialize)] -pub struct BlocklistMalformedDnsFields { +pub struct BlocklistMalformedDnsFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, + /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, pub duration: i64, pub orig_pkts: u64, diff --git a/src/event/mqtt.rs b/src/event/mqtt.rs index 2b21f00a..e4a67dad 100644 --- a/src/event/mqtt.rs +++ b/src/event/mqtt.rs @@ -43,14 +43,16 @@ macro_rules! find_mqtt_attr_by_kind { }}; } -pub type BlocklistMqttFields = BlocklistMqttFieldsV0_42; +pub type BlocklistMqttFields = BlocklistMqttFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistMqttFieldsV0_42 { +pub struct BlocklistMqttFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/nfs.rs b/src/event/nfs.rs index 01b39456..9e344261 100644 --- a/src/event/nfs.rs +++ b/src/event/nfs.rs @@ -35,14 +35,16 @@ macro_rules! find_nfs_attr_by_kind { }}; } -pub type BlocklistNfsFields = BlocklistNfsFieldsV0_42; +pub type BlocklistNfsFields = BlocklistNfsFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistNfsFieldsV0_42 { +pub struct BlocklistNfsFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/ntlm.rs b/src/event/ntlm.rs index 9eb406c5..8baab8b6 100644 --- a/src/event/ntlm.rs +++ b/src/event/ntlm.rs @@ -34,14 +34,16 @@ macro_rules! find_ntlm_attr_by_kind { }}; } -pub type BlocklistNtlmFields = BlocklistNtlmFieldsV0_42; +pub type BlocklistNtlmFields = BlocklistNtlmFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistNtlmFieldsV0_42 { +pub struct BlocklistNtlmFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/radius.rs b/src/event/radius.rs index 80a9a346..f778fbe4 100644 --- a/src/event/radius.rs +++ b/src/event/radius.rs @@ -43,14 +43,19 @@ macro_rules! find_radius_attr_by_kind { }}; } +pub type BlocklistRadiusFields = BlocklistRadiusFieldsV0_43; + #[derive(Serialize, Deserialize)] -pub struct BlocklistRadiusFields { +pub struct BlocklistRadiusFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, + /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, pub duration: i64, pub orig_pkts: u64, diff --git a/src/event/rdp.rs b/src/event/rdp.rs index c5af6de8..44d7afbd 100644 --- a/src/event/rdp.rs +++ b/src/event/rdp.rs @@ -35,13 +35,15 @@ macro_rules! find_rdp_attr_by_kind { }}; } -pub type RdpBruteForceFields = RdpBruteForceFieldsV0_42; +pub type RdpBruteForceFields = RdpBruteForceFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct RdpBruteForceFieldsV0_42 { +pub struct RdpBruteForceFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addrs: Vec, + pub dst_country_codes: Vec>, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -180,14 +182,16 @@ impl Match for RdpBruteForce { } } -pub type BlocklistRdpFields = BlocklistRdpFieldsV0_42; +pub type BlocklistRdpFields = BlocklistRdpFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistRdpFieldsV0_42 { +pub struct BlocklistRdpFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/smb.rs b/src/event/smb.rs index 73e7de8b..780ad4f6 100644 --- a/src/event/smb.rs +++ b/src/event/smb.rs @@ -40,14 +40,16 @@ macro_rules! find_smb_attr_by_kind { }}; } -pub type BlocklistSmbFields = BlocklistSmbFieldsV0_42; +pub type BlocklistSmbFields = BlocklistSmbFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistSmbFieldsV0_42 { +pub struct BlocklistSmbFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/smtp.rs b/src/event/smtp.rs index 077aa8de..4728a83c 100644 --- a/src/event/smtp.rs +++ b/src/event/smtp.rs @@ -36,14 +36,16 @@ macro_rules! find_smtp_attr_by_kind { }}; } -pub type BlocklistSmtpFields = BlocklistSmtpFieldsV0_42; +pub type BlocklistSmtpFields = BlocklistSmtpFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistSmtpFieldsV0_42 { +pub struct BlocklistSmtpFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/ssh.rs b/src/event/ssh.rs index bb5ee8bc..535e92f0 100644 --- a/src/event/ssh.rs +++ b/src/event/ssh.rs @@ -44,14 +44,16 @@ macro_rules! find_ssh_attr_by_kind { }}; } -pub type BlocklistSshFields = BlocklistSshFieldsV0_42; +pub type BlocklistSshFields = BlocklistSshFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistSshFieldsV0_42 { +pub struct BlocklistSshFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/tls.rs b/src/event/tls.rs index fb16bc1d..3538f3eb 100644 --- a/src/event/tls.rs +++ b/src/event/tls.rs @@ -68,14 +68,16 @@ macro_rules! find_tls_attr_by_kind { }}; } -pub type BlocklistTlsFields = BlocklistTlsFieldsV0_42; +pub type BlocklistTlsFields = BlocklistTlsFieldsV0_43; #[derive(Serialize, Deserialize)] -pub struct BlocklistTlsFieldsV0_42 { +pub struct BlocklistTlsFieldsV0_43 { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). diff --git a/src/event/tor.rs b/src/event/tor.rs index 6290f825..b19b4811 100644 --- a/src/event/tor.rs +++ b/src/event/tor.rs @@ -349,8 +349,10 @@ mod tests { .unwrap(); BlocklistConnFields { sensor: "test-sensor".to_string(), + src_country_code: None, orig_addr: "192.168.1.100".parse().unwrap(), orig_port: 12345, + dst_country_code: None, resp_addr: "198.51.100.1".parse().unwrap(), resp_port: 443, proto: 6, diff --git a/src/event/unusual_destination_pattern.rs b/src/event/unusual_destination_pattern.rs index f48f7c8e..fe9995cd 100644 --- a/src/event/unusual_destination_pattern.rs +++ b/src/event/unusual_destination_pattern.rs @@ -7,12 +7,17 @@ use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; use crate::event::common::{AttrValue, triage_scores_to_string}; +pub type UnusualDestinationPatternFields = UnusualDestinationPatternFieldsV0_43; + #[derive(Serialize, Deserialize)] -pub struct UnusualDestinationPatternFields { +pub struct UnusualDestinationPatternFieldsV0_43 { pub sensor: String, + /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, + /// Timestamp in nanoseconds since the Unix epoch (UTC). pub end_time: i64, pub destination_ips: Vec, + pub dst_country_codes: Vec>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, diff --git a/src/migrate.rs b/src/migrate.rs index 81c3998e..99e2af25 100644 --- a/src/migrate.rs +++ b/src/migrate.rs @@ -11,7 +11,10 @@ fn main() -> Result<()> { println!("Starting migration process..."); println!("Migrating data directory..."); - migrate_data_dir(&config.data_dir, &config.backup_dir).context("migration failed")?; + // Note: Passing None for the ip2location::DB means country codes will be set to None + // during migration. To resolve country codes from IP addresses, load an ip2location + // database and pass Some(&db) instead. + migrate_data_dir(&config.data_dir, &config.backup_dir, None).context("migration failed")?; Ok(()) } diff --git a/src/migration.rs b/src/migration.rs index e1517fc5..e5e3268d 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -14,7 +14,7 @@ use semver::{Version, VersionReq}; use tracing::info; use crate::{ - AllowNetwork, BlockNetwork, Customer, + AllowNetwork, BlockNetwork, Customer, EventKind, migration::migration_structures::{AllowNetworkV0_42, BlockNetworkV0_42}, tables::NETWORK_TAGS, }; @@ -107,13 +107,28 @@ const COMPATIBLE_VERSION_REQ: &str = ">=0.44.0-alpha.2,<0.44.0-alpha.3"; /// Migration is supported between released versions only. The prelease versions (alpha, beta, /// etc.) should be assumed to be incompatible with each other. /// +/// # Arguments +/// +/// * `data_dir` - Path to the data directory containing the database +/// * `backup_dir` - Path to the backup directory +/// * `locator` - Optional IP geolocation database for resolving country codes during migration. +/// If `None`, country code fields will be set to `None` for migrated records. +/// /// # Errors /// /// Returns an error if the data directory doesn't exist and cannot be created, /// or if the data directory exists but is in the format incompatible with the /// current version. -pub fn migrate_data_dir>(data_dir: P, backup_dir: P) -> Result<()> { - type Migration = (VersionReq, Version, fn(&Path) -> anyhow::Result<()>); +pub fn migrate_data_dir>( + data_dir: P, + backup_dir: P, + locator: Option<&ip2location::DB>, +) -> Result<()> { + type Migration = ( + VersionReq, + Version, + fn(&Path, Option<&ip2location::DB>) -> anyhow::Result<()>, + ); let data_dir = data_dir.as_ref(); let backup_dir = backup_dir.as_ref(); @@ -165,7 +180,7 @@ pub fn migrate_data_dir>(data_dir: P, backup_dir: P) -> Result<() .find(|(req, _to, _m)| req.matches(&version)) { info!("Migrating database to {to}"); - m(data_dir)?; + m(data_dir, locator)?; version = to.clone(); if compatible.matches(&version) { create_version_file(&backup).context("failed to update VERSION")?; @@ -225,7 +240,7 @@ fn map_names_v0_42_without_account_policy() -> Vec<&'static str> { .collect() } -fn migrate_0_42_to_0_43(data_dir: &Path) -> Result<()> { +fn migrate_0_42_to_0_43(data_dir: &Path, locator: Option<&ip2location::DB>) -> Result<()> { let db_path = data_dir.join("states.db"); // Step 1: Drop "account policy" column family if it exists (from 0.42) @@ -240,13 +255,18 @@ fn migrate_0_42_to_0_43(data_dir: &Path) -> Result<()> { Ok(()) } -fn migrate_0_43_to_0_44(data_dir: &Path) -> Result<()> { - // Migrate network tags to customer-scoped format +fn migrate_0_43_to_0_44(data_dir: &Path, locator: Option<&ip2location::DB>) -> Result<()> { + let db_path = data_dir.join("states.db"); + + // Step 1: Migrate network tags to customer-scoped format migrate_network_tags_to_customer_scoped(data_dir)?; - // Migrate Network table to enforce global name uniqueness + // Step 2: Migrate Network table to enforce global name uniqueness migrate_network_cf(data_dir)?; + // Step 3: Migrate event fields to add country codes + migrate_event_country_codes(&db_path, locator)?; + Ok(()) } @@ -825,6 +845,291 @@ fn migrate_network_cf_inner( Ok(()) } +/// Migrates event fields from `V0_43` format (without country codes) to `V0_44` format +/// (with country codes). If a locator is provided, country codes are resolved from +/// IP addresses. Otherwise, country codes are set to None. +fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB>) -> Result<()> { + use num_traits::FromPrimitive; + + use crate::event::{ + BlocklistBootpFields, BlocklistConnFields, BlocklistDceRpcFields, BlocklistDhcpFields, + BlocklistDnsFields, BlocklistKerberosFields, BlocklistMalformedDnsFields, + BlocklistMqttFields, BlocklistNfsFields, BlocklistNtlmFields, BlocklistRadiusFields, + BlocklistRdpFields, BlocklistSmbFields, BlocklistSmtpFields, BlocklistSshFields, + BlocklistTlsFields, CryptocurrencyMiningPoolFields, DgaFields, DnsEventFields, + ExternalDdosFields, FtpBruteForceFields, FtpEventFields, HttpEventFields, HttpThreatFields, + LdapBruteForceFields, LdapEventFields, MultiHostPortScanFields, PortScanFields, + RdpBruteForceFields, RepeatedHttpSessionsFields, UnusualDestinationPatternFields, + }; + use crate::migration::migration_structures::{ + BlocklistBootpFieldsV0_43, BlocklistConnFieldsV0_43, BlocklistDceRpcFieldsV0_43, + BlocklistDhcpFieldsV0_43, BlocklistDnsFieldsV0_43, BlocklistKerberosFieldsV0_43, + BlocklistMalformedDnsFieldsV0_43, BlocklistMqttFieldsV0_43, BlocklistNfsFieldsV0_43, + BlocklistNtlmFieldsV0_43, BlocklistRadiusFieldsV0_43, BlocklistRdpFieldsV0_43, + BlocklistSmbFieldsV0_43, BlocklistSmtpFieldsV0_43, BlocklistSshFieldsV0_43, + BlocklistTlsFieldsV0_43, CryptocurrencyMiningPoolFieldsV0_43, DgaFieldsV0_43, + DnsEventFieldsV0_43, ExternalDdosFieldsV0_43, FtpBruteForceFieldsV0_43, + FtpEventFieldsV0_43, HttpEventFieldsV0_43, HttpThreatFieldsV0_43, + LdapBruteForceFieldsV0_43, LdapEventFieldsV0_43, MultiHostPortScanFieldsV0_43, + PortScanFieldsV0_43, RdpBruteForceFieldsV0_43, RepeatedHttpSessionsFieldsV0_43, + UnusualDestinationPatternFieldsV0_43, + }; + + info!("Migrating event fields to add country codes"); + + let mut opts = rocksdb::Options::default(); + opts.create_if_missing(false); + opts.create_missing_column_families(false); + + let db: rocksdb::OptimisticTransactionDB = + rocksdb::OptimisticTransactionDB::open_cf(&opts, db_path, crate::tables::MAP_NAMES) + .context("Failed to open database for event migration")?; + + // Collect all events that need migration + // Events are stored in the default column family + let entries_to_migrate: Vec<(Vec, Vec)> = db + .iterator(rocksdb::IteratorMode::Start) + .filter_map(|item| match item { + Ok((key, value)) => Some((key.to_vec(), value.to_vec())), + Err(_) => None, + }) + .collect(); + + if entries_to_migrate.is_empty() { + info!("No events to migrate"); + return Ok(()); + } + + info!("Found {} events to migrate", entries_to_migrate.len()); + + let txn = db.transaction(); + let mut migrated_count = 0usize; + let mut skipped_count = 0usize; + + for (key, value) in &entries_to_migrate { + // Deserialize the EventMessage wrapper + let event_msg: crate::EventMessage = + if let Ok(msg) = bincode::DefaultOptions::new().deserialize(value) { + msg + } else { + skipped_count += 1; + continue; + }; + + // Extract the event kind from the key (bits 32-63 of the 128-bit key) + let kind_value = if key.len() >= 16 { + let key_i128 = i128::from_be_bytes(key[..16].try_into().unwrap_or([0; 16])); + ((key_i128 >> 32) & 0xFFFF_FFFF) as i32 + } else { + skipped_count += 1; + continue; + }; + + let Some(kind) = EventKind::from_i32(kind_value) else { + skipped_count += 1; + continue; + }; + + // Migrate the fields based on event kind + let new_fields: Vec = match kind { + EventKind::DnsCovertChannel | EventKind::LockyRansomware => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::HttpThreat => migrate_fields::( + &event_msg.fields, + locator, + )?, + EventKind::RdpBruteForce => migrate_fields::< + RdpBruteForceFieldsV0_43, + RdpBruteForceFields, + >(&event_msg.fields, locator)?, + EventKind::RepeatedHttpSessions => migrate_fields::< + RepeatedHttpSessionsFieldsV0_43, + RepeatedHttpSessionsFields, + >(&event_msg.fields, locator)?, + EventKind::TorConnection | EventKind::NonBrowser | EventKind::BlocklistHttp => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::TorConnectionConn | EventKind::BlocklistConn => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::DomainGenerationAlgorithm => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::FtpBruteForce => migrate_fields::< + FtpBruteForceFieldsV0_43, + FtpBruteForceFields, + >(&event_msg.fields, locator)?, + EventKind::FtpPlainText | EventKind::BlocklistFtp => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::PortScan => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::MultiHostPortScan => migrate_fields::< + MultiHostPortScanFieldsV0_43, + MultiHostPortScanFields, + >(&event_msg.fields, locator)?, + EventKind::ExternalDdos => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::LdapBruteForce => migrate_fields::< + LdapBruteForceFieldsV0_43, + LdapBruteForceFields, + >(&event_msg.fields, locator)?, + EventKind::LdapPlainText | EventKind::BlocklistLdap => { + migrate_fields::(&event_msg.fields, locator)? + } + EventKind::CryptocurrencyMiningPool => migrate_fields::< + CryptocurrencyMiningPoolFieldsV0_43, + CryptocurrencyMiningPoolFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistBootp => migrate_fields::< + BlocklistBootpFieldsV0_43, + BlocklistBootpFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistDceRpc => migrate_fields::< + BlocklistDceRpcFieldsV0_43, + BlocklistDceRpcFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistDhcp => migrate_fields::< + BlocklistDhcpFieldsV0_43, + BlocklistDhcpFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistDns => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::BlocklistKerberos => migrate_fields::< + BlocklistKerberosFieldsV0_43, + BlocklistKerberosFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistMalformedDns => migrate_fields::< + BlocklistMalformedDnsFieldsV0_43, + BlocklistMalformedDnsFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistMqtt => migrate_fields::< + BlocklistMqttFieldsV0_43, + BlocklistMqttFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistNfs => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::BlocklistNtlm => migrate_fields::< + BlocklistNtlmFieldsV0_43, + BlocklistNtlmFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistRadius => migrate_fields::< + BlocklistRadiusFieldsV0_43, + BlocklistRadiusFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistRdp => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::BlocklistSmb => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::BlocklistSmtp => migrate_fields::< + BlocklistSmtpFieldsV0_43, + BlocklistSmtpFields, + >(&event_msg.fields, locator)?, + EventKind::BlocklistSsh => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::BlocklistTls | EventKind::SuspiciousTlsTraffic => { + migrate_fields::( + &event_msg.fields, + locator, + )? + } + EventKind::UnusualDestinationPattern => migrate_fields::< + UnusualDestinationPatternFieldsV0_43, + UnusualDestinationPatternFields, + >(&event_msg.fields, locator)?, + // These event types don't have country code fields or use different structures + EventKind::WindowsThreat | EventKind::NetworkThreat | EventKind::ExtraThreat => { + // Skip migration for these types - they don't have the standard + // orig_addr/resp_addr fields or use different serialization + skipped_count += 1; + continue; + } + }; + + // Create new EventMessage with migrated fields + let new_event_msg = crate::EventMessage { + time: event_msg.time, + kind: event_msg.kind, + fields: new_fields, + }; + + // Serialize and update + let new_value = bincode::DefaultOptions::new() + .serialize(&new_event_msg) + .context("failed to serialize migrated event")?; + txn.put(key, &new_value) + .context("failed to update migrated event")?; + migrated_count += 1; + } + + txn.commit().context("failed to commit event migration")?; + info!( + "Successfully migrated {} events ({} skipped)", + migrated_count, skipped_count + ); + Ok(()) +} + +/// Helper function to migrate event fields from old format to new format +fn migrate_fields(old_data: &[u8], _locator: Option<&ip2location::DB>) -> Result> +where + O: serde::de::DeserializeOwned, + N: serde::Serialize + serde::de::DeserializeOwned + From, +{ + // First try to deserialize as the new format (already migrated) + if bincode::DefaultOptions::new() + .deserialize::(old_data) + .is_ok() + { + // Already in new format, no migration needed + return Ok(old_data.to_vec()); + } + + // Deserialize as old format and convert + let old_fields: O = bincode::DefaultOptions::new() + .deserialize(old_data) + .context("failed to deserialize old event fields")?; + + let new_fields: N = old_fields.into(); + + // Note: Country code resolution from locator is handled by the From trait. + // Currently, From implementations set country codes to None. + // To enable IP-based resolution, the From traits would need to accept the locator. + + bincode::DefaultOptions::new() + .serialize(&new_fields) + .context("failed to serialize new event fields") +} + /// Recursively creates `path` if not existed, creates the VERSION file /// under `path` if missing with current version number. Returns VERSION /// file path with VERSION number written on file. diff --git a/src/migration/migration_structures.rs b/src/migration/migration_structures.rs index 1f8c4bdf..e9e32b7e 100644 --- a/src/migration/migration_structures.rs +++ b/src/migration/migration_structures.rs @@ -4,12 +4,14 @@ //! and must not be modified. They are used to migrate data from //! old formats to new formats. +use std::net::IpAddr; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::PeriodForSearch; use crate::event::{FilterEndpoint, FlowKind, LearningMethod}; -use crate::types::HostNetworkGroup; +use crate::types::{EventCategory, HostNetworkGroup}; /// Filter value structure from version 0.41.x /// @@ -104,3 +106,1790 @@ pub(crate) struct NetworkValueV0_43 { pub(crate) tag_ids: Vec, pub(crate) creation_time: DateTime, } + +// ============================================================================= +// Event Fields V0_42 structures (before src_country_code/dst_country_code) +// These structs represent event field schemas from version 0.42.x without +// country code fields. From 0.43.x, country code fields were added. +// ============================================================================= + +/// FTP Command structure for `V0_42` migration +#[derive(Clone, Deserialize, Serialize)] +pub(crate) struct FtpCommandV0_42 { + pub command: String, + pub reply_code: String, + pub reply_msg: String, +} + +/// Port scan fields from version 0.42.x (before country codes were added) +#[derive(Serialize, Deserialize)] +pub(crate) struct PortScanFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub resp_addr: IpAddr, + pub resp_ports: Vec, + pub start_time: i64, + pub end_time: i64, + pub proto: u8, + pub confidence: f32, + pub category: Option, +} + +/// Multi-host port scan fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct MultiHostPortScanFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub resp_port: u16, + pub resp_addrs: Vec, + pub proto: u8, + pub start_time: i64, + pub end_time: i64, + pub confidence: f32, + pub category: Option, +} + +/// External `DDoS` fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct ExternalDdosFieldsV0_42 { + pub sensor: String, + pub orig_addrs: Vec, + pub resp_addr: IpAddr, + pub proto: u8, + pub start_time: i64, + pub end_time: i64, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist connection fields from version 0.42.x +#[derive(Deserialize, Serialize)] +pub(crate) struct BlocklistConnFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub conn_state: String, + pub start_time: i64, + pub duration: i64, + pub service: String, + pub orig_bytes: u64, + pub resp_bytes: u64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub confidence: f32, + pub category: Option, +} + +/// DNS event fields from version 0.42.x +#[allow(clippy::struct_excessive_bools)] +#[derive(Deserialize, Serialize)] +pub(crate) struct DnsEventFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub query: String, + pub answer: Vec, + pub trans_id: u16, + pub rtt: i64, + pub qclass: u16, + pub qtype: u16, + pub rcode: u16, + pub aa_flag: bool, + pub tc_flag: bool, + pub rd_flag: bool, + pub ra_flag: bool, + pub ttl: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Cryptocurrency mining pool fields from version 0.42.x +#[allow(clippy::struct_excessive_bools)] +#[derive(Deserialize, Serialize)] +pub(crate) struct CryptocurrencyMiningPoolFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub query: String, + pub answer: Vec, + pub trans_id: u16, + pub rtt: i64, + pub qclass: u16, + pub qtype: u16, + pub rcode: u16, + pub aa_flag: bool, + pub tc_flag: bool, + pub rd_flag: bool, + pub ra_flag: bool, + pub ttl: Vec, + pub coins: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist DNS fields from version 0.42.x +#[allow(clippy::struct_excessive_bools)] +#[derive(Deserialize, Serialize)] +pub(crate) struct BlocklistDnsFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub query: String, + pub answer: Vec, + pub trans_id: u16, + pub rtt: i64, + pub qclass: u16, + pub qtype: u16, + pub rcode: u16, + pub aa_flag: bool, + pub tc_flag: bool, + pub rd_flag: bool, + pub ra_flag: bool, + pub ttl: Vec, + pub confidence: f32, + pub category: Option, +} + +/// HTTP event fields from version 0.42.x +#[derive(Deserialize, Serialize)] +pub(crate) struct HttpEventFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub method: String, + pub host: String, + pub uri: String, + pub referer: String, + pub version: String, + pub user_agent: String, + pub request_len: usize, + pub response_len: usize, + pub status_code: u16, + pub status_msg: String, + pub username: String, + pub password: String, + pub cookie: String, + pub content_encoding: String, + pub content_type: String, + pub cache_control: String, + pub filenames: Vec, + pub mime_types: Vec, + pub body: Vec, + pub state: String, + pub confidence: f32, + pub category: Option, +} + +/// Repeated HTTP sessions fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct RepeatedHttpSessionsFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub end_time: i64, + pub confidence: f32, + pub category: Option, +} + +/// HTTP threat fields from version 0.42.x +#[derive(Deserialize, Serialize)] +pub(crate) struct HttpThreatFieldsV0_42 { + #[serde(with = "chrono::serde::ts_nanoseconds")] + pub time: DateTime, + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub method: String, + pub host: String, + pub uri: String, + pub referer: String, + pub version: String, + pub user_agent: String, + pub request_len: usize, + pub response_len: usize, + pub status_code: u16, + pub status_msg: String, + pub username: String, + pub password: String, + pub cookie: String, + pub content_encoding: String, + pub content_type: String, + pub cache_control: String, + pub filenames: Vec, + pub mime_types: Vec, + pub body: Vec, + pub state: String, + pub db_name: String, + pub rule_id: u32, + pub matched_to: String, + pub cluster_id: Option, + pub attack_kind: String, + pub confidence: f32, + pub category: Option, +} + +/// DGA fields from version 0.42.x +#[derive(Deserialize, Serialize)] +pub(crate) struct DgaFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub method: String, + pub host: String, + pub uri: String, + pub referer: String, + pub version: String, + pub user_agent: String, + pub request_len: usize, + pub response_len: usize, + pub status_code: u16, + pub status_msg: String, + pub username: String, + pub password: String, + pub cookie: String, + pub content_encoding: String, + pub content_type: String, + pub cache_control: String, + pub filenames: Vec, + pub mime_types: Vec, + pub body: Vec, + pub state: String, + pub confidence: f32, + pub category: Option, +} + +/// RDP brute force fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct RdpBruteForceFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub resp_addrs: Vec, + pub start_time: i64, + pub end_time: i64, + pub proto: u8, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist RDP fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistRdpFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub cookie: String, + pub confidence: f32, + pub category: Option, +} + +/// FTP brute force fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct FtpBruteForceFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub user_list: Vec, + pub start_time: i64, + pub end_time: i64, + pub is_internal: bool, + pub confidence: f32, + pub category: Option, +} + +/// FTP event fields from version 0.42.x +#[derive(Deserialize, Serialize)] +pub(crate) struct FtpEventFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub user: String, + pub password: String, + pub commands: Vec, + pub confidence: f32, + pub category: Option, +} + +/// LDAP brute force fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct LdapBruteForceFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub user_pw_list: Vec<(String, String)>, + pub start_time: i64, + pub end_time: i64, + pub confidence: f32, + pub category: Option, +} + +/// LDAP event fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct LdapEventFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub message_id: u32, + pub version: u8, + pub opcode: Vec, + pub result: Vec, + pub diagnostic_message: Vec, + pub object: Vec, + pub argument: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist SSH fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistSshFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub client: String, + pub server: String, + pub cipher_alg: String, + pub mac_alg: String, + pub compression_alg: String, + pub kex_alg: String, + pub host_key_alg: String, + pub hassh_algorithms: String, + pub hassh: String, + pub hassh_server_algorithms: String, + pub hassh_server: String, + pub client_shka: String, + pub server_shka: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist TLS fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistTlsFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub server_name: String, + pub alpn_protocol: String, + pub ja3: String, + pub version: String, + pub client_cipher_suites: Vec, + pub client_extensions: Vec, + pub cipher: u16, + pub extensions: Vec, + pub ja3s: String, + pub serial: String, + pub subject_country: String, + pub subject_org_name: String, + pub subject_common_name: String, + pub validity_not_before: i64, + pub validity_not_after: i64, + pub subject_alt_name: String, + pub issuer_country: String, + pub issuer_org_name: String, + pub issuer_org_unit_name: String, + pub issuer_common_name: String, + pub last_alert: u8, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist Kerberos fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistKerberosFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub client_time: i64, + pub server_time: i64, + pub error_code: u32, + pub client_realm: String, + pub cname_type: u8, + pub client_name: Vec, + pub realm: String, + pub sname_type: u8, + pub service_name: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist SMTP fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistSmtpFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub mailfrom: String, + pub date: String, + pub from: String, + pub to: String, + pub subject: String, + pub agent: String, + pub state: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist NFS fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistNfsFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub read_files: Vec, + pub write_files: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist DHCP fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistDhcpFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub msg_type: u8, + pub ciaddr: IpAddr, + pub yiaddr: IpAddr, + pub siaddr: IpAddr, + pub giaddr: IpAddr, + pub subnet_mask: IpAddr, + pub router: Vec, + pub domain_name_server: Vec, + pub req_ip_addr: IpAddr, + pub lease_time: u32, + pub server_id: IpAddr, + pub param_req_list: Vec, + pub message: String, + pub renewal_time: u32, + pub rebinding_time: u32, + pub class_id: Vec, + pub client_id_type: u8, + pub client_id: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist DCE-RPC fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistDceRpcFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub rtt: i64, + pub named_pipe: String, + pub endpoint: String, + pub operation: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist NTLM fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistNtlmFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub protocol: String, + pub username: String, + pub hostname: String, + pub domainname: String, + pub success: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist SMB fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistSmbFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub command: u8, + pub path: String, + pub service: String, + pub file_name: String, + pub file_size: u64, + pub resource_type: u16, + pub fid: u16, + pub create_time: i64, + pub access_time: i64, + pub write_time: i64, + pub change_time: i64, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist MQTT fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistMqttFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub protocol: String, + pub version: u8, + pub client_id: String, + pub connack_reason: u8, + pub subscribe: Vec, + pub suback_reason: Vec, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist BOOTP fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistBootpFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub op: u8, + pub htype: u8, + pub hops: u8, + pub xid: u32, + pub ciaddr: IpAddr, + pub yiaddr: IpAddr, + pub siaddr: IpAddr, + pub giaddr: IpAddr, + pub chaddr: Vec, + pub sname: String, + pub file: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist Radius fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistRadiusFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub id: u8, + pub code: u8, + pub resp_code: u8, + pub auth: String, + pub resp_auth: String, + pub user_name: Vec, + pub user_passwd: Vec, + pub chap_passwd: Vec, + pub nas_ip: IpAddr, + pub nas_port: u32, + pub state: Vec, + pub nas_id: Vec, + pub nas_port_type: u32, + pub message: String, + pub confidence: f32, + pub category: Option, +} + +/// Blocklist malformed DNS fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct BlocklistMalformedDnsFieldsV0_42 { + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub start_time: i64, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub trans_id: u16, + pub flags: u16, + pub question_count: u16, + pub answer_count: u16, + pub authority_count: u16, + pub additional_count: u16, + pub query_count: u32, + pub resp_count: u32, + pub query_bytes: u64, + pub resp_bytes: u64, + pub query_body: Vec>, + pub resp_body: Vec>, + pub confidence: f32, + pub category: Option, +} + +/// Unusual destination pattern fields from version 0.42.x +#[derive(Serialize, Deserialize)] +pub(crate) struct UnusualDestinationPatternFieldsV0_42 { + pub sensor: String, + pub start_time: i64, + pub end_time: i64, + pub destination_ips: Vec, + pub count: usize, + pub expected_mean: f64, + pub std_deviation: f64, + pub z_score: f64, + pub confidence: f32, + pub category: Option, +} + +// ============================================================================= +// From trait implementations for V0_42 -> V0_43 conversions +// These enable migrating old event fields to new format with country codes +// ============================================================================= + +use crate::event::ExternalDdosFields; +use crate::event::{ + BlocklistBootpFields, BlocklistConnFields, BlocklistDceRpcFields, BlocklistDhcpFields, + BlocklistDnsFields, BlocklistKerberosFields, BlocklistMalformedDnsFields, BlocklistMqttFields, + BlocklistNfsFields, BlocklistNtlmFields, BlocklistRadiusFields, BlocklistRdpFields, + BlocklistSmbFields, BlocklistSmtpFields, BlocklistSshFields, BlocklistTlsFields, + CryptocurrencyMiningPoolFields, DgaFields, DnsEventFields, FtpBruteForceFields, FtpCommand, + FtpEventFields, HttpEventFields, HttpThreatFields, LdapBruteForceFields, LdapEventFields, + MultiHostPortScanFields, PortScanFields, RdpBruteForceFields, RepeatedHttpSessionsFields, + UnusualDestinationPatternFields, +}; + +impl From for PortScanFields { + fn from(old: PortScanFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_ports: old.resp_ports, + start_time: old.start_time, + end_time: old.end_time, + proto: old.proto, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for MultiHostPortScanFields { + fn from(old: MultiHostPortScanFieldsV0_42) -> Self { + let dst_country_codes = vec![None; old.resp_addrs.len()]; + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + resp_port: old.resp_port, + resp_addrs: old.resp_addrs, + dst_country_codes, + proto: old.proto, + start_time: old.start_time, + end_time: old.end_time, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for ExternalDdosFields { + fn from(old: ExternalDdosFieldsV0_42) -> Self { + let src_country_codes = vec![None; old.orig_addrs.len()]; + Self { + sensor: old.sensor, + orig_addrs: old.orig_addrs, + src_country_codes, + resp_addr: old.resp_addr, + dst_country_code: None, + proto: old.proto, + start_time: old.start_time, + end_time: old.end_time, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistConnFields { + fn from(old: BlocklistConnFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + conn_state: old.conn_state, + start_time: old.start_time, + duration: old.duration, + service: old.service, + orig_bytes: old.orig_bytes, + resp_bytes: old.resp_bytes, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for DnsEventFields { + fn from(old: DnsEventFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + query: old.query, + answer: old.answer, + trans_id: old.trans_id, + rtt: old.rtt, + qclass: old.qclass, + qtype: old.qtype, + rcode: old.rcode, + aa_flag: old.aa_flag, + tc_flag: old.tc_flag, + rd_flag: old.rd_flag, + ra_flag: old.ra_flag, + ttl: old.ttl, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for CryptocurrencyMiningPoolFields { + fn from(old: CryptocurrencyMiningPoolFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + query: old.query, + answer: old.answer, + trans_id: old.trans_id, + rtt: old.rtt, + qclass: old.qclass, + qtype: old.qtype, + rcode: old.rcode, + aa_flag: old.aa_flag, + tc_flag: old.tc_flag, + rd_flag: old.rd_flag, + ra_flag: old.ra_flag, + ttl: old.ttl, + coins: old.coins, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistDnsFields { + fn from(old: BlocklistDnsFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + query: old.query, + answer: old.answer, + trans_id: old.trans_id, + rtt: old.rtt, + qclass: old.qclass, + qtype: old.qtype, + rcode: old.rcode, + aa_flag: old.aa_flag, + tc_flag: old.tc_flag, + rd_flag: old.rd_flag, + ra_flag: old.ra_flag, + ttl: old.ttl, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for HttpEventFields { + fn from(old: HttpEventFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + method: old.method, + host: old.host, + uri: old.uri, + referer: old.referer, + version: old.version, + user_agent: old.user_agent, + request_len: old.request_len, + response_len: old.response_len, + status_code: old.status_code, + status_msg: old.status_msg, + username: old.username, + password: old.password, + cookie: old.cookie, + content_encoding: old.content_encoding, + content_type: old.content_type, + cache_control: old.cache_control, + filenames: old.filenames, + mime_types: old.mime_types, + body: old.body, + state: old.state, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for RepeatedHttpSessionsFields { + fn from(old: RepeatedHttpSessionsFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + end_time: old.end_time, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for HttpThreatFields { + fn from(old: HttpThreatFieldsV0_42) -> Self { + Self { + time: old.time, + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + method: old.method, + host: old.host, + uri: old.uri, + referer: old.referer, + version: old.version, + user_agent: old.user_agent, + request_len: old.request_len, + response_len: old.response_len, + status_code: old.status_code, + status_msg: old.status_msg, + username: old.username, + password: old.password, + cookie: old.cookie, + content_encoding: old.content_encoding, + content_type: old.content_type, + cache_control: old.cache_control, + filenames: old.filenames, + mime_types: old.mime_types, + body: old.body, + state: old.state, + db_name: old.db_name, + rule_id: old.rule_id, + matched_to: old.matched_to, + cluster_id: old.cluster_id, + attack_kind: old.attack_kind, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for DgaFields { + fn from(old: DgaFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + method: old.method, + host: old.host, + uri: old.uri, + referer: old.referer, + version: old.version, + user_agent: old.user_agent, + request_len: old.request_len, + response_len: old.response_len, + status_code: old.status_code, + status_msg: old.status_msg, + username: old.username, + password: old.password, + cookie: old.cookie, + content_encoding: old.content_encoding, + content_type: old.content_type, + cache_control: old.cache_control, + filenames: old.filenames, + mime_types: old.mime_types, + body: old.body, + state: old.state, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for RdpBruteForceFields { + fn from(old: RdpBruteForceFieldsV0_42) -> Self { + let dst_country_codes = vec![None; old.resp_addrs.len()]; + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + resp_addrs: old.resp_addrs, + dst_country_codes, + start_time: old.start_time, + end_time: old.end_time, + proto: old.proto, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistRdpFields { + fn from(old: BlocklistRdpFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + cookie: old.cookie, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for FtpBruteForceFields { + fn from(old: FtpBruteForceFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + user_list: old.user_list, + start_time: old.start_time, + end_time: old.end_time, + is_internal: old.is_internal, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for FtpCommand { + fn from(old: FtpCommandV0_42) -> Self { + use std::net::{IpAddr, Ipv4Addr}; + Self { + command: old.command, + reply_code: old.reply_code, + reply_msg: old.reply_msg, + // New fields added after V0_42 - use sensible defaults + data_passive: false, + data_orig_addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), + data_resp_addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), + data_resp_port: 0, + file: String::new(), + file_size: 0, + file_id: String::new(), + } + } +} + +impl From for FtpEventFields { + fn from(old: FtpEventFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + user: old.user, + password: old.password, + commands: old.commands.into_iter().map(Into::into).collect(), + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for LdapBruteForceFields { + fn from(old: LdapBruteForceFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + user_pw_list: old.user_pw_list, + start_time: old.start_time, + end_time: old.end_time, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for LdapEventFields { + fn from(old: LdapEventFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + message_id: old.message_id, + version: old.version, + opcode: old.opcode, + result: old.result, + diagnostic_message: old.diagnostic_message, + object: old.object, + argument: old.argument, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistSshFields { + fn from(old: BlocklistSshFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + client: old.client, + server: old.server, + cipher_alg: old.cipher_alg, + mac_alg: old.mac_alg, + compression_alg: old.compression_alg, + kex_alg: old.kex_alg, + host_key_alg: old.host_key_alg, + hassh_algorithms: old.hassh_algorithms, + hassh: old.hassh, + hassh_server_algorithms: old.hassh_server_algorithms, + hassh_server: old.hassh_server, + client_shka: old.client_shka, + server_shka: old.server_shka, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistTlsFields { + fn from(old: BlocklistTlsFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + server_name: old.server_name, + alpn_protocol: old.alpn_protocol, + ja3: old.ja3, + version: old.version, + client_cipher_suites: old.client_cipher_suites, + client_extensions: old.client_extensions, + cipher: old.cipher, + extensions: old.extensions, + ja3s: old.ja3s, + serial: old.serial, + subject_country: old.subject_country, + subject_org_name: old.subject_org_name, + subject_common_name: old.subject_common_name, + validity_not_before: old.validity_not_before, + validity_not_after: old.validity_not_after, + subject_alt_name: old.subject_alt_name, + issuer_country: old.issuer_country, + issuer_org_name: old.issuer_org_name, + issuer_org_unit_name: old.issuer_org_unit_name, + issuer_common_name: old.issuer_common_name, + last_alert: old.last_alert, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistKerberosFields { + fn from(old: BlocklistKerberosFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + client_time: old.client_time, + server_time: old.server_time, + error_code: old.error_code, + client_realm: old.client_realm, + cname_type: old.cname_type, + client_name: old.client_name, + realm: old.realm, + sname_type: old.sname_type, + service_name: old.service_name, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistSmtpFields { + fn from(old: BlocklistSmtpFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + mailfrom: old.mailfrom, + date: old.date, + from: old.from, + to: old.to, + subject: old.subject, + agent: old.agent, + state: old.state, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistNfsFields { + fn from(old: BlocklistNfsFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + read_files: old.read_files, + write_files: old.write_files, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistDhcpFields { + fn from(old: BlocklistDhcpFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + msg_type: old.msg_type, + ciaddr: old.ciaddr, + yiaddr: old.yiaddr, + siaddr: old.siaddr, + giaddr: old.giaddr, + subnet_mask: old.subnet_mask, + router: old.router, + domain_name_server: old.domain_name_server, + req_ip_addr: old.req_ip_addr, + lease_time: old.lease_time, + server_id: old.server_id, + param_req_list: old.param_req_list, + message: old.message, + renewal_time: old.renewal_time, + rebinding_time: old.rebinding_time, + class_id: old.class_id, + client_id_type: old.client_id_type, + client_id: old.client_id, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistDceRpcFields { + fn from(old: BlocklistDceRpcFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + rtt: old.rtt, + named_pipe: old.named_pipe, + endpoint: old.endpoint, + operation: old.operation, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistNtlmFields { + fn from(old: BlocklistNtlmFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + protocol: old.protocol, + username: old.username, + hostname: old.hostname, + domainname: old.domainname, + success: old.success, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistSmbFields { + fn from(old: BlocklistSmbFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + command: old.command, + path: old.path, + service: old.service, + file_name: old.file_name, + file_size: old.file_size, + resource_type: old.resource_type, + fid: old.fid, + create_time: old.create_time, + access_time: old.access_time, + write_time: old.write_time, + change_time: old.change_time, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistMqttFields { + fn from(old: BlocklistMqttFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + protocol: old.protocol, + version: old.version, + client_id: old.client_id, + connack_reason: old.connack_reason, + subscribe: old.subscribe, + suback_reason: old.suback_reason, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistBootpFields { + fn from(old: BlocklistBootpFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + op: old.op, + htype: old.htype, + hops: old.hops, + xid: old.xid, + ciaddr: old.ciaddr, + yiaddr: old.yiaddr, + siaddr: old.siaddr, + giaddr: old.giaddr, + chaddr: old.chaddr, + sname: old.sname, + file: old.file, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistRadiusFields { + fn from(old: BlocklistRadiusFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + id: old.id, + code: old.code, + resp_code: old.resp_code, + auth: old.auth, + resp_auth: old.resp_auth, + user_name: old.user_name, + user_passwd: old.user_passwd, + chap_passwd: old.chap_passwd, + nas_ip: old.nas_ip, + nas_port: old.nas_port, + state: old.state, + nas_id: old.nas_id, + nas_port_type: old.nas_port_type, + message: old.message, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for BlocklistMalformedDnsFields { + fn from(old: BlocklistMalformedDnsFieldsV0_42) -> Self { + Self { + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + trans_id: old.trans_id, + flags: old.flags, + question_count: old.question_count, + answer_count: old.answer_count, + authority_count: old.authority_count, + additional_count: old.additional_count, + query_count: old.query_count, + resp_count: old.resp_count, + query_bytes: old.query_bytes, + resp_bytes: old.resp_bytes, + query_body: old.query_body, + resp_body: old.resp_body, + confidence: old.confidence, + category: old.category, + } + } +} + +impl From for UnusualDestinationPatternFields { + fn from(old: UnusualDestinationPatternFieldsV0_42) -> Self { + let dst_country_codes = vec![None; old.destination_ips.len()]; + Self { + sensor: old.sensor, + start_time: old.start_time, + end_time: old.end_time, + destination_ips: old.destination_ips, + dst_country_codes, + count: old.count, + expected_mean: old.expected_mean, + std_deviation: old.std_deviation, + z_score: old.z_score, + confidence: old.confidence, + category: old.category, + } + } +} From 2f9b215a3e50d82e868e06f527839724f5670af1 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:27:43 +0000 Subject: [PATCH 02/12] Implement country code resolution in migration --- src/migration.rs | 292 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 276 insertions(+), 16 deletions(-) diff --git a/src/migration.rs b/src/migration.rs index e5e3268d..6ee1f583 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -5,6 +5,7 @@ mod migration_structures; use std::{ fs::{File, create_dir_all}, io::{Read, Write}, + net::IpAddr, path::{Path, PathBuf}, }; @@ -851,16 +852,6 @@ fn migrate_network_cf_inner( fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB>) -> Result<()> { use num_traits::FromPrimitive; - use crate::event::{ - BlocklistBootpFields, BlocklistConnFields, BlocklistDceRpcFields, BlocklistDhcpFields, - BlocklistDnsFields, BlocklistKerberosFields, BlocklistMalformedDnsFields, - BlocklistMqttFields, BlocklistNfsFields, BlocklistNtlmFields, BlocklistRadiusFields, - BlocklistRdpFields, BlocklistSmbFields, BlocklistSmtpFields, BlocklistSshFields, - BlocklistTlsFields, CryptocurrencyMiningPoolFields, DgaFields, DnsEventFields, - ExternalDdosFields, FtpBruteForceFields, FtpEventFields, HttpEventFields, HttpThreatFields, - LdapBruteForceFields, LdapEventFields, MultiHostPortScanFields, PortScanFields, - RdpBruteForceFields, RepeatedHttpSessionsFields, UnusualDestinationPatternFields, - }; use crate::migration::migration_structures::{ BlocklistBootpFieldsV0_43, BlocklistConnFieldsV0_43, BlocklistDceRpcFieldsV0_43, BlocklistDhcpFieldsV0_43, BlocklistDnsFieldsV0_43, BlocklistKerberosFieldsV0_43, @@ -1099,11 +1090,279 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> Ok(()) } +/// Trait for applying country code resolution to migrated event fields. +/// +/// Types implementing this trait can have their country code fields populated +/// from IP addresses using an ip2location database. +trait ResolveCountryCodes { + /// Resolves country codes from IP addresses using the provided locator. + fn resolve_country_codes(&mut self, locator: &ip2location::DB); +} + +/// Converts a country code string to a 2-byte array. +/// Returns `None` if the lookup fails or returns "XX" (unknown). +fn country_code_to_bytes(locator: &ip2location::DB, addr: IpAddr) -> Option<[u8; 2]> { + let code = crate::util::find_ip_country(locator, addr); + if code == "XX" || code.len() != 2 { + None + } else { + let bytes = code.as_bytes(); + Some([bytes[0], bytes[1]]) + } +} + +// ============================================================================= +// ResolveCountryCodes implementations for event field types +// ============================================================================= + +use crate::event::{ + BlocklistBootpFields, BlocklistConnFields, BlocklistDceRpcFields, BlocklistDhcpFields, + BlocklistDnsFields, BlocklistKerberosFields, BlocklistMalformedDnsFields, BlocklistMqttFields, + BlocklistNfsFields, BlocklistNtlmFields, BlocklistRadiusFields, BlocklistRdpFields, + BlocklistSmbFields, BlocklistSmtpFields, BlocklistSshFields, BlocklistTlsFields, + CryptocurrencyMiningPoolFields, DgaFields, DnsEventFields, ExternalDdosFields, + FtpBruteForceFields, FtpEventFields, HttpEventFields, HttpThreatFields, LdapBruteForceFields, + LdapEventFields, MultiHostPortScanFields, PortScanFields, RdpBruteForceFields, + RepeatedHttpSessionsFields, UnusualDestinationPatternFields, +}; + +impl ResolveCountryCodes for PortScanFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for MultiHostPortScanFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_codes = self + .resp_addrs + .iter() + .map(|addr| country_code_to_bytes(locator, *addr)) + .collect(); + } +} + +impl ResolveCountryCodes for ExternalDdosFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_codes = self + .orig_addrs + .iter() + .map(|addr| country_code_to_bytes(locator, *addr)) + .collect(); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistConnFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for DnsEventFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for CryptocurrencyMiningPoolFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistDnsFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for HttpEventFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for RepeatedHttpSessionsFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for HttpThreatFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for DgaFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for RdpBruteForceFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_codes = self + .resp_addrs + .iter() + .map(|addr| country_code_to_bytes(locator, *addr)) + .collect(); + } +} + +impl ResolveCountryCodes for BlocklistRdpFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for FtpBruteForceFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for FtpEventFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for LdapBruteForceFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for LdapEventFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistSshFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistTlsFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistKerberosFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistSmtpFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistNfsFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistDhcpFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistDceRpcFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistNtlmFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistSmbFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistMqttFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistBootpFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistRadiusFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for BlocklistMalformedDnsFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + +impl ResolveCountryCodes for UnusualDestinationPatternFields { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.dst_country_codes = self + .destination_ips + .iter() + .map(|addr| country_code_to_bytes(locator, *addr)) + .collect(); + } +} + /// Helper function to migrate event fields from old format to new format -fn migrate_fields(old_data: &[u8], _locator: Option<&ip2location::DB>) -> Result> +fn migrate_fields(old_data: &[u8], locator: Option<&ip2location::DB>) -> Result> where O: serde::de::DeserializeOwned, - N: serde::Serialize + serde::de::DeserializeOwned + From, + N: serde::Serialize + serde::de::DeserializeOwned + From + ResolveCountryCodes, { // First try to deserialize as the new format (already migrated) if bincode::DefaultOptions::new() @@ -1119,11 +1378,12 @@ where .deserialize(old_data) .context("failed to deserialize old event fields")?; - let new_fields: N = old_fields.into(); + let mut new_fields: N = old_fields.into(); - // Note: Country code resolution from locator is handled by the From trait. - // Currently, From implementations set country codes to None. - // To enable IP-based resolution, the From traits would need to accept the locator. + // Apply country code resolution if locator is provided + if let Some(loc) = locator { + new_fields.resolve_country_codes(loc); + } bincode::DefaultOptions::new() .serialize(&new_fields) From f60db0f8feed50558b4d95de03bd54d23ba53b1b Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 01:39:13 +0000 Subject: [PATCH 03/12] Load ip2location DB and resolve country codes --- CHANGELOG.md | 4 +++- src/migrate.rs | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 753c2607..a36dd469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,9 @@ Versioning](https://semver.org/spec/v2.0.0.html). database during event creation. - Updated `migrate_data_dir` function signature to accept an optional `ip2location::DB` parameter for resolving country codes during migration - from older database formats. + from older database formats. The migration binary now supports an optional + `ip2location` configuration field to specify the path to an ip2location + database file for country code resolution during migration. - Added `BackupConfig` entity to configure RocksDB backup settings (interval, execution time, retention). The configuration can be saved, updated, and read from persistent storage, with default values applied if none exist. diff --git a/src/migrate.rs b/src/migrate.rs index 99e2af25..b8729d45 100644 --- a/src/migrate.rs +++ b/src/migrate.rs @@ -10,11 +10,19 @@ fn main() -> Result<()> { let config = Config::load_config(parse().as_deref())?; println!("Starting migration process..."); + + let locator = config + .ip2location + .as_ref() + .map(|path| { + println!("Loading ip2location database from {}...", path.display()); + ip2location::DB::from_file(path).context("failed to load ip2location database") + }) + .transpose()?; + println!("Migrating data directory..."); - // Note: Passing None for the ip2location::DB means country codes will be set to None - // during migration. To resolve country codes from IP addresses, load an ip2location - // database and pass Some(&db) instead. - migrate_data_dir(&config.data_dir, &config.backup_dir, None).context("migration failed")?; + migrate_data_dir(&config.data_dir, &config.backup_dir, locator.as_ref()) + .context("migration failed")?; Ok(()) } @@ -60,6 +68,7 @@ fn bin() -> &'static str { pub struct Config { data_dir: PathBuf, backup_dir: PathBuf, + ip2location: Option, } impl Config { @@ -86,6 +95,7 @@ impl Config { Ok(Self { data_dir: config.data_dir, backup_dir: config.backup_dir, + ip2location: config.ip2location, }) } } @@ -94,4 +104,5 @@ impl Config { struct ConfigParser { data_dir: PathBuf, backup_dir: PathBuf, + ip2location: Option, } From 035b19a141a3363f15fab2b6270703abf404f9bd Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 01:55:06 +0000 Subject: [PATCH 04/12] Add country codes to NetworkThreat and migration --- CHANGELOG.md | 8 ++-- src/event.rs | 2 + src/event/common.rs | 2 + src/event/network.rs | 4 ++ src/migration.rs | 18 ++++++-- src/migration/migration_structures.rs | 64 +++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a36dd469..c66a9bfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,10 +31,10 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Added `src_country_code` and `dst_country_code` fields to all event-specific - `*Fields` structs. These fields store 2-letter ISO country codes as - `Option<[u8; 2]>`, enabling geographic filtering and analysis of security - events. Country codes can be resolved from IP addresses using an ip2location - database during event creation. + `*Fields` structs and `NetworkThreat`. These fields store 2-letter ISO country + codes as `Option<[u8; 2]>`, enabling geographic filtering and analysis of + security events. Country codes can be resolved from IP addresses using an + ip2location database during event creation. - Updated `migrate_data_dir` function signature to accept an optional `ip2location::DB` parameter for resolving country codes during migration from older database formats. The migration binary now supports an optional diff --git a/src/event.rs b/src/event.rs index 850a9f75..b61d6c6f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -5030,9 +5030,11 @@ mod tests { let fields = NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "collector1".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, service: "http".to_string(), diff --git a/src/event/common.rs b/src/event/common.rs index 4edae345..cff4f215 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -2540,9 +2540,11 @@ mod tests { NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "sensor".to_string(), + src_country_code: None, orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), + dst_country_code: None, resp_port: 80, proto: 6, service: "http".to_string(), diff --git a/src/event/network.rs b/src/event/network.rs index 11262912..2f371304 100644 --- a/src/event/network.rs +++ b/src/event/network.rs @@ -38,9 +38,13 @@ pub struct NetworkThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, + #[serde(default)] + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + #[serde(default)] + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub service: String, diff --git a/src/migration.rs b/src/migration.rs index 6ee1f583..8c1f8ad8 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -862,8 +862,8 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> DnsEventFieldsV0_43, ExternalDdosFieldsV0_43, FtpBruteForceFieldsV0_43, FtpEventFieldsV0_43, HttpEventFieldsV0_43, HttpThreatFieldsV0_43, LdapBruteForceFieldsV0_43, LdapEventFieldsV0_43, MultiHostPortScanFieldsV0_43, - PortScanFieldsV0_43, RdpBruteForceFieldsV0_43, RepeatedHttpSessionsFieldsV0_43, - UnusualDestinationPatternFieldsV0_43, + NetworkThreatV0_43, PortScanFieldsV0_43, RdpBruteForceFieldsV0_43, + RepeatedHttpSessionsFieldsV0_43, UnusualDestinationPatternFieldsV0_43, }; info!("Migrating event fields to add country codes"); @@ -1057,8 +1057,11 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> UnusualDestinationPatternFieldsV0_43, UnusualDestinationPatternFields, >(&event_msg.fields, locator)?, + EventKind::NetworkThreat => { + migrate_fields::(&event_msg.fields, locator)? + } // These event types don't have country code fields or use different structures - EventKind::WindowsThreat | EventKind::NetworkThreat | EventKind::ExtraThreat => { + EventKind::WindowsThreat | EventKind::ExtraThreat => { // Skip migration for these types - they don't have the standard // orig_addr/resp_addr fields or use different serialization skipped_count += 1; @@ -1122,7 +1125,7 @@ use crate::event::{ BlocklistSmbFields, BlocklistSmtpFields, BlocklistSshFields, BlocklistTlsFields, CryptocurrencyMiningPoolFields, DgaFields, DnsEventFields, ExternalDdosFields, FtpBruteForceFields, FtpEventFields, HttpEventFields, HttpThreatFields, LdapBruteForceFields, - LdapEventFields, MultiHostPortScanFields, PortScanFields, RdpBruteForceFields, + LdapEventFields, MultiHostPortScanFields, NetworkThreat, PortScanFields, RdpBruteForceFields, RepeatedHttpSessionsFields, UnusualDestinationPatternFields, }; @@ -1358,6 +1361,13 @@ impl ResolveCountryCodes for UnusualDestinationPatternFields { } } +impl ResolveCountryCodes for NetworkThreat { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.src_country_code = country_code_to_bytes(locator, self.orig_addr); + self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + } +} + /// Helper function to migrate event fields from old format to new format fn migrate_fields(old_data: &[u8], locator: Option<&ip2location::DB>) -> Result> where diff --git a/src/migration/migration_structures.rs b/src/migration/migration_structures.rs index e9e32b7e..75bc1c86 100644 --- a/src/migration/migration_structures.rs +++ b/src/migration/migration_structures.rs @@ -1893,3 +1893,67 @@ impl From for UnusualDestinationPatternFie } } } + +/// Network threat from version 0.42.x (before country codes were added) +#[derive(Deserialize, Serialize)] +pub(crate) struct NetworkThreatV0_42 { + #[serde(with = "chrono::serde::ts_nanoseconds")] + pub time: DateTime, + pub sensor: String, + pub orig_addr: IpAddr, + pub orig_port: u16, + pub resp_addr: IpAddr, + pub resp_port: u16, + pub proto: u8, + pub service: String, + #[serde(with = "chrono::serde::ts_nanoseconds")] + pub start_time: DateTime, + pub duration: i64, + pub orig_pkts: u64, + pub resp_pkts: u64, + pub orig_l2_bytes: u64, + pub resp_l2_bytes: u64, + pub content: String, + pub db_name: String, + pub rule_id: u32, + pub matched_to: String, + pub cluster_id: Option, + pub attack_kind: String, + pub confidence: f32, + pub category: Option, + pub triage_scores: Option>, +} + +use crate::event::NetworkThreat; + +impl From for NetworkThreat { + fn from(old: NetworkThreatV0_42) -> Self { + Self { + time: old.time, + sensor: old.sensor, + src_country_code: None, + orig_addr: old.orig_addr, + orig_port: old.orig_port, + resp_addr: old.resp_addr, + dst_country_code: None, + resp_port: old.resp_port, + proto: old.proto, + service: old.service, + start_time: old.start_time, + duration: old.duration, + orig_pkts: old.orig_pkts, + resp_pkts: old.resp_pkts, + orig_l2_bytes: old.orig_l2_bytes, + resp_l2_bytes: old.resp_l2_bytes, + content: old.content, + db_name: old.db_name, + rule_id: old.rule_id, + matched_to: old.matched_to, + cluster_id: old.cluster_id, + attack_kind: old.attack_kind, + confidence: old.confidence, + category: old.category, + triage_scores: old.triage_scores, + } + } +} From f33ea0812e0edafd38965e5d0807d684f31a394d Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 03:17:46 +0000 Subject: [PATCH 05/12] Add src/dst country codes to runtime events --- src/event/bootp.rs | 4 ++++ src/event/common.rs | 8 ++++---- src/event/conn.rs | 16 ++++++++++++++++ src/event/dcerpc.rs | 4 ++++ src/event/dhcp.rs | 4 ++++ src/event/dns.rs | 16 ++++++++++++++++ src/event/ftp.rs | 12 ++++++++++++ src/event/http.rs | 20 ++++++++++++++++++++ src/event/kerberos.rs | 4 ++++ src/event/ldap.rs | 12 ++++++++++++ src/event/malformed_dns.rs | 4 ++++ src/event/mqtt.rs | 4 ++++ src/event/nfs.rs | 4 ++++ src/event/ntlm.rs | 4 ++++ src/event/radius.rs | 4 ++++ src/event/rdp.rs | 8 ++++++++ src/event/smb.rs | 4 ++++ src/event/smtp.rs | 4 ++++ src/event/ssh.rs | 4 ++++ src/event/tls.rs | 8 ++++++++ src/event/tor.rs | 8 ++++++++ src/event/unusual_destination_pattern.rs | 2 ++ 22 files changed, 154 insertions(+), 4 deletions(-) diff --git a/src/event/bootp.rs b/src/event/bootp.rs index 2b8e45d0..a227c19e 100644 --- a/src/event/bootp.rs +++ b/src/event/bootp.rs @@ -116,9 +116,11 @@ pub struct BlocklistBootpFieldsV0_43 { pub struct BlocklistBootp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -180,9 +182,11 @@ impl BlocklistBootp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/common.rs b/src/event/common.rs index cff4f215..60023dca 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -2229,7 +2229,7 @@ mod tests { IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![], + dst_country_codes: vec![None, None], resp_port: 80, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2254,7 +2254,7 @@ mod tests { IpAddr::V4(Ipv4Addr::LOCALHOST), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - src_country_codes: vec![], + src_country_codes: vec![None, None], resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), dst_country_code: None, start_time: Utc @@ -2482,7 +2482,7 @@ mod tests { IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![], + dst_country_codes: vec![None, None], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2746,7 +2746,7 @@ mod tests { .timestamp_nanos_opt() .unwrap(), destination_ips: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))], - dst_country_codes: vec![], + dst_country_codes: vec![None], count: 1, expected_mean: 0.0, std_deviation: 0.0, diff --git a/src/event/conn.rs b/src/event/conn.rs index 0267714f..59521481 100644 --- a/src/event/conn.rs +++ b/src/event/conn.rs @@ -82,8 +82,10 @@ impl PortScanFields { pub struct PortScan { pub sensor: String, pub time: DateTime, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_ports: Vec, pub start_time: DateTime, pub end_time: DateTime, @@ -114,8 +116,10 @@ impl PortScan { PortScan { sensor: fields.sensor.clone(), time, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_ports: fields.resp_ports.clone(), proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -235,9 +239,11 @@ impl MultiHostPortScanFields { pub struct MultiHostPortScan { pub sensor: String, pub time: DateTime, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_port: u16, pub resp_addrs: Vec, + pub dst_country_codes: Vec>, pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -267,9 +273,11 @@ impl MultiHostPortScan { MultiHostPortScan { sensor: fields.sensor.clone(), time, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, resp_port: fields.resp_port, resp_addrs: fields.resp_addrs.clone(), + dst_country_codes: fields.dst_country_codes.clone(), proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -388,7 +396,9 @@ pub struct ExternalDdos { pub sensor: String, pub time: DateTime, pub orig_addrs: Vec, + pub src_country_codes: Vec>, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -418,7 +428,9 @@ impl ExternalDdos { sensor: fields.sensor.clone(), time, orig_addrs: fields.orig_addrs.clone(), + src_country_codes: fields.src_country_codes.clone(), resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -553,9 +565,11 @@ impl BlocklistConnFields { pub struct BlocklistConn { pub sensor: String, pub time: DateTime, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub conn_state: String, @@ -604,9 +618,11 @@ impl BlocklistConn { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, conn_state: fields.conn_state, diff --git a/src/event/dcerpc.rs b/src/event/dcerpc.rs index 8382ea1a..2ff447e2 100644 --- a/src/event/dcerpc.rs +++ b/src/event/dcerpc.rs @@ -68,9 +68,11 @@ impl BlocklistDceRpcFields { pub struct BlocklistDceRpc { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -119,9 +121,11 @@ impl BlocklistDceRpc { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/dhcp.rs b/src/event/dhcp.rs index 8b3b7844..b2895b8d 100644 --- a/src/event/dhcp.rs +++ b/src/event/dhcp.rs @@ -155,9 +155,11 @@ impl BlocklistDhcpFields { pub struct BlocklistDhcp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -235,9 +237,11 @@ impl BlocklistDhcp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/dns.rs b/src/event/dns.rs index ef1873a5..55d1e19c 100644 --- a/src/event/dns.rs +++ b/src/event/dns.rs @@ -125,9 +125,11 @@ impl DnsEventFields { pub struct DnsCovertChannel { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -193,6 +195,7 @@ impl DnsCovertChannel { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -202,6 +205,7 @@ impl DnsCovertChannel { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -297,9 +301,11 @@ impl Match for DnsCovertChannel { pub struct LockyRansomware { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -365,6 +371,7 @@ impl LockyRansomware { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -374,6 +381,7 @@ impl LockyRansomware { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -545,9 +553,11 @@ impl CryptocurrencyMiningPoolFields { pub struct CryptocurrencyMiningPool { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -614,6 +624,7 @@ impl CryptocurrencyMiningPool { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -623,6 +634,7 @@ impl CryptocurrencyMiningPool { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -793,9 +805,11 @@ impl BlocklistDnsFields { pub struct BlocklistDns { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -860,10 +874,12 @@ impl BlocklistDns { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/ftp.rs b/src/event/ftp.rs index 757f0089..663062b6 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -242,9 +242,11 @@ pub(crate) struct FtpBruteForceFieldsV0_41 { #[derive(Serialize, Deserialize)] pub struct FtpBruteForce { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub user_list: Vec, @@ -278,9 +280,11 @@ impl FtpBruteForce { pub(super) fn new(time: DateTime, fields: &FtpBruteForceFields) -> Self { FtpBruteForce { sensor: fields.sensor.clone(), + src_country_code: fields.src_country_code, time, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, user_list: fields.user_list.clone(), @@ -424,9 +428,11 @@ pub struct FtpEventFieldsV0_43 { pub struct FtpPlainText { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -480,10 +486,12 @@ impl FtpPlainText { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -555,9 +563,11 @@ impl Match for FtpPlainText { pub struct BlocklistFtp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -611,10 +621,12 @@ impl BlocklistFtp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/http.rs b/src/event/http.rs index fcd2d320..24ec7d4c 100644 --- a/src/event/http.rs +++ b/src/event/http.rs @@ -197,9 +197,11 @@ impl RepeatedHttpSessionsFields { pub struct RepeatedHttpSessions { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -232,9 +234,11 @@ impl RepeatedHttpSessions { RepeatedHttpSessions { time, sensor: fields.sensor.clone(), + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -431,9 +435,11 @@ pub struct HttpThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -525,10 +531,12 @@ impl HttpThreat { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -753,9 +761,11 @@ pub struct DomainGenerationAlgorithm { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -837,10 +847,12 @@ impl DomainGenerationAlgorithm { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -944,9 +956,11 @@ impl Match for DomainGenerationAlgorithm { pub struct NonBrowser { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -1027,6 +1041,7 @@ impl NonBrowser { NonBrowser { time, sensor: fields.sensor.clone(), + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -1036,6 +1051,7 @@ impl NonBrowser { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, method: fields.method.clone(), @@ -1138,9 +1154,11 @@ pub type BlocklistHttpFields = DgaFields; pub struct BlocklistHttp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -1221,10 +1239,12 @@ impl BlocklistHttp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/kerberos.rs b/src/event/kerberos.rs index c06900d6..e53f3346 100644 --- a/src/event/kerberos.rs +++ b/src/event/kerberos.rs @@ -114,9 +114,11 @@ impl BlocklistKerberosFields { pub struct BlocklistKerberos { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -175,9 +177,11 @@ impl BlocklistKerberos { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ldap.rs b/src/event/ldap.rs index 82e4d69d..05987906 100644 --- a/src/event/ldap.rs +++ b/src/event/ldap.rs @@ -106,9 +106,11 @@ fn get_user_pw_list(user_pw_list: &[(String, String)]) -> String { #[derive(Serialize, Deserialize)] pub struct LdapBruteForce { pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub user_pw_list: Vec<(String, String)>, @@ -140,9 +142,11 @@ impl LdapBruteForce { pub(super) fn new(time: DateTime, fields: &LdapBruteForceFields) -> Self { LdapBruteForce { sensor: fields.sensor.clone(), + src_country_code: fields.src_country_code, time, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, user_pw_list: fields.user_pw_list.clone(), @@ -283,9 +287,11 @@ impl LdapEventFields { pub struct LdapPlainText { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -340,10 +346,12 @@ impl LdapPlainText { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -419,9 +427,11 @@ impl Match for LdapPlainText { pub struct BlocklistLdap { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -476,10 +486,12 @@ impl BlocklistLdap { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/malformed_dns.rs b/src/event/malformed_dns.rs index 6424b565..7ae6f29f 100644 --- a/src/event/malformed_dns.rs +++ b/src/event/malformed_dns.rs @@ -116,9 +116,11 @@ fn format_vec_vec_u8(data: &[Vec]) -> String { pub struct BlocklistMalformedDns { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -185,9 +187,11 @@ impl BlocklistMalformedDns { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/mqtt.rs b/src/event/mqtt.rs index e4a67dad..106196fd 100644 --- a/src/event/mqtt.rs +++ b/src/event/mqtt.rs @@ -110,9 +110,11 @@ impl BlocklistMqttFields { pub struct BlocklistMqtt { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -165,9 +167,11 @@ impl BlocklistMqtt { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/nfs.rs b/src/event/nfs.rs index 9e344261..d3f2bdc0 100644 --- a/src/event/nfs.rs +++ b/src/event/nfs.rs @@ -93,9 +93,11 @@ impl BlocklistNfsFields { pub struct BlocklistNfs { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -139,9 +141,11 @@ impl BlocklistNfs { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ntlm.rs b/src/event/ntlm.rs index 8baab8b6..6e600b6d 100644 --- a/src/event/ntlm.rs +++ b/src/event/ntlm.rs @@ -98,9 +98,11 @@ impl BlocklistNtlmFields { pub struct BlocklistNtlm { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -149,9 +151,11 @@ impl BlocklistNtlm { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/radius.rs b/src/event/radius.rs index f778fbe4..653e81bb 100644 --- a/src/event/radius.rs +++ b/src/event/radius.rs @@ -124,9 +124,11 @@ impl BlocklistRadiusFields { pub struct BlocklistRadius { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -197,9 +199,11 @@ impl BlocklistRadius { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/rdp.rs b/src/event/rdp.rs index 44d7afbd..39fc2c79 100644 --- a/src/event/rdp.rs +++ b/src/event/rdp.rs @@ -79,8 +79,10 @@ impl RdpBruteForceFields { pub struct RdpBruteForce { pub sensor: String, pub time: DateTime, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub resp_addrs: Vec, + pub dst_country_codes: Vec>, pub start_time: DateTime, pub end_time: DateTime, pub proto: u8, @@ -109,8 +111,10 @@ impl RdpBruteForce { RdpBruteForce { sensor: fields.sensor.clone(), time, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, resp_addrs: fields.resp_addrs.clone(), + dst_country_codes: fields.dst_country_codes.clone(), start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), proto: fields.proto, @@ -237,9 +241,11 @@ impl BlocklistRdpFields { pub struct BlocklistRdp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -281,9 +287,11 @@ impl BlocklistRdp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/smb.rs b/src/event/smb.rs index 780ad4f6..06ada78b 100644 --- a/src/event/smb.rs +++ b/src/event/smb.rs @@ -116,9 +116,11 @@ impl BlocklistSmbFields { pub struct BlocklistSmb { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -179,9 +181,11 @@ impl BlocklistSmb { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/smtp.rs b/src/event/smtp.rs index 4728a83c..f53f1586 100644 --- a/src/event/smtp.rs +++ b/src/event/smtp.rs @@ -104,9 +104,11 @@ impl BlocklistSmtpFields { pub struct BlocklistSmtp { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -160,9 +162,11 @@ impl BlocklistSmtp { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ssh.rs b/src/event/ssh.rs index 535e92f0..83aba073 100644 --- a/src/event/ssh.rs +++ b/src/event/ssh.rs @@ -124,9 +124,11 @@ impl BlocklistSshFields { pub struct BlocklistSsh { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -192,9 +194,11 @@ impl BlocklistSsh { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/tls.rs b/src/event/tls.rs index 3538f3eb..ae2442d5 100644 --- a/src/event/tls.rs +++ b/src/event/tls.rs @@ -164,9 +164,11 @@ impl BlocklistTlsFields { pub struct BlocklistTls { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -250,9 +252,11 @@ impl BlocklistTls { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -342,9 +346,11 @@ impl Match for BlocklistTls { pub struct SuspiciousTlsTraffic { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -428,10 +434,12 @@ impl SuspiciousTlsTraffic { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/tor.rs b/src/event/tor.rs index b19b4811..6fc19c66 100644 --- a/src/event/tor.rs +++ b/src/event/tor.rs @@ -17,9 +17,11 @@ use crate::event::{ pub struct TorConnection { pub time: DateTime, pub sensor: String, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -100,6 +102,7 @@ impl TorConnection { TorConnection { time, sensor: fields.sensor.clone(), + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -109,6 +112,7 @@ impl TorConnection { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, method: fields.method.clone(), @@ -206,9 +210,11 @@ impl Match for TorConnection { pub struct TorConnectionConn { pub sensor: String, pub time: DateTime, + pub src_country_code: Option<[u8; 2]>, pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, + pub dst_country_code: Option<[u8; 2]>, pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -257,10 +263,12 @@ impl TorConnectionConn { Self { time, sensor: fields.sensor, + src_country_code: fields.src_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, + dst_country_code: fields.dst_country_code, resp_port: fields.resp_port, proto: fields.proto, conn_state: fields.conn_state, diff --git a/src/event/unusual_destination_pattern.rs b/src/event/unusual_destination_pattern.rs index fe9995cd..d9a51d3b 100644 --- a/src/event/unusual_destination_pattern.rs +++ b/src/event/unusual_destination_pattern.rs @@ -64,6 +64,7 @@ pub struct UnusualDestinationPattern { pub start_time: DateTime, pub end_time: DateTime, pub destination_ips: Vec, + pub dst_country_codes: Vec>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, @@ -99,6 +100,7 @@ impl UnusualDestinationPattern { start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), destination_ips: fields.destination_ips, + dst_country_codes: fields.dst_country_codes, count: fields.count, expected_mean: fields.expected_mean, std_deviation: fields.std_deviation, From e3605e76583e72a595f74b4009e531e7e901add7 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:28:41 -0800 Subject: [PATCH 06/12] Update country codes to [u8; 2] type with XX fallback This change addresses reviewer feedback to maintain the invariant that country codes are always represented as two-letter alphabetic codes. Changes: - Changed all country code fields from Option<[u8; 2]> to [u8; 2] - Changed Vec> to Vec<[u8; 2]> for multi-address types - Updated find_ip_country to validate 2-letter alphabetic codes and return "XX" for invalid values (like "-" from IP2Location) - Updated migration From impls to use *b"XX" instead of None - Updated version to 0.44.0-alpha.1 (0.43.0 has been released) - Updated CHANGELOG with breaking changes for 0.44.0 --- CHANGELOG.md | 21 +-- src/backup.rs | 4 +- src/event.rs | 164 ++++++++++++----------- src/event/bootp.rs | 8 +- src/event/common.rs | 130 +++++++++--------- src/event/conn.rs | 32 ++--- src/event/dcerpc.rs | 8 +- src/event/dhcp.rs | 8 +- src/event/dns.rs | 28 ++-- src/event/ftp.rs | 24 ++-- src/event/http.rs | 36 ++--- src/event/kerberos.rs | 8 +- src/event/ldap.rs | 20 +-- src/event/malformed_dns.rs | 8 +- src/event/mqtt.rs | 8 +- src/event/network.rs | 4 +- src/event/nfs.rs | 8 +- src/event/ntlm.rs | 8 +- src/event/radius.rs | 8 +- src/event/rdp.rs | 16 +-- src/event/smb.rs | 8 +- src/event/smtp.rs | 8 +- src/event/ssh.rs | 8 +- src/event/tls.rs | 12 +- src/event/tor.rs | 12 +- src/event/unusual_destination_pattern.rs | 4 +- src/migration.rs | 15 +-- src/migration/migration_structures.rs | 126 ++++++++--------- src/util.rs | 24 +++- 29 files changed, 394 insertions(+), 374 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c66a9bfd..8d17b710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- Added `orig_country_code` and `resp_country_code` fields to all event-specific + `*Fields` structs and `NetworkThreat`. These fields store 2-letter ISO country + codes as `[u8; 2]`, enabling geographic filtering and analysis of + security events. Country codes can be resolved from IP addresses using an + ip2location database during event creation. +- Updated `migrate_data_dir` function signature to accept an optional + `ip2location::DB` parameter for resolving country codes during migration + from older database formats. + ### Changed - Changed `Store::network_tag_set` signature to require a `customer_id: u32` @@ -30,16 +41,6 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Added -- Added `src_country_code` and `dst_country_code` fields to all event-specific - `*Fields` structs and `NetworkThreat`. These fields store 2-letter ISO country - codes as `Option<[u8; 2]>`, enabling geographic filtering and analysis of - security events. Country codes can be resolved from IP addresses using an - ip2location database during event creation. -- Updated `migrate_data_dir` function signature to accept an optional - `ip2location::DB` parameter for resolving country codes during migration - from older database formats. The migration binary now supports an optional - `ip2location` configuration field to specify the path to an ip2location - database file for country code resolution during migration. - Added `BackupConfig` entity to configure RocksDB backup settings (interval, execution time, retention). The configuration can be saved, updated, and read from persistent storage, with default values applied if none exist. diff --git a/src/backup.rs b/src/backup.rs index 7560c94a..9890d0ce 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -109,11 +109,11 @@ mod tests { let codec = bincode::DefaultOptions::new(); let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc diff --git a/src/event.rs b/src/event.rs index b61d6c6f..41c4e259 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1086,8 +1086,8 @@ impl Event { ) -> Result<()> { let addr_pair = self.address_pair(locator, filter)?; - let mut src_country = "ZZ".to_string(); - let mut dst_country = "ZZ".to_string(); + let mut src_country = *b"ZZ"; + let mut dst_country = *b"ZZ"; if let Some(locator) = locator { if let Some(src_addr) = addr_pair.0 { src_country = crate::util::find_ip_country(locator, src_addr); @@ -1096,6 +1096,12 @@ impl Event { dst_country = crate::util::find_ip_country(locator, dst_addr); } } + let src_country = std::str::from_utf8(&src_country) + .unwrap_or("ZZ") + .to_string(); + let dst_country = std::str::from_utf8(&dst_country) + .unwrap_or("ZZ") + .to_string(); // If origin and destination countries are different, count each one if src_country != dst_country && addr_pair.0.is_some() && addr_pair.1.is_some() { @@ -2913,7 +2919,7 @@ pub enum TrafficDirection { fn eq_ip_country(locator: &ip2location::DB, addr: IpAddr, country: [u8; 2]) -> bool { let country_code = crate::util::find_ip_country(locator, addr); - country_code.as_bytes() == country + country_code == country } #[cfg(test)] @@ -2964,10 +2970,10 @@ mod tests { fn example_message(kind: EventKind, category: EventCategory) -> EventMessage { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -3081,10 +3087,10 @@ mod tests { fn syslog_for_dga() { let fields = DgaFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3235,10 +3241,10 @@ mod tests { let fields = HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3308,10 +3314,10 @@ mod tests { fn syslog_for_nonbrowser() { let fields = HttpEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3376,10 +3382,10 @@ mod tests { fn syslog_for_blocklist_http() { let fields = BlocklistHttpFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3445,10 +3451,10 @@ mod tests { fn syslog_for_lockyransomware() { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 4)), resp_port: 53, proto: 17, @@ -3508,9 +3514,9 @@ mod tests { fn syslog_for_portscan() { let fields = PortScanFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc @@ -3557,9 +3563,9 @@ mod tests { fn syslog_for_multihostportscan() { let fields = MultiHostPortScanFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_codes: vec![None, None], + dst_country_codes: vec![*b"XX", *b"XX"], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -3609,12 +3615,12 @@ mod tests { fn syslog_for_externalddos() { let fields = ExternalDdosFields { sensor: String::new(), - src_country_codes: vec![None, None], + src_country_codes: vec![*b"XX", *b"XX"], orig_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3658,10 +3664,10 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 67, proto: 17, @@ -3791,10 +3797,10 @@ mod tests { fn syslog_for_blocklist_conn() { let fields = BlocklistConnFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3845,10 +3851,10 @@ mod tests { fn syslog_for_blocklist_dcerpc() { let fields = BlocklistDceRpcFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 135, proto: 6, @@ -3898,10 +3904,10 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::from_str("127.0.0.1").unwrap(), orig_port: 68, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::from_str("127.0.0.2").unwrap(), resp_port: 67, proto: 17, @@ -4038,10 +4044,10 @@ mod tests { fn syslog_for_dnscovertchannel() { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4106,10 +4112,10 @@ mod tests { fn syslog_for_cryptocurrencyminingpool() { let fields = CryptocurrencyMiningPoolFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4170,10 +4176,10 @@ mod tests { fn syslog_for_blocklist_dns() { let fields = BlocklistDnsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4231,9 +4237,9 @@ mod tests { fn syslog_for_ftpbruteforce() { let fields = FtpBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4298,10 +4304,10 @@ mod tests { let fields = FtpEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4364,10 +4370,10 @@ mod tests { }; FtpEventFields { - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4496,10 +4502,10 @@ mod tests { .unwrap(); let fields = RepeatedHttpSessionsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -4537,10 +4543,10 @@ mod tests { fn syslog_for_blocklist_kerberos() { let fields = BlocklistKerberosFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 88, proto: 17, @@ -4597,9 +4603,9 @@ mod tests { fn syslog_for_ldapbruteforce() { let fields = LdapBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4651,10 +4657,10 @@ mod tests { fn syslog_for_ldapplaintext() { let fields = LdapEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4708,10 +4714,10 @@ mod tests { fn ldapeventfields() -> LdapEventFields { LdapEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4837,10 +4843,10 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1812, proto: 17, @@ -4972,10 +4978,10 @@ mod tests { fn syslog_for_blocklist_mqtt() { let fields = BlocklistMqttFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1883, proto: 6, @@ -5030,11 +5036,11 @@ mod tests { let fields = NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, service: "http".to_string(), @@ -5074,10 +5080,10 @@ mod tests { fn syslog_for_blocklist_nfs() { let fields = BlocklistNfsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 2049, proto: 6, @@ -5127,10 +5133,10 @@ mod tests { fn syslog_for_blocklist_ntlm() { let fields = BlocklistNtlmFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5212,10 +5218,10 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -5346,9 +5352,9 @@ mod tests { fn syslog_for_rdpbruteforce() { let fields = RdpBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_codes: vec![None, None], + dst_country_codes: vec![*b"XX", *b"XX"], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -5398,10 +5404,10 @@ mod tests { fn syslog_for_blocklist_rdp() { let fields = BlocklistRdpFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 3389, proto: 6, @@ -5450,10 +5456,10 @@ mod tests { fn syslog_for_blocklist_smb() { let fields = BlocklistSmbFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5512,10 +5518,10 @@ mod tests { fn syslog_for_blocklist_smtp() { let fields = BlocklistSmtpFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 25, proto: 6, @@ -5570,10 +5576,10 @@ mod tests { fn syslog_for_blocklist_ssh() { let fields = BlocklistSshFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 22, proto: 6, @@ -5688,10 +5694,10 @@ mod tests { fn syslog_for_blocklist_tls() { let fields = BlocklistTlsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5769,10 +5775,10 @@ mod tests { resp_pkts: 0, orig_l2_bytes: 0, resp_l2_bytes: 0, - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5901,10 +5907,10 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, diff --git a/src/event/bootp.rs b/src/event/bootp.rs index a227c19e..22de9cdb 100644 --- a/src/event/bootp.rs +++ b/src/event/bootp.rs @@ -83,11 +83,11 @@ impl BlocklistBootpFields { #[derive(Serialize, Deserialize)] pub struct BlocklistBootpFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -116,11 +116,11 @@ pub struct BlocklistBootpFieldsV0_43 { pub struct BlocklistBootp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/common.rs b/src/event/common.rs index 60023dca..db383625 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -1604,11 +1604,11 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 67, proto: 17, start_time: Utc @@ -1640,11 +1640,11 @@ mod tests { fn blocklist_conn_fields() -> BlocklistConnFields { BlocklistConnFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, conn_state: "SAF".to_string(), @@ -1669,11 +1669,11 @@ mod tests { fn blocklist_dcerpc_fields() -> BlocklistDceRpcFields { BlocklistDceRpcFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 135, proto: 6, start_time: Utc @@ -1698,11 +1698,11 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 67, proto: 17, start_time: Utc @@ -1742,11 +1742,11 @@ mod tests { fn blocklist_dns_fields() -> BlocklistDnsFields { BlocklistDnsFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -1779,11 +1779,11 @@ mod tests { fn blocklist_http_fields() -> BlocklistHttpFields { BlocklistHttpFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -1824,11 +1824,11 @@ mod tests { fn blocklist_kerberos_fields() -> BlocklistKerberosFields { BlocklistKerberosFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 88, proto: 17, start_time: Utc @@ -1858,11 +1858,11 @@ mod tests { fn blocklist_mqtt_fields() -> BlocklistMqttFields { BlocklistMqttFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 1883, proto: 6, start_time: Utc @@ -1889,11 +1889,11 @@ mod tests { fn blocklist_nfs_fields() -> BlocklistNfsFields { BlocklistNfsFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 2049, proto: 6, start_time: Utc @@ -1916,11 +1916,11 @@ mod tests { fn blocklist_ntlm_fields() -> BlocklistNtlmFields { BlocklistNtlmFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 445, proto: 6, start_time: Utc @@ -1946,11 +1946,11 @@ mod tests { fn blocklist_rdp_fields() -> BlocklistRdpFields { BlocklistRdpFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 3389, proto: 6, start_time: Utc @@ -1972,11 +1972,11 @@ mod tests { fn blocklist_smb_fields() -> BlocklistSmbFields { BlocklistSmbFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 445, proto: 6, start_time: Utc @@ -2008,11 +2008,11 @@ mod tests { fn blocklist_smtp_fields() -> BlocklistSmtpFields { BlocklistSmtpFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 25, proto: 6, start_time: Utc @@ -2040,11 +2040,11 @@ mod tests { fn blocklist_ssh_fields() -> BlocklistSshFields { BlocklistSshFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 22, proto: 6, start_time: Utc @@ -2078,11 +2078,11 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 443, proto: 6, start_time: Utc @@ -2124,11 +2124,11 @@ mod tests { fn ldap_event_fields() -> LdapEventFields { LdapEventFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 389, proto: 6, start_time: Utc @@ -2171,11 +2171,11 @@ mod tests { FtpEventFields { sensor: "collector1".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 21, proto: 6, start_time: Utc @@ -2199,10 +2199,10 @@ mod tests { fn port_scan_fields() -> PortScanFields { PortScanFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2223,13 +2223,13 @@ mod tests { fn multi_host_port_scan_fields() -> MultiHostPortScanFields { MultiHostPortScanFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![None, None], + dst_country_codes: vec![*b"XX", *b"XX"], resp_port: 80, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2254,9 +2254,9 @@ mod tests { IpAddr::V4(Ipv4Addr::LOCALHOST), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - src_country_codes: vec![None, None], + src_country_codes: vec![*b"XX", *b"XX"], resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2276,11 +2276,11 @@ mod tests { fn crypto_miining_pool_fields() -> CryptocurrencyMiningPoolFields { CryptocurrencyMiningPoolFields { sensor: "sensro".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2314,10 +2314,10 @@ mod tests { fn ftp_brute_force_fields() -> FtpBruteForceFields { FtpBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 21, proto: 6, user_list: vec!["user1".to_string(), "user_2".to_string()], @@ -2341,11 +2341,11 @@ mod tests { let now = chrono::Utc::now().timestamp_nanos_opt().unwrap(); RepeatedHttpSessionsFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 443, proto: 6, start_time: now, @@ -2358,11 +2358,11 @@ mod tests { fn dga_fields() -> DgaFields { DgaFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2403,11 +2403,11 @@ mod tests { fn http_event_fields() -> HttpEventFields { HttpEventFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2448,10 +2448,10 @@ mod tests { fn ldap_brute_force_fields() -> LdapBruteForceFields { LdapBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 389, proto: 6, user_pw_list: vec![ @@ -2476,13 +2476,13 @@ mod tests { fn rdp_brute_force_fields() -> RdpBruteForceFields { RdpBruteForceFields { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![None, None], + dst_country_codes: vec![*b"XX", *b"XX"], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2502,11 +2502,11 @@ mod tests { fn dns_event_fields() -> DnsEventFields { DnsEventFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2540,11 +2540,11 @@ mod tests { NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, service: "http".to_string(), @@ -2610,11 +2610,11 @@ mod tests { HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2659,11 +2659,11 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 1812, proto: 17, start_time: Utc @@ -2698,11 +2698,11 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: None, + dst_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2746,7 +2746,7 @@ mod tests { .timestamp_nanos_opt() .unwrap(), destination_ips: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))], - dst_country_codes: vec![None], + dst_country_codes: vec![*b"XX"], count: 1, expected_mean: 0.0, std_deviation: 0.0, diff --git a/src/event/conn.rs b/src/event/conn.rs index 59521481..8e9b4a43 100644 --- a/src/event/conn.rs +++ b/src/event/conn.rs @@ -40,10 +40,10 @@ pub type PortScanFields = PortScanFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct PortScanFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_ports: Vec, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -82,10 +82,10 @@ impl PortScanFields { pub struct PortScan { pub sensor: String, pub time: DateTime, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_ports: Vec, pub start_time: DateTime, pub end_time: DateTime, @@ -197,11 +197,11 @@ pub type MultiHostPortScanFields = MultiHostPortScanFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct MultiHostPortScanFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_port: u16, pub resp_addrs: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -239,11 +239,11 @@ impl MultiHostPortScanFields { pub struct MultiHostPortScan { pub sensor: String, pub time: DateTime, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_port: u16, pub resp_addrs: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -356,9 +356,9 @@ pub type ExternalDdosFields = ExternalDdosFieldsV0_43; pub struct ExternalDdosFieldsV0_43 { pub sensor: String, pub orig_addrs: Vec, - pub src_country_codes: Vec>, + pub src_country_codes: Vec<[u8; 2]>, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -396,9 +396,9 @@ pub struct ExternalDdos { pub sensor: String, pub time: DateTime, pub orig_addrs: Vec, - pub src_country_codes: Vec>, + pub src_country_codes: Vec<[u8; 2]>, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -507,11 +507,11 @@ pub type BlocklistConnFields = BlocklistConnFieldsV0_43; #[derive(Deserialize, Serialize)] pub struct BlocklistConnFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub conn_state: String, @@ -565,11 +565,11 @@ impl BlocklistConnFields { pub struct BlocklistConn { pub sensor: String, pub time: DateTime, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub conn_state: String, diff --git a/src/event/dcerpc.rs b/src/event/dcerpc.rs index 2ff447e2..b41ac3be 100644 --- a/src/event/dcerpc.rs +++ b/src/event/dcerpc.rs @@ -12,11 +12,11 @@ pub type BlocklistDceRpcFields = BlocklistDceRpcFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistDceRpcFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -68,11 +68,11 @@ impl BlocklistDceRpcFields { pub struct BlocklistDceRpc { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/dhcp.rs b/src/event/dhcp.rs index b2895b8d..9bb52948 100644 --- a/src/event/dhcp.rs +++ b/src/event/dhcp.rs @@ -63,11 +63,11 @@ pub type BlocklistDhcpFields = BlocklistDhcpFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistDhcpFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -155,11 +155,11 @@ impl BlocklistDhcpFields { pub struct BlocklistDhcp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/dns.rs b/src/event/dns.rs index 55d1e19c..a7ccddcf 100644 --- a/src/event/dns.rs +++ b/src/event/dns.rs @@ -52,11 +52,11 @@ pub type DnsEventFields = DnsEventFieldsV0_43; #[derive(Deserialize, Serialize)] pub struct DnsEventFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -125,11 +125,11 @@ impl DnsEventFields { pub struct DnsCovertChannel { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -301,11 +301,11 @@ impl Match for DnsCovertChannel { pub struct LockyRansomware { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -478,11 +478,11 @@ pub type CryptocurrencyMiningPoolFields = CryptocurrencyMiningPoolFieldsV0_43; #[derive(Deserialize, Serialize)] pub struct CryptocurrencyMiningPoolFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -553,11 +553,11 @@ impl CryptocurrencyMiningPoolFields { pub struct CryptocurrencyMiningPool { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -732,11 +732,11 @@ pub type BlocklistDnsFields = BlocklistDnsFieldsV0_43; #[derive(Deserialize, Serialize)] pub struct BlocklistDnsFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -805,11 +805,11 @@ impl BlocklistDnsFields { pub struct BlocklistDns { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/ftp.rs b/src/event/ftp.rs index 663062b6..48fc8c76 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -189,10 +189,10 @@ impl FtpBruteForceFields { #[derive(Serialize, Deserialize)] pub struct FtpBruteForceFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_list: Vec, @@ -209,10 +209,10 @@ impl From for FtpBruteForceFieldsV0_43 { fn from(value: FtpBruteForceFieldsV0_41) -> Self { Self { sensor: String::new(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: value.src_addr, resp_addr: value.dst_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: value.dst_port, proto: value.proto, user_list: value.user_list, @@ -242,11 +242,11 @@ pub(crate) struct FtpBruteForceFieldsV0_41 { #[derive(Serialize, Deserialize)] pub struct FtpBruteForce { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_list: Vec, @@ -403,11 +403,11 @@ impl FtpEventFields { #[derive(Debug, Deserialize, Serialize)] pub struct FtpEventFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -428,11 +428,11 @@ pub struct FtpEventFieldsV0_43 { pub struct FtpPlainText { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -563,11 +563,11 @@ impl Match for FtpPlainText { pub struct BlocklistFtp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/http.rs b/src/event/http.rs index 24ec7d4c..66e7711b 100644 --- a/src/event/http.rs +++ b/src/event/http.rs @@ -64,11 +64,11 @@ pub type HttpEventFields = HttpEventFieldsV0_43; #[derive(Deserialize, Serialize)] pub struct HttpEventFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -154,11 +154,11 @@ pub type RepeatedHttpSessionsFields = RepeatedHttpSessionsFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct RepeatedHttpSessionsFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -197,11 +197,11 @@ impl RepeatedHttpSessionsFields { pub struct RepeatedHttpSessions { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -319,11 +319,11 @@ pub struct HttpThreatFieldsV0_43 { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -435,11 +435,11 @@ pub struct HttpThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -671,11 +671,11 @@ pub type DgaFields = DgaFieldsV0_43; #[derive(Debug, Deserialize, Serialize)] pub struct DgaFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -761,11 +761,11 @@ pub struct DomainGenerationAlgorithm { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -956,11 +956,11 @@ impl Match for DomainGenerationAlgorithm { pub struct NonBrowser { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -1154,11 +1154,11 @@ pub type BlocklistHttpFields = DgaFields; pub struct BlocklistHttp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/kerberos.rs b/src/event/kerberos.rs index e53f3346..8074d7e7 100644 --- a/src/event/kerberos.rs +++ b/src/event/kerberos.rs @@ -47,11 +47,11 @@ pub type BlocklistKerberosFields = BlocklistKerberosFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistKerberosFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -114,11 +114,11 @@ impl BlocklistKerberosFields { pub struct BlocklistKerberos { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/ldap.rs b/src/event/ldap.rs index 05987906..55ae6e40 100644 --- a/src/event/ldap.rs +++ b/src/event/ldap.rs @@ -52,10 +52,10 @@ pub type LdapBruteForceFields = LdapBruteForceFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct LdapBruteForceFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_pw_list: Vec<(String, String)>, @@ -106,11 +106,11 @@ fn get_user_pw_list(user_pw_list: &[(String, String)]) -> String { #[derive(Serialize, Deserialize)] pub struct LdapBruteForce { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_pw_list: Vec<(String, String)>, @@ -224,11 +224,11 @@ pub type LdapEventFields = LdapEventFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct LdapEventFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -287,11 +287,11 @@ impl LdapEventFields { pub struct LdapPlainText { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -427,11 +427,11 @@ impl Match for LdapPlainText { pub struct BlocklistLdap { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/malformed_dns.rs b/src/event/malformed_dns.rs index 7ae6f29f..16741be3 100644 --- a/src/event/malformed_dns.rs +++ b/src/event/malformed_dns.rs @@ -36,11 +36,11 @@ pub type BlocklistMalformedDnsFields = BlocklistMalformedDnsFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistMalformedDnsFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -116,11 +116,11 @@ fn format_vec_vec_u8(data: &[Vec]) -> String { pub struct BlocklistMalformedDns { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/mqtt.rs b/src/event/mqtt.rs index 106196fd..bfebde9f 100644 --- a/src/event/mqtt.rs +++ b/src/event/mqtt.rs @@ -48,11 +48,11 @@ pub type BlocklistMqttFields = BlocklistMqttFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistMqttFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -110,11 +110,11 @@ impl BlocklistMqttFields { pub struct BlocklistMqtt { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/network.rs b/src/event/network.rs index 2f371304..7e581b27 100644 --- a/src/event/network.rs +++ b/src/event/network.rs @@ -39,12 +39,12 @@ pub struct NetworkThreat { pub time: DateTime, pub sensor: String, #[serde(default)] - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, #[serde(default)] - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub service: String, diff --git a/src/event/nfs.rs b/src/event/nfs.rs index d3f2bdc0..e72df908 100644 --- a/src/event/nfs.rs +++ b/src/event/nfs.rs @@ -40,11 +40,11 @@ pub type BlocklistNfsFields = BlocklistNfsFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistNfsFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -93,11 +93,11 @@ impl BlocklistNfsFields { pub struct BlocklistNfs { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/ntlm.rs b/src/event/ntlm.rs index 6e600b6d..784a9379 100644 --- a/src/event/ntlm.rs +++ b/src/event/ntlm.rs @@ -39,11 +39,11 @@ pub type BlocklistNtlmFields = BlocklistNtlmFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistNtlmFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -98,11 +98,11 @@ impl BlocklistNtlmFields { pub struct BlocklistNtlm { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/radius.rs b/src/event/radius.rs index 653e81bb..96efba13 100644 --- a/src/event/radius.rs +++ b/src/event/radius.rs @@ -48,11 +48,11 @@ pub type BlocklistRadiusFields = BlocklistRadiusFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistRadiusFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -124,11 +124,11 @@ impl BlocklistRadiusFields { pub struct BlocklistRadius { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/rdp.rs b/src/event/rdp.rs index 39fc2c79..e3628f48 100644 --- a/src/event/rdp.rs +++ b/src/event/rdp.rs @@ -40,10 +40,10 @@ pub type RdpBruteForceFields = RdpBruteForceFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct RdpBruteForceFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addrs: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -79,10 +79,10 @@ impl RdpBruteForceFields { pub struct RdpBruteForce { pub sensor: String, pub time: DateTime, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addrs: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, pub start_time: DateTime, pub end_time: DateTime, pub proto: u8, @@ -191,11 +191,11 @@ pub type BlocklistRdpFields = BlocklistRdpFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistRdpFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -241,11 +241,11 @@ impl BlocklistRdpFields { pub struct BlocklistRdp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/smb.rs b/src/event/smb.rs index 06ada78b..087b7849 100644 --- a/src/event/smb.rs +++ b/src/event/smb.rs @@ -45,11 +45,11 @@ pub type BlocklistSmbFields = BlocklistSmbFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistSmbFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -116,11 +116,11 @@ impl BlocklistSmbFields { pub struct BlocklistSmb { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/smtp.rs b/src/event/smtp.rs index f53f1586..e99586ff 100644 --- a/src/event/smtp.rs +++ b/src/event/smtp.rs @@ -41,11 +41,11 @@ pub type BlocklistSmtpFields = BlocklistSmtpFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistSmtpFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -104,11 +104,11 @@ impl BlocklistSmtpFields { pub struct BlocklistSmtp { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/ssh.rs b/src/event/ssh.rs index 83aba073..32c68625 100644 --- a/src/event/ssh.rs +++ b/src/event/ssh.rs @@ -49,11 +49,11 @@ pub type BlocklistSshFields = BlocklistSshFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistSshFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -124,11 +124,11 @@ impl BlocklistSshFields { pub struct BlocklistSsh { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/tls.rs b/src/event/tls.rs index ae2442d5..010a86ef 100644 --- a/src/event/tls.rs +++ b/src/event/tls.rs @@ -73,11 +73,11 @@ pub type BlocklistTlsFields = BlocklistTlsFieldsV0_43; #[derive(Serialize, Deserialize)] pub struct BlocklistTlsFieldsV0_43 { pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -164,11 +164,11 @@ impl BlocklistTlsFields { pub struct BlocklistTls { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -346,11 +346,11 @@ impl Match for BlocklistTls { pub struct SuspiciousTlsTraffic { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, diff --git a/src/event/tor.rs b/src/event/tor.rs index 6fc19c66..10e9686a 100644 --- a/src/event/tor.rs +++ b/src/event/tor.rs @@ -17,11 +17,11 @@ use crate::event::{ pub struct TorConnection { pub time: DateTime, pub sensor: String, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -210,11 +210,11 @@ impl Match for TorConnection { pub struct TorConnectionConn { pub sensor: String, pub time: DateTime, - pub src_country_code: Option<[u8; 2]>, + pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: Option<[u8; 2]>, + pub dst_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -357,10 +357,10 @@ mod tests { .unwrap(); BlocklistConnFields { sensor: "test-sensor".to_string(), - src_country_code: None, + src_country_code: *b"XX", orig_addr: "192.168.1.100".parse().unwrap(), orig_port: 12345, - dst_country_code: None, + dst_country_code: *b"XX", resp_addr: "198.51.100.1".parse().unwrap(), resp_port: 443, proto: 6, diff --git a/src/event/unusual_destination_pattern.rs b/src/event/unusual_destination_pattern.rs index d9a51d3b..12573b4a 100644 --- a/src/event/unusual_destination_pattern.rs +++ b/src/event/unusual_destination_pattern.rs @@ -17,7 +17,7 @@ pub struct UnusualDestinationPatternFieldsV0_43 { /// Timestamp in nanoseconds since the Unix epoch (UTC). pub end_time: i64, pub destination_ips: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, @@ -64,7 +64,7 @@ pub struct UnusualDestinationPattern { pub start_time: DateTime, pub end_time: DateTime, pub destination_ips: Vec, - pub dst_country_codes: Vec>, + pub dst_country_codes: Vec<[u8; 2]>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, diff --git a/src/migration.rs b/src/migration.rs index 8c1f8ad8..a5295ce5 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -1102,16 +1102,11 @@ trait ResolveCountryCodes { fn resolve_country_codes(&mut self, locator: &ip2location::DB); } -/// Converts a country code string to a 2-byte array. -/// Returns `None` if the lookup fails or returns "XX" (unknown). -fn country_code_to_bytes(locator: &ip2location::DB, addr: IpAddr) -> Option<[u8; 2]> { - let code = crate::util::find_ip_country(locator, addr); - if code == "XX" || code.len() != 2 { - None - } else { - let bytes = code.as_bytes(); - Some([bytes[0], bytes[1]]) - } +/// Converts an IP address to a country code using the ip2location database. +/// Returns the 2-letter country code, or "XX" if the lookup fails or returns +/// an invalid code. +fn country_code_to_bytes(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { + crate::util::find_ip_country(locator, addr) } // ============================================================================= diff --git a/src/migration/migration_structures.rs b/src/migration/migration_structures.rs index 75bc1c86..11f173e0 100644 --- a/src/migration/migration_structures.rs +++ b/src/migration/migration_structures.rs @@ -949,10 +949,10 @@ impl From for PortScanFields { fn from(old: PortScanFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_ports: old.resp_ports, start_time: old.start_time, end_time: old.end_time, @@ -965,10 +965,10 @@ impl From for PortScanFields { impl From for MultiHostPortScanFields { fn from(old: MultiHostPortScanFieldsV0_42) -> Self { - let dst_country_codes = vec![None; old.resp_addrs.len()]; + let dst_country_codes = vec![*b"XX"; old.resp_addrs.len()]; Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, resp_port: old.resp_port, resp_addrs: old.resp_addrs, @@ -984,13 +984,13 @@ impl From for MultiHostPortScanFields { impl From for ExternalDdosFields { fn from(old: ExternalDdosFieldsV0_42) -> Self { - let src_country_codes = vec![None; old.orig_addrs.len()]; + let src_country_codes = vec![*b"XX"; old.orig_addrs.len()]; Self { sensor: old.sensor, orig_addrs: old.orig_addrs, src_country_codes, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -1004,11 +1004,11 @@ impl From for BlocklistConnFields { fn from(old: BlocklistConnFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, conn_state: old.conn_state, @@ -1031,11 +1031,11 @@ impl From for DnsEventFields { fn from(old: DnsEventFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1066,11 +1066,11 @@ impl From for CryptocurrencyMiningPoolField fn from(old: CryptocurrencyMiningPoolFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1102,11 +1102,11 @@ impl From for BlocklistDnsFields { fn from(old: BlocklistDnsFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1137,11 +1137,11 @@ impl From for HttpEventFields { fn from(old: HttpEventFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1180,11 +1180,11 @@ impl From for RepeatedHttpSessionsFields { fn from(old: RepeatedHttpSessionsFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1200,11 +1200,11 @@ impl From for HttpThreatFields { Self { time: old.time, sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1248,11 +1248,11 @@ impl From for DgaFields { fn from(old: DgaFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1289,10 +1289,10 @@ impl From for DgaFields { impl From for RdpBruteForceFields { fn from(old: RdpBruteForceFieldsV0_42) -> Self { - let dst_country_codes = vec![None; old.resp_addrs.len()]; + let dst_country_codes = vec![*b"XX"; old.resp_addrs.len()]; Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, resp_addrs: old.resp_addrs, dst_country_codes, @@ -1309,11 +1309,11 @@ impl From for BlocklistRdpFields { fn from(old: BlocklistRdpFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1333,10 +1333,10 @@ impl From for FtpBruteForceFields { fn from(old: FtpBruteForceFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, user_list: old.user_list, @@ -1372,11 +1372,11 @@ impl From for FtpEventFields { fn from(old: FtpEventFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1398,10 +1398,10 @@ impl From for LdapBruteForceFields { fn from(old: LdapBruteForceFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, user_pw_list: old.user_pw_list, @@ -1417,11 +1417,11 @@ impl From for LdapEventFields { fn from(old: LdapEventFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1447,11 +1447,11 @@ impl From for BlocklistSshFields { fn from(old: BlocklistSshFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1483,11 +1483,11 @@ impl From for BlocklistTlsFields { fn from(old: BlocklistTlsFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1527,11 +1527,11 @@ impl From for BlocklistKerberosFields { fn from(old: BlocklistKerberosFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1559,11 +1559,11 @@ impl From for BlocklistSmtpFields { fn from(old: BlocklistSmtpFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1589,11 +1589,11 @@ impl From for BlocklistNfsFields { fn from(old: BlocklistNfsFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1614,11 +1614,11 @@ impl From for BlocklistDhcpFields { fn from(old: BlocklistDhcpFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1655,11 +1655,11 @@ impl From for BlocklistDceRpcFields { fn from(old: BlocklistDceRpcFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1682,11 +1682,11 @@ impl From for BlocklistNtlmFields { fn from(old: BlocklistNtlmFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1710,11 +1710,11 @@ impl From for BlocklistSmbFields { fn from(old: BlocklistSmbFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1744,11 +1744,11 @@ impl From for BlocklistMqttFields { fn from(old: BlocklistMqttFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1773,11 +1773,11 @@ impl From for BlocklistBootpFields { fn from(old: BlocklistBootpFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1807,11 +1807,11 @@ impl From for BlocklistRadiusFields { fn from(old: BlocklistRadiusFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1844,11 +1844,11 @@ impl From for BlocklistMalformedDnsFields { fn from(old: BlocklistMalformedDnsFieldsV0_42) -> Self { Self { sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1877,7 +1877,7 @@ impl From for BlocklistMalformedDnsFields { impl From for UnusualDestinationPatternFields { fn from(old: UnusualDestinationPatternFieldsV0_42) -> Self { - let dst_country_codes = vec![None; old.destination_ips.len()]; + let dst_country_codes = vec![*b"XX"; old.destination_ips.len()]; Self { sensor: old.sensor, start_time: old.start_time, @@ -1931,11 +1931,11 @@ impl From for NetworkThreat { Self { time: old.time, sensor: old.sensor, - src_country_code: None, + src_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: None, + dst_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, service: old.service, diff --git a/src/util.rs b/src/util.rs index 9f64a052..333b10bf 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,6 +2,9 @@ use std::net::IpAddr; +/// The unknown country code, used when lookup fails or returns an invalid code. +pub const UNKNOWN_COUNTRY_CODE: [u8; 2] = *b"XX"; + /// Looks up the country code for the given IP address. /// /// # Arguments @@ -11,15 +14,30 @@ use std::net::IpAddr; /// /// # Returns /// -/// Returns the two-letter country code for the IP address, or "XX" if the lookup fails. +/// Returns the two-letter country code for the IP address, or "XX" if the lookup fails +/// or the returned code is not a valid two-letter alphabetic code. #[must_use] -pub fn find_ip_country(locator: &ip2location::DB, addr: IpAddr) -> String { +pub fn find_ip_country(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { locator .ip_lookup(addr) .map(|r| get_record_country_short_name(&r)) .ok() .flatten() - .unwrap_or_else(|| "XX".to_string()) + .and_then(|code| validate_country_code(&code)) + .unwrap_or(UNKNOWN_COUNTRY_CODE) +} + +/// Validates that the given country code is a valid two-letter alphabetic code. +/// +/// Returns `Some([u8; 2])` if valid, `None` otherwise. +/// This filters out invalid values like "-" that `IP2Location` may return. +fn validate_country_code(code: &str) -> Option<[u8; 2]> { + let bytes = code.as_bytes(); + if bytes.len() == 2 && bytes[0].is_ascii_alphabetic() && bytes[1].is_ascii_alphabetic() { + Some([bytes[0], bytes[1]]) + } else { + None + } } fn get_record_country_short_name(record: &ip2location::Record) -> Option { From b589f1020097fa8e1dbf56eeeb369eb42ce54421 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 17:55:37 -0800 Subject: [PATCH 07/12] Address PR feedback: rename country code fields and update version suffixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename src_country_code/dst_country_code to orig_country_code/resp_country_code to align with existing orig/resp terminology - Update field ordering to follow addr → port → country_code pattern - Rename V0_43 suffix to V0_44 in event structs (country codes are a 0.44 feature) - Rename V0_42 suffix to V0_43 in migration structures - Revert find_ip_country return type to String to avoid widespread crate changes - Add country_code_to_bytes helper for internal [u8; 2] conversion - Add country code fields to Display and syslog_rfc5424 implementations - Update CHANGELOG to place country code changes under Unreleased (for 0.44) - Update all test expectations to include country code fields --- src/backup.rs | 4 +- src/event.rs | 298 ++++++++-------- src/event/bootp.rs | 24 +- src/event/common.rs | 130 +++---- src/event/conn.rs | 94 +++--- src/event/dcerpc.rs | 24 +- src/event/dhcp.rs | 24 +- src/event/dns.rs | 84 +++-- src/event/ftp.rs | 66 ++-- src/event/http.rs | 108 +++--- src/event/kerberos.rs | 24 +- src/event/ldap.rs | 56 ++-- src/event/malformed_dns.rs | 24 +- src/event/mqtt.rs | 24 +- src/event/network.rs | 16 +- src/event/nfs.rs | 24 +- src/event/ntlm.rs | 24 +- src/event/radius.rs | 24 +- src/event/rdp.rs | 46 +-- src/event/smb.rs | 24 +- src/event/smtp.rs | 24 +- src/event/ssh.rs | 24 +- src/event/tls.rs | 36 +- src/event/tor.rs | 20 +- src/event/unusual_destination_pattern.rs | 10 +- src/lib.rs | 2 +- src/migration.rs | 130 +++---- src/migration/migration_structures.rs | 410 +++++++++++------------ src/util.rs | 27 +- 29 files changed, 975 insertions(+), 850 deletions(-) diff --git a/src/backup.rs b/src/backup.rs index 9890d0ce..7ccdc9ff 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -109,11 +109,11 @@ mod tests { let codec = bincode::DefaultOptions::new(); let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc diff --git a/src/event.rs b/src/event.rs index 41c4e259..37fe670b 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1086,8 +1086,8 @@ impl Event { ) -> Result<()> { let addr_pair = self.address_pair(locator, filter)?; - let mut src_country = *b"ZZ"; - let mut dst_country = *b"ZZ"; + let mut src_country = "ZZ".to_string(); + let mut dst_country = "ZZ".to_string(); if let Some(locator) = locator { if let Some(src_addr) = addr_pair.0 { src_country = crate::util::find_ip_country(locator, src_addr); @@ -1096,12 +1096,6 @@ impl Event { dst_country = crate::util::find_ip_country(locator, dst_addr); } } - let src_country = std::str::from_utf8(&src_country) - .unwrap_or("ZZ") - .to_string(); - let dst_country = std::str::from_utf8(&dst_country) - .unwrap_or("ZZ") - .to_string(); // If origin and destination countries are different, count each one if src_country != dst_country && addr_pair.0.is_some() && addr_pair.1.is_some() { @@ -2919,7 +2913,7 @@ pub enum TrafficDirection { fn eq_ip_country(locator: &ip2location::DB, addr: IpAddr, country: [u8; 2]) -> bool { let country_code = crate::util::find_ip_country(locator, addr); - country_code == country + crate::util::country_code_to_bytes(&country_code) == country } #[cfg(test)] @@ -2970,10 +2964,10 @@ mod tests { fn example_message(kind: EventKind, category: EventCategory) -> EventMessage { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -3087,10 +3081,10 @@ mod tests { fn syslog_for_dga() { let fields = DgaFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3137,7 +3131,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="DomainGenerationAlgorithm" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="0.8""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="DomainGenerationAlgorithm" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="0.8""# ); let dga = DomainGenerationAlgorithm::new( @@ -3148,7 +3142,7 @@ mod tests { let dga_display = format!("{event}"); assert_eq!( &dga_display, - r#"time="1970-01-01T00:01:01+00:00" event_kind="DomainGenerationAlgorithm" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="0.8" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="DomainGenerationAlgorithm" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="0.8" triage_scores="""# ); } @@ -3241,10 +3235,10 @@ mod tests { let fields = HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3298,7 +3292,7 @@ mod tests { assert_eq!( syslog_message, format!( - "time=\"1970-01-01T00:01:01+00:00\" event_kind=\"HttpThreat\" category=\"Reconnaissance\" sensor=\"collector1\" orig_addr=\"127.0.0.1\" orig_port=\"10000\" resp_addr=\"127.0.0.2\" resp_port=\"80\" proto=\"6\" start_time=\"{start_time}\" duration=\"0\" orig_pkts=\"0\" resp_pkts=\"0\" orig_l2_bytes=\"0\" resp_l2_bytes=\"0\" method=\"GET\" host=\"example.com\" uri=\"/uri/path\" referer=\"-\" version=\"1.1\" user_agent=\"browser\" request_len=\"100\" response_len=\"100\" status_code=\"200\" status_msg=\"-\" username=\"-\" password=\"-\" cookie=\"cookie\" content_encoding=\"encoding type\" content_type=\"content type\" cache_control=\"no cache\" filenames=\"a1,a2\" mime_types=\"b1,b2\" body=\"1234567890...\" state=\"\" db_name=\"db\" rule_id=\"12000\" matched_to=\"match\" cluster_id=\"1111\" attack_kind=\"attack\" confidence=\"0.8\"" + "time=\"1970-01-01T00:01:01+00:00\" event_kind=\"HttpThreat\" category=\"Reconnaissance\" sensor=\"collector1\" orig_addr=\"127.0.0.1\" orig_port=\"10000\" orig_country_code=\"XX\" resp_addr=\"127.0.0.2\" resp_port=\"80\" resp_country_code=\"XX\" proto=\"6\" start_time=\"{start_time}\" duration=\"0\" orig_pkts=\"0\" resp_pkts=\"0\" orig_l2_bytes=\"0\" resp_l2_bytes=\"0\" method=\"GET\" host=\"example.com\" uri=\"/uri/path\" referer=\"-\" version=\"1.1\" user_agent=\"browser\" request_len=\"100\" response_len=\"100\" status_code=\"200\" status_msg=\"-\" username=\"-\" password=\"-\" cookie=\"cookie\" content_encoding=\"encoding type\" content_type=\"content type\" cache_control=\"no cache\" filenames=\"a1,a2\" mime_types=\"b1,b2\" body=\"1234567890...\" state=\"\" db_name=\"db\" rule_id=\"12000\" matched_to=\"match\" cluster_id=\"1111\" attack_kind=\"attack\" confidence=\"0.8\"" ) ); @@ -3314,10 +3308,10 @@ mod tests { fn syslog_for_nonbrowser() { let fields = HttpEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3366,7 +3360,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="NonBrowser" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="1""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="NonBrowser" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="1""# ); let non_browser = Event::NonBrowser(NonBrowser::new( @@ -3382,10 +3376,10 @@ mod tests { fn syslog_for_blocklist_http() { let fields = BlocklistHttpFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3434,7 +3428,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="BlocklistHttp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="1""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="BlocklistHttp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="example.com" uri="/uri/path" referer="-" version="1.1" user_agent="browser" request_len="100" response_len="100" status_code="200" status_msg="-" username="-" password="-" cookie="cookie" content_encoding="encoding type" content_type="content type" cache_control="no cache" filenames="a1,a2" mime_types="b1,b2" body="1234567890..." state="" confidence="1""# ); let blocklist_http = Event::Blocklist(RecordType::Http(BlocklistHttp::new( @@ -3451,10 +3445,10 @@ mod tests { fn syslog_for_lockyransomware() { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 4)), resp_port: 53, proto: 17, @@ -3495,7 +3489,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="LockyRansomware" category="Impact" sensor="collector1" orig_addr="127.0.0.3" orig_port="10000" resp_addr="127.0.0.4" resp_port="53" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="locky.com" answer="1.1.1.100" trans_id="1100" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="true" rd_flag="false" ra_flag="false" ttl="120,120,120,120,120" confidence="0.8""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="LockyRansomware" category="Impact" sensor="collector1" orig_addr="127.0.0.3" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.4" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="locky.com" answer="1.1.1.100" trans_id="1100" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="true" rd_flag="false" ra_flag="false" ttl="120,120,120,120,120" confidence="0.8""# ); let locky_ransomware = Event::LockyRansomware(LockyRansomware::new( @@ -3514,9 +3508,9 @@ mod tests { fn syslog_for_portscan() { let fields = PortScanFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc @@ -3545,7 +3539,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_country_code="XX" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" confidence="0.3""# ); let port_scan = Event::PortScan(PortScan::new( @@ -3555,7 +3549,7 @@ mod tests { .to_string(); assert_eq!( &port_scan, - r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_country_code="XX" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" triage_scores="""# ); } @@ -3563,9 +3557,9 @@ mod tests { fn syslog_for_multihostportscan() { let fields = MultiHostPortScanFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_codes: vec![*b"XX", *b"XX"], + resp_country_codes: vec![*b"XX", *b"XX"], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -3597,7 +3591,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# ); let multi_host_port_scan = Event::MultiHostPortScan(MultiHostPortScan::new( @@ -3607,7 +3601,7 @@ mod tests { .to_string(); assert_eq!( &multi_host_port_scan, - r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" orig_addr="127.0.0.1" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# ); } @@ -3615,12 +3609,12 @@ mod tests { fn syslog_for_externalddos() { let fields = ExternalDdosFields { sensor: String::new(), - src_country_codes: vec![*b"XX", *b"XX"], + orig_country_codes: vec![*b"XX", *b"XX"], orig_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3647,7 +3641,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" sensor="" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" sensor="" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# ); let external_ddos = Event::ExternalDdos(ExternalDdos::new( @@ -3657,17 +3651,17 @@ mod tests { .to_string(); assert_eq!( &external_ddos, - r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# ); } fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 67, proto: 17, @@ -3712,7 +3706,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistBootp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" resp_addr="127.0.0.2" resp_port="67" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" op="1" htype="2" hops="1" xid="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" chaddr="01:02:03:04:05:06" sname="server_name" file="boot_file_name" confidence="1""#, + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistBootp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="67" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" op="1" htype="2" hops="1" xid="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" chaddr="01:02:03:04:05:06" sname="server_name" file="boot_file_name" confidence="1""#, ); let blocklist_bootp = Event::Blocklist(RecordType::Bootp(BlocklistBootp::new( Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), @@ -3722,7 +3716,7 @@ mod tests { assert_eq!( &blocklist_bootp, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistBootp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" resp_addr="127.0.0.2" resp_port="67" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" op="1" htype="2" hops="1" xid="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" chaddr="01:02:03:04:05:06" sname="server_name" file="boot_file_name" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistBootp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="67" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" op="1" htype="2" hops="1" xid="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" chaddr="01:02:03:04:05:06" sname="server_name" file="boot_file_name" triage_scores="""# ); } @@ -3797,10 +3791,10 @@ mod tests { fn syslog_for_blocklist_conn() { let fields = BlocklistConnFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, proto: 6, @@ -3833,7 +3827,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistConn" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" conn_state="SAF" start_time="1970-01-01T00:00:00+00:00" duration="0" service="http" orig_bytes="100" resp_bytes="100" orig_pkts="1" resp_pkts="1" orig_l2_bytes="122" resp_l2_bytes="122" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistConn" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" conn_state="SAF" start_time="1970-01-01T00:00:00+00:00" duration="0" service="http" orig_bytes="100" resp_bytes="100" orig_pkts="1" resp_pkts="1" orig_l2_bytes="122" resp_l2_bytes="122" confidence="1""# ); let blocklist_conn = Event::Blocklist(RecordType::Conn(BlocklistConn::new( @@ -3843,7 +3837,7 @@ mod tests { .to_string(); assert_eq!( &blocklist_conn, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistConn" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" conn_state="SAF" start_time="1970-01-01T00:00:00+00:00" duration="0" service="http" orig_bytes="100" resp_bytes="100" orig_pkts="1" resp_pkts="1" orig_l2_bytes="122" resp_l2_bytes="122" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistConn" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" conn_state="SAF" start_time="1970-01-01T00:00:00+00:00" duration="0" service="http" orig_bytes="100" resp_bytes="100" orig_pkts="1" resp_pkts="1" orig_l2_bytes="122" resp_l2_bytes="122" triage_scores="""# ); } @@ -3851,10 +3845,10 @@ mod tests { fn syslog_for_blocklist_dcerpc() { let fields = BlocklistDceRpcFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 135, proto: 6, @@ -3887,7 +3881,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDceRpc" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="135" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" rtt="1" named_pipe="svcctl" endpoint="epmapper" operation="bind" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDceRpc" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="135" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" rtt="1" named_pipe="svcctl" endpoint="epmapper" operation="bind" confidence="1""# ); let blocklist_dce_rpc = Event::Blocklist(RecordType::DceRpc(BlocklistDceRpc::new( @@ -3897,17 +3891,17 @@ mod tests { .to_string(); assert_eq!( &blocklist_dce_rpc, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDceRpc" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="135" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" rtt="1" named_pipe="svcctl" endpoint="epmapper" operation="bind" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDceRpc" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="135" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" rtt="1" named_pipe="svcctl" endpoint="epmapper" operation="bind" triage_scores="""# ); } fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::from_str("127.0.0.1").unwrap(), orig_port: 68, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::from_str("127.0.0.2").unwrap(), resp_port: 67, proto: 17, @@ -3958,7 +3952,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDhcp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" resp_addr="127.0.0.2" resp_port="67" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" msg_type="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" subnet_mask="255.255.255.0" router="127.0.0.1" domain_name_server="127.0.0.1" req_ip_addr="127.0.0.100" lease_time="100" server_id="127.0.0.1" param_req_list="1,2,3" message="message" renewal_time="100" rebinding_time="200" class_id="MSFT 5.0" client_id_type="1" client_id="07:08:09" confidence="1""#, + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDhcp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="67" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" msg_type="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" subnet_mask="255.255.255.0" router="127.0.0.1" domain_name_server="127.0.0.1" req_ip_addr="127.0.0.100" lease_time="100" server_id="127.0.0.1" param_req_list="1,2,3" message="message" renewal_time="100" rebinding_time="200" class_id="MSFT 5.0" client_id_type="1" client_id="07:08:09" confidence="1""#, ); let blocklist_dhcp = Event::Blocklist(RecordType::Dhcp(BlocklistDhcp::new( @@ -3969,7 +3963,7 @@ mod tests { assert_eq!( &blocklist_dhcp, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDhcp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" resp_addr="127.0.0.2" resp_port="67" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" msg_type="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" subnet_mask="255.255.255.0" router="127.0.0.1" domain_name_server="127.0.0.1" req_ip_addr="127.0.0.100" lease_time="100" server_id="127.0.0.1" param_req_list="1,2,3" message="message" renewal_time="100" rebinding_time="200" class_id="MSFT 5.0" client_id_type="1" client_id="07:08:09" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDhcp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="68" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="67" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" msg_type="1" ciaddr="127.0.0.5" yiaddr="127.0.0.6" siaddr="127.0.0.7" giaddr="127.0.0.8" subnet_mask="255.255.255.0" router="127.0.0.1" domain_name_server="127.0.0.1" req_ip_addr="127.0.0.100" lease_time="100" server_id="127.0.0.1" param_req_list="1,2,3" message="message" renewal_time="100" rebinding_time="200" class_id="MSFT 5.0" client_id_type="1" client_id="07:08:09" triage_scores="""# ); } @@ -4044,10 +4038,10 @@ mod tests { fn syslog_for_dnscovertchannel() { let fields = DnsEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4088,7 +4082,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="DnsCovertChannel" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="0.9""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="DnsCovertChannel" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="0.9""# ); let triage_scores = vec![TriageScore { @@ -4104,7 +4098,7 @@ mod tests { assert_eq!( &dns_covert_channel, - r#"time="1970-01-01T01:01:01+00:00" event_kind="DnsCovertChannel" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="0.9" triage_scores="109:0.90""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="DnsCovertChannel" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="0.9" triage_scores="109:0.90""# ); } @@ -4112,10 +4106,10 @@ mod tests { fn syslog_for_cryptocurrencyminingpool() { let fields = CryptocurrencyMiningPoolFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4157,7 +4151,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="CryptocurrencyMiningPool" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" coins="bitcoin,monero" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="CryptocurrencyMiningPool" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" coins="bitcoin,monero" confidence="1""# ); let cryptocurrency_mining_pool = @@ -4168,7 +4162,7 @@ mod tests { .to_string(); assert_eq!( &cryptocurrency_mining_pool, - r#"time="1970-01-01T01:01:01+00:00" event_kind="CryptocurrencyMiningPool" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" coins="bitcoin,monero" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="CryptocurrencyMiningPool" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" coins="bitcoin,monero" triage_scores="""# ); } @@ -4176,10 +4170,10 @@ mod tests { fn syslog_for_blocklist_dns() { let fields = BlocklistDnsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -4220,7 +4214,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" confidence="1""# ); let blocklist_dns = Event::Blocklist(RecordType::Dns(BlocklistDns::new( Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), @@ -4229,7 +4223,7 @@ mod tests { .to_string(); assert_eq!( &blocklist_dns, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" query="foo.com" answer="10.10.10.10,20.20.20.20" trans_id="123" rtt="1" qclass="0" qtype="0" rcode="0" aa_flag="false" tc_flag="false" rd_flag="false" ra_flag="true" ttl="120,120,120,120,120" triage_scores="""# ); } @@ -4237,9 +4231,9 @@ mod tests { fn syslog_for_ftpbruteforce() { let fields = FtpBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4270,7 +4264,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="FtpBruteForce" category="CredentialAccess" sensor="" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_port="21" proto="6" user_list="user1,user_2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" is_internal="true" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="FtpBruteForce" category="CredentialAccess" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" user_list="user1,user_2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" is_internal="true" confidence="0.3""# ); let ftp_brute_force = Event::FtpBruteForce(FtpBruteForce::new( @@ -4281,7 +4275,7 @@ mod tests { assert_eq!( &ftp_brute_force, - r#"time="1970-01-01T00:01:01+00:00" event_kind="FtpBruteForce" category="CredentialAccess" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_port="21" proto="6" user_list="user1,user_2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" is_internal="true" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="FtpBruteForce" category="CredentialAccess" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" user_list="user1,user_2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" is_internal="true" triage_scores="""# ); } @@ -4304,10 +4298,10 @@ mod tests { let fields = FtpEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4339,7 +4333,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="FtpPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="21" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="FtpPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" confidence="1""# ); let ftp_plain_text = Event::FtpPlainText(FtpPlainText::new( @@ -4349,7 +4343,7 @@ mod tests { .to_string(); assert_eq!( &ftp_plain_text, - r#"time="1970-01-01T01:01:01+00:00" event_kind="FtpPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="21" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="FtpPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" triage_scores="""# ); } @@ -4370,10 +4364,10 @@ mod tests { }; FtpEventFields { - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, proto: 6, @@ -4411,7 +4405,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistFtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="21" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistFtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" confidence="1""# ); let blocklist_ftp = Event::Blocklist(RecordType::Ftp(BlocklistFtp::new( @@ -4422,7 +4416,7 @@ mod tests { assert_eq!( &blocklist_ftp, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistFtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="21" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistFtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="21" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" user="user1" password="password" commands="ls:200:OK" triage_scores="""# ); } @@ -4502,10 +4496,10 @@ mod tests { .unwrap(); let fields = RepeatedHttpSessionsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -4526,7 +4520,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="RepeatedHttpSessions" category="Exfiltration" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T01:01:01+00:00" end_time="1970-01-01T01:01:01+00:00" confidence="0.3""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="RepeatedHttpSessions" category="Exfiltration" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T01:01:01+00:00" end_time="1970-01-01T01:01:01+00:00" confidence="0.3""# ); let repeated_http_sessions = Event::RepeatedHttpSessions(RepeatedHttpSessions::new( Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), @@ -4535,7 +4529,7 @@ mod tests { .to_string(); assert_eq!( &repeated_http_sessions, - r#"time="1970-01-01T01:01:01+00:00" event_kind="RepeatedHttpSessions" category="Exfiltration" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T01:01:01+00:00" end_time="1970-01-01T01:01:01+00:00" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="RepeatedHttpSessions" category="Exfiltration" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T01:01:01+00:00" end_time="1970-01-01T01:01:01+00:00" triage_scores="""# ); } @@ -4543,10 +4537,10 @@ mod tests { fn syslog_for_blocklist_kerberos() { let fields = BlocklistKerberosFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 88, proto: 17, @@ -4584,7 +4578,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistKerberos" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="88" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client_time="100" server_time="101" error_code="0" client_realm="EXAMPLE.COM" cname_type="1" client_name="user1" realm="EXAMPLE.COM" sname_type="1" service_name="krbtgt/EXAMPLE.COM" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistKerberos" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="88" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client_time="100" server_time="101" error_code="0" client_realm="EXAMPLE.COM" cname_type="1" client_name="user1" realm="EXAMPLE.COM" sname_type="1" service_name="krbtgt/EXAMPLE.COM" confidence="1""# ); let blocklist_kerberos = Event::Blocklist(RecordType::Kerberos(BlocklistKerberos::new( @@ -4595,7 +4589,7 @@ mod tests { assert_eq!( &blocklist_kerberos, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistKerberos" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="88" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client_time="100" server_time="101" error_code="0" client_realm="EXAMPLE.COM" cname_type="1" client_name="user1" realm="EXAMPLE.COM" sname_type="1" service_name="krbtgt/EXAMPLE.COM" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistKerberos" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="88" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client_time="100" server_time="101" error_code="0" client_realm="EXAMPLE.COM" cname_type="1" client_name="user1" realm="EXAMPLE.COM" sname_type="1" service_name="krbtgt/EXAMPLE.COM" triage_scores="""# ); } @@ -4603,9 +4597,9 @@ mod tests { fn syslog_for_ldapbruteforce() { let fields = LdapBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4638,7 +4632,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="LdapBruteForce" category="CredentialAccess" sensor="" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_port="389" proto="6" user_pw_list="user1:pw1,user_2:pw2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="LdapBruteForce" category="CredentialAccess" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="389" resp_country_code="XX" proto="6" user_pw_list="user1:pw1,user_2:pw2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# ); let ldap_brute_force = Event::LdapBruteForce(LdapBruteForce::new( @@ -4649,7 +4643,7 @@ mod tests { assert_eq!( &ldap_brute_force, - r#"time="1970-01-01T00:01:01+00:00" event_kind="LdapBruteForce" category="CredentialAccess" orig_addr="127.0.0.1" resp_addr="127.0.0.2" resp_port="389" proto="6" user_pw_list="user1:pw1,user_2:pw2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="LdapBruteForce" category="CredentialAccess" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="389" resp_country_code="XX" proto="6" user_pw_list="user1:pw1,user_2:pw2" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# ); } @@ -4657,10 +4651,10 @@ mod tests { fn syslog_for_ldapplaintext() { let fields = LdapEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4696,7 +4690,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="LdapPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="389" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="LdapPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="389" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" confidence="1""# ); let ldap_plain_text = Event::LdapPlainText(LdapPlainText::new( @@ -4707,17 +4701,17 @@ mod tests { assert_eq!( &ldap_plain_text, - r#"time="1970-01-01T01:01:01+00:00" event_kind="LdapPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="389" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="LdapPlainText" category="LateralMovement" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="389" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" triage_scores="""# ); } fn ldapeventfields() -> LdapEventFields { LdapEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, proto: 6, @@ -4758,7 +4752,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistLdap" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="389" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistLdap" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="389" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" message_id="1" version="3" opcode="bind" result="success" diagnostic_message="msg" object="object" argument="argument" confidence="1""# ); let blocklist_ldap = Event::Blocklist(RecordType::Ldap(BlocklistLdap::new( @@ -4843,10 +4837,10 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1812, proto: 17, @@ -4978,10 +4972,10 @@ mod tests { fn syslog_for_blocklist_mqtt() { let fields = BlocklistMqttFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1883, proto: 6, @@ -5016,7 +5010,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMqtt" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="1883" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="mqtt" version="211" client_id="client1" connack_reason="0" subscribe="topic" suback_reason="error" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMqtt" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="1883" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="mqtt" version="211" client_id="client1" connack_reason="0" subscribe="topic" suback_reason="error" confidence="1""# ); let blocklist_mqtt = Event::Blocklist(RecordType::Mqtt(BlocklistMqtt::new( @@ -5027,7 +5021,7 @@ mod tests { assert_eq!( &blocklist_mqtt, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMqtt" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="1883" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="mqtt" version="211" client_id="client1" connack_reason="0" subscribe="topic" suback_reason="error" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMqtt" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="1883" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="mqtt" version="211" client_id="client1" connack_reason="0" subscribe="topic" suback_reason="error" triage_scores="""# ); } @@ -5036,11 +5030,11 @@ mod tests { let fields = NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, service: "http".to_string(), @@ -5072,7 +5066,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="NetworkThreat" category="Reconnaissance" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="80" proto="6" service="http" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" content="content" db_name="db_name" rule_id="1" matched_to="matched_to" cluster_id="1" attack_kind="attack_kind" confidence="0.9""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="NetworkThreat" category="Reconnaissance" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="80" resp_country_code="XX" proto="6" service="http" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" content="content" db_name="db_name" rule_id="1" matched_to="matched_to" cluster_id="1" attack_kind="attack_kind" confidence="0.9""# ); } @@ -5080,10 +5074,10 @@ mod tests { fn syslog_for_blocklist_nfs() { let fields = BlocklistNfsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 2049, proto: 6, @@ -5114,7 +5108,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNfs" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="2049" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" read_files="/etc/passwd" write_files="/etc/shadow" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNfs" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="2049" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" read_files="/etc/passwd" write_files="/etc/shadow" confidence="1""# ); let blocklist_nfs = Event::Blocklist(RecordType::Nfs(BlocklistNfs::new( @@ -5125,7 +5119,7 @@ mod tests { assert_eq!( &blocklist_nfs, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNfs" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="2049" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" read_files="/etc/passwd" write_files="/etc/shadow" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNfs" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="2049" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" read_files="/etc/passwd" write_files="/etc/shadow" triage_scores="""# ); } @@ -5133,10 +5127,10 @@ mod tests { fn syslog_for_blocklist_ntlm() { let fields = BlocklistNtlmFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5170,7 +5164,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNtlm" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="445" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="ntlm" username="user1" hostname="host1" domainname="domain1" success="true" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNtlm" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="445" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="ntlm" username="user1" hostname="host1" domainname="domain1" success="true" confidence="1""# ); let blocklist_ntlm = Event::Blocklist(RecordType::Ntlm(BlocklistNtlm::new( @@ -5181,7 +5175,7 @@ mod tests { assert_eq!( &blocklist_ntlm, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNtlm" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="445" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="ntlm" username="user1" hostname="host1" domainname="domain1" success="true" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistNtlm" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="445" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" protocol="ntlm" username="user1" hostname="host1" domainname="domain1" success="true" triage_scores="""# ); } @@ -5200,7 +5194,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRadius" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="1812" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" id="1" code="1" resp_code="2" auth="auth_string" resp_auth="resp_auth_string" user_name="user1" user_passwd="password" chap_passwd="chap_pass" nas_ip="127.0.0.3" nas_port="5060" state="state" nas_id="nas_identifier" nas_port_type="15" message="RADIUS message" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRadius" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="1812" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" id="1" code="1" resp_code="2" auth="auth_string" resp_auth="resp_auth_string" user_name="user1" user_passwd="password" chap_passwd="chap_pass" nas_ip="127.0.0.3" nas_port="5060" state="state" nas_id="nas_identifier" nas_port_type="15" message="RADIUS message" confidence="1""# ); let blocklist_radius = Event::Blocklist(RecordType::Radius(BlocklistRadius::new( @@ -5211,17 +5205,17 @@ mod tests { assert_eq!( &blocklist_radius, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRadius" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="1812" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" id="1" code="1" resp_code="2" auth="auth_string" resp_auth="resp_auth_string" user_name="user1" user_passwd="password" chap_passwd="chap_pass" nas_ip="127.0.0.3" nas_port="5060" state="state" nas_id="nas_identifier" nas_port_type="15" message="RADIUS message" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRadius" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="1812" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" id="1" code="1" resp_code="2" auth="auth_string" resp_auth="resp_auth_string" user_name="user1" user_passwd="password" chap_passwd="chap_pass" nas_ip="127.0.0.3" nas_port="5060" state="state" nas_id="nas_identifier" nas_port_type="15" message="RADIUS message" triage_scores="""# ); } fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, proto: 17, @@ -5334,7 +5328,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMalformedDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="1000000000" orig_pkts="10" resp_pkts="5" orig_l2_bytes="500" resp_l2_bytes="300" trans_id="1234" flags="33152" question_count="1" answer_count="1" authority_count="0" additional_count="0" query_count="1" resp_count="1" query_bytes="50" resp_bytes="100" query_body="example.com" resp_body="192.0.2.1" confidence="0.95""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMalformedDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="1000000000" orig_pkts="10" resp_pkts="5" orig_l2_bytes="500" resp_l2_bytes="300" trans_id="1234" flags="33152" question_count="1" answer_count="1" authority_count="0" additional_count="0" query_count="1" resp_count="1" query_bytes="50" resp_bytes="100" query_body="example.com" resp_body="192.0.2.1" confidence="0.95""# ); let blocklist_malformed_dns = Event::Blocklist(RecordType::MalformedDns( @@ -5344,7 +5338,7 @@ mod tests { assert_eq!( &blocklist_malformed_dns, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMalformedDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="53" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="1000000000" orig_pkts="10" resp_pkts="5" orig_l2_bytes="500" resp_l2_bytes="300" trans_id="1234" flags="33152" question_count="1" answer_count="1" authority_count="0" additional_count="0" query_count="1" resp_count="1" query_bytes="50" resp_bytes="100" query_body="example.com" resp_body="192.0.2.1" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistMalformedDns" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="53" resp_country_code="XX" proto="17" start_time="1970-01-01T00:00:00+00:00" duration="1000000000" orig_pkts="10" resp_pkts="5" orig_l2_bytes="500" resp_l2_bytes="300" trans_id="1234" flags="33152" question_count="1" answer_count="1" authority_count="0" additional_count="0" query_count="1" resp_count="1" query_bytes="50" resp_bytes="100" query_body="example.com" resp_body="192.0.2.1" triage_scores="""# ); } @@ -5352,9 +5346,9 @@ mod tests { fn syslog_for_rdpbruteforce() { let fields = RdpBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - dst_country_codes: vec![*b"XX", *b"XX"], + resp_country_codes: vec![*b"XX", *b"XX"], resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -5385,7 +5379,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" sensor="" orig_addr="127.0.0.1" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" confidence="0.3""# ); let rdp_brute_force = Event::RdpBruteForce(RdpBruteForce::new( @@ -5396,7 +5390,7 @@ mod tests { assert_eq!( &rdp_brute_force, - r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" orig_addr="127.0.0.1" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" triage_scores="""# ); } @@ -5404,10 +5398,10 @@ mod tests { fn syslog_for_blocklist_rdp() { let fields = BlocklistRdpFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 3389, proto: 6, @@ -5437,7 +5431,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRdp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="3389" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" cookie="cookie" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRdp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="3389" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" cookie="cookie" confidence="1""# ); let blocklist_rdp = Event::Blocklist(RecordType::Rdp(BlocklistRdp::new( @@ -5448,7 +5442,7 @@ mod tests { assert_eq!( &blocklist_rdp, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRdp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="3389" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" cookie="cookie" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistRdp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="3389" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" cookie="cookie" triage_scores="""# ); } @@ -5456,10 +5450,10 @@ mod tests { fn syslog_for_blocklist_smb() { let fields = BlocklistSmbFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, proto: 6, @@ -5499,7 +5493,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmb" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="445" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" command="1" path="path" service="service" file_name="file_name" file_size="100" resource_type="1" fid="1" create_time="100" access_time="200" write_time="300" change_time="400" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmb" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="445" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" command="1" path="path" service="service" file_name="file_name" file_size="100" resource_type="1" fid="1" create_time="100" access_time="200" write_time="300" change_time="400" confidence="1""# ); let blocklist_smb = Event::Blocklist(RecordType::Smb(BlocklistSmb::new( @@ -5510,7 +5504,7 @@ mod tests { assert_eq!( &blocklist_smb, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmb" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="445" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" command="1" path="path" service="service" file_name="file_name" file_size="100" resource_type="1" fid="1" create_time="100" access_time="200" write_time="300" change_time="400" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmb" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="445" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" command="1" path="path" service="service" file_name="file_name" file_size="100" resource_type="1" fid="1" create_time="100" access_time="200" write_time="300" change_time="400" triage_scores="""# ); } @@ -5518,10 +5512,10 @@ mod tests { fn syslog_for_blocklist_smtp() { let fields = BlocklistSmtpFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 25, proto: 6, @@ -5557,7 +5551,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="25" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" mailfrom="mailfrom" date="date" from="from" to="to" subject="subject" agent="agent" state="state" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="25" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" mailfrom="mailfrom" date="date" from="from" to="to" subject="subject" agent="agent" state="state" confidence="1""# ); let blocklist_smtp = Event::Blocklist(RecordType::Smtp(BlocklistSmtp::new( @@ -5568,7 +5562,7 @@ mod tests { assert_eq!( &blocklist_smtp, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="25" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" mailfrom="mailfrom" date="date" from="from" to="to" subject="subject" agent="agent" state="state" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSmtp" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="25" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" mailfrom="mailfrom" date="date" from="from" to="to" subject="subject" agent="agent" state="state" triage_scores="""# ); } @@ -5576,10 +5570,10 @@ mod tests { fn syslog_for_blocklist_ssh() { let fields = BlocklistSshFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 22, proto: 6, @@ -5621,7 +5615,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSsh" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="22" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client="client" server="server" cipher_alg="cipher_alg" mac_alg="mac_alg" compression_alg="compression_alg" kex_alg="kex_alg" host_key_alg="host_key_alg" hassh_algorithms="hassh_algorithms" hassh="hassh" hassh_server_algorithms="hassh_server_algorithms" hassh_server="hassh_server" client_shka="client_shka" server_shka="server_shka" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSsh" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="22" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client="client" server="server" cipher_alg="cipher_alg" mac_alg="mac_alg" compression_alg="compression_alg" kex_alg="kex_alg" host_key_alg="host_key_alg" hassh_algorithms="hassh_algorithms" hassh="hassh" hassh_server_algorithms="hassh_server_algorithms" hassh_server="hassh_server" client_shka="client_shka" server_shka="server_shka" confidence="1""# ); let blocklist_ssh = Event::Blocklist(RecordType::Ssh(BlocklistSsh::new( @@ -5632,7 +5626,7 @@ mod tests { assert_eq!( &blocklist_ssh, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSsh" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="22" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client="client" server="server" cipher_alg="cipher_alg" mac_alg="mac_alg" compression_alg="compression_alg" kex_alg="kex_alg" host_key_alg="host_key_alg" hassh_algorithms="hassh_algorithms" hassh="hassh" hassh_server_algorithms="hassh_server_algorithms" hassh_server="hassh_server" client_shka="client_shka" server_shka="server_shka" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistSsh" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="22" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" client="client" server="server" cipher_alg="cipher_alg" mac_alg="mac_alg" compression_alg="compression_alg" kex_alg="kex_alg" host_key_alg="host_key_alg" hassh_algorithms="hassh_algorithms" hassh="hassh" hassh_server_algorithms="hassh_server_algorithms" hassh_server="hassh_server" client_shka="client_shka" server_shka="server_shka" triage_scores="""# ); } @@ -5694,10 +5688,10 @@ mod tests { fn syslog_for_blocklist_tls() { let fields = BlocklistTlsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5747,7 +5741,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistTls" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistTls" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9""# ); let blocklist_tls = Event::Blocklist(RecordType::Tls(BlocklistTls::new( @@ -5758,7 +5752,7 @@ mod tests { assert_eq!( &blocklist_tls, - r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistTls" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="BlocklistTls" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9" triage_scores="""# ); } @@ -5775,10 +5769,10 @@ mod tests { resp_pkts: 0, orig_l2_bytes: 0, resp_l2_bytes: 0, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5822,7 +5816,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="TorConnection" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="host" uri="uri" referer="referer" version="version" user_agent="user_agent" request_len="100" response_len="200" status_code="200" status_msg="OK" username="user" password="password" cookie="cookie" content_encoding="content_encoding" content_type="content_type" cache_control="cache_control" filenames="filename" mime_types="mime_type" body="post_body" state="state" confidence="1""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="TorConnection" category="CommandAndControl" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" method="GET" host="host" uri="uri" referer="referer" version="version" user_agent="user_agent" request_len="100" response_len="200" status_code="200" status_msg="OK" username="user" password="password" cookie="cookie" content_encoding="content_encoding" content_type="content_type" cache_control="cache_control" filenames="filename" mime_types="mime_type" body="post_body" state="state" confidence="1""# ); let tor_connection = Event::TorConnection(TorConnection::new( @@ -5907,10 +5901,10 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, proto: 6, @@ -5966,7 +5960,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="SuspiciousTlsTraffic" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="SuspiciousTlsTraffic" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9""# ); let suspicious_tls_traffic = @@ -5991,7 +5985,7 @@ mod tests { assert_eq!( &blocklist_tls, - r#"time="1970-01-01T01:01:01+00:00" event_kind="SuspiciousTlsTraffic" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" resp_addr="127.0.0.2" resp_port="443" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="SuspiciousTlsTraffic" category="InitialAccess" sensor="collector1" orig_addr="127.0.0.1" orig_port="10000" orig_country_code="XX" resp_addr="127.0.0.2" resp_port="443" resp_country_code="XX" proto="6" start_time="1970-01-01T00:00:00+00:00" duration="0" orig_pkts="0" resp_pkts="0" orig_l2_bytes="0" resp_l2_bytes="0" server_name="server" alpn_protocol="alpn" ja3="ja3" version="version" client_cipher_suites="1,2,3" client_extensions="4,5,6" cipher="1" extensions="7,8,9" ja3s="ja3s" serial="serial" subject_country="country" subject_org_name="org" subject_common_name="common" validity_not_before="100" validity_not_after="200" subject_alt_name="alt" issuer_country="country" issuer_org_name="org" issuer_org_unit_name="unit" issuer_common_name="common" last_alert="1" confidence="0.9" triage_scores="""# ); } diff --git a/src/event/bootp.rs b/src/event/bootp.rs index 22de9cdb..8099faa9 100644 --- a/src/event/bootp.rs +++ b/src/event/bootp.rs @@ -40,14 +40,14 @@ macro_rules! find_bootp_attr_by_kind { }}; } -pub type BlocklistBootpFields = BlocklistBootpFieldsV0_43; +pub type BlocklistBootpFields = BlocklistBootpFieldsV0_44; impl BlocklistBootpFields { #[must_use] pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -55,8 +55,10 @@ impl BlocklistBootpFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -81,14 +83,14 @@ impl BlocklistBootpFields { } #[derive(Serialize, Deserialize)] -pub struct BlocklistBootpFieldsV0_43 { +pub struct BlocklistBootpFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -116,11 +118,11 @@ pub struct BlocklistBootpFieldsV0_43 { pub struct BlocklistBootp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -148,12 +150,14 @@ impl fmt::Display for BlocklistBootp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -182,11 +186,11 @@ impl BlocklistBootp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/common.rs b/src/event/common.rs index db383625..46eeba29 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -1604,11 +1604,11 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 67, proto: 17, start_time: Utc @@ -1640,11 +1640,11 @@ mod tests { fn blocklist_conn_fields() -> BlocklistConnFields { BlocklistConnFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, conn_state: "SAF".to_string(), @@ -1669,11 +1669,11 @@ mod tests { fn blocklist_dcerpc_fields() -> BlocklistDceRpcFields { BlocklistDceRpcFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 135, proto: 6, start_time: Utc @@ -1698,11 +1698,11 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 67, proto: 17, start_time: Utc @@ -1742,11 +1742,11 @@ mod tests { fn blocklist_dns_fields() -> BlocklistDnsFields { BlocklistDnsFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -1779,11 +1779,11 @@ mod tests { fn blocklist_http_fields() -> BlocklistHttpFields { BlocklistHttpFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -1824,11 +1824,11 @@ mod tests { fn blocklist_kerberos_fields() -> BlocklistKerberosFields { BlocklistKerberosFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 88, proto: 17, start_time: Utc @@ -1858,11 +1858,11 @@ mod tests { fn blocklist_mqtt_fields() -> BlocklistMqttFields { BlocklistMqttFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 1883, proto: 6, start_time: Utc @@ -1889,11 +1889,11 @@ mod tests { fn blocklist_nfs_fields() -> BlocklistNfsFields { BlocklistNfsFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 2049, proto: 6, start_time: Utc @@ -1916,11 +1916,11 @@ mod tests { fn blocklist_ntlm_fields() -> BlocklistNtlmFields { BlocklistNtlmFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 445, proto: 6, start_time: Utc @@ -1946,11 +1946,11 @@ mod tests { fn blocklist_rdp_fields() -> BlocklistRdpFields { BlocklistRdpFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 3389, proto: 6, start_time: Utc @@ -1972,11 +1972,11 @@ mod tests { fn blocklist_smb_fields() -> BlocklistSmbFields { BlocklistSmbFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 445, proto: 6, start_time: Utc @@ -2008,11 +2008,11 @@ mod tests { fn blocklist_smtp_fields() -> BlocklistSmtpFields { BlocklistSmtpFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 25, proto: 6, start_time: Utc @@ -2040,11 +2040,11 @@ mod tests { fn blocklist_ssh_fields() -> BlocklistSshFields { BlocklistSshFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 22, proto: 6, start_time: Utc @@ -2078,11 +2078,11 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 443, proto: 6, start_time: Utc @@ -2124,11 +2124,11 @@ mod tests { fn ldap_event_fields() -> LdapEventFields { LdapEventFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 389, proto: 6, start_time: Utc @@ -2171,11 +2171,11 @@ mod tests { FtpEventFields { sensor: "collector1".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 21, proto: 6, start_time: Utc @@ -2199,10 +2199,10 @@ mod tests { fn port_scan_fields() -> PortScanFields { PortScanFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2223,13 +2223,13 @@ mod tests { fn multi_host_port_scan_fields() -> MultiHostPortScanFields { MultiHostPortScanFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![*b"XX", *b"XX"], + resp_country_codes: vec![*b"XX", *b"XX"], resp_port: 80, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2254,9 +2254,9 @@ mod tests { IpAddr::V4(Ipv4Addr::LOCALHOST), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - src_country_codes: vec![*b"XX", *b"XX"], + orig_country_codes: vec![*b"XX", *b"XX"], resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2276,11 +2276,11 @@ mod tests { fn crypto_miining_pool_fields() -> CryptocurrencyMiningPoolFields { CryptocurrencyMiningPoolFields { sensor: "sensro".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2314,10 +2314,10 @@ mod tests { fn ftp_brute_force_fields() -> FtpBruteForceFields { FtpBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 21, proto: 6, user_list: vec!["user1".to_string(), "user_2".to_string()], @@ -2341,11 +2341,11 @@ mod tests { let now = chrono::Utc::now().timestamp_nanos_opt().unwrap(); RepeatedHttpSessionsFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 443, proto: 6, start_time: now, @@ -2358,11 +2358,11 @@ mod tests { fn dga_fields() -> DgaFields { DgaFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2403,11 +2403,11 @@ mod tests { fn http_event_fields() -> HttpEventFields { HttpEventFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2448,10 +2448,10 @@ mod tests { fn ldap_brute_force_fields() -> LdapBruteForceFields { LdapBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 389, proto: 6, user_pw_list: vec![ @@ -2476,13 +2476,13 @@ mod tests { fn rdp_brute_force_fields() -> RdpBruteForceFields { RdpBruteForceFields { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - dst_country_codes: vec![*b"XX", *b"XX"], + resp_country_codes: vec![*b"XX", *b"XX"], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2502,11 +2502,11 @@ mod tests { fn dns_event_fields() -> DnsEventFields { DnsEventFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2540,11 +2540,11 @@ mod tests { NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, service: "http".to_string(), @@ -2610,11 +2610,11 @@ mod tests { HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 80, proto: 6, start_time: Utc @@ -2659,11 +2659,11 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 1812, proto: 17, start_time: Utc @@ -2698,11 +2698,11 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: 53, proto: 17, start_time: Utc @@ -2746,7 +2746,7 @@ mod tests { .timestamp_nanos_opt() .unwrap(), destination_ips: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))], - dst_country_codes: vec![*b"XX"], + resp_country_codes: vec![*b"XX"], count: 1, expected_mean: 0.0, std_deviation: 0.0, diff --git a/src/event/conn.rs b/src/event/conn.rs index 8e9b4a43..c21ca865 100644 --- a/src/event/conn.rs +++ b/src/event/conn.rs @@ -35,15 +35,15 @@ macro_rules! find_conn_attr_by_kind { } pub(crate) use find_conn_attr_by_kind; -pub type PortScanFields = PortScanFieldsV0_43; +pub type PortScanFields = PortScanFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct PortScanFieldsV0_43 { +pub struct PortScanFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_ports: Vec, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -60,14 +60,16 @@ impl PortScanFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} resp_addr={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_country_code={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), vector_to_string(&self.resp_ports), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), @@ -82,10 +84,10 @@ impl PortScanFields { pub struct PortScan { pub sensor: String, pub time: DateTime, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_ports: Vec, pub start_time: DateTime, pub end_time: DateTime, @@ -99,9 +101,11 @@ impl fmt::Display for PortScan { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addr={:?} resp_addr={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_country_code={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), vector_to_string(&self.resp_ports), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), @@ -116,10 +120,10 @@ impl PortScan { PortScan { sensor: fields.sensor.clone(), time, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_ports: fields.resp_ports.clone(), proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -192,16 +196,16 @@ impl Match for PortScan { } } -pub type MultiHostPortScanFields = MultiHostPortScanFieldsV0_43; +pub type MultiHostPortScanFields = MultiHostPortScanFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct MultiHostPortScanFieldsV0_43 { +pub struct MultiHostPortScanFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, - pub resp_port: u16, + pub orig_country_code: [u8; 2], pub resp_addrs: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, + pub resp_port: u16, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -217,13 +221,14 @@ impl MultiHostPortScanFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), self.resp_port.to_string(), self.proto.to_string(), @@ -239,11 +244,11 @@ impl MultiHostPortScanFields { pub struct MultiHostPortScan { pub sensor: String, pub time: DateTime, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_port: u16, pub resp_addrs: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -256,8 +261,9 @@ impl fmt::Display for MultiHostPortScan { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addr={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), self.resp_port.to_string(), self.proto.to_string(), @@ -273,11 +279,11 @@ impl MultiHostPortScan { MultiHostPortScan { sensor: fields.sensor.clone(), time, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, resp_port: fields.resp_port, resp_addrs: fields.resp_addrs.clone(), - dst_country_codes: fields.dst_country_codes.clone(), + resp_country_codes: fields.resp_country_codes.clone(), proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -350,15 +356,15 @@ impl Match for MultiHostPortScan { } } -pub type ExternalDdosFields = ExternalDdosFieldsV0_43; +pub type ExternalDdosFields = ExternalDdosFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct ExternalDdosFieldsV0_43 { +pub struct ExternalDdosFieldsV0_44 { pub sensor: String, pub orig_addrs: Vec, - pub src_country_codes: Vec<[u8; 2]>, + pub orig_country_codes: Vec<[u8; 2]>, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -374,7 +380,7 @@ impl ExternalDdosFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addrs={:?} resp_addr={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addrs={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -382,6 +388,7 @@ impl ExternalDdosFields { self.sensor, vector_to_string(&self.orig_addrs), self.resp_addr.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), @@ -396,9 +403,9 @@ pub struct ExternalDdos { pub sensor: String, pub time: DateTime, pub orig_addrs: Vec, - pub src_country_codes: Vec<[u8; 2]>, + pub orig_country_codes: Vec<[u8; 2]>, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -411,9 +418,10 @@ impl fmt::Display for ExternalDdos { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addrs={:?} resp_addr={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "orig_addrs={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", vector_to_string(&self.orig_addrs), self.resp_addr.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), @@ -428,9 +436,9 @@ impl ExternalDdos { sensor: fields.sensor.clone(), time, orig_addrs: fields.orig_addrs.clone(), - src_country_codes: fields.src_country_codes.clone(), + orig_country_codes: fields.orig_country_codes.clone(), resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -502,17 +510,17 @@ impl Match for ExternalDdos { } } -pub type BlocklistConnFields = BlocklistConnFieldsV0_43; +pub type BlocklistConnFields = BlocklistConnFieldsV0_44; #[derive(Deserialize, Serialize)] -pub struct BlocklistConnFieldsV0_43 { +pub struct BlocklistConnFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub conn_state: String, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -535,7 +543,7 @@ impl BlocklistConnFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} conn_state={:?} start_time={:?} duration={:?} service={:?} orig_bytes={:?} resp_bytes={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} conn_state={:?} start_time={:?} duration={:?} service={:?} orig_bytes={:?} resp_bytes={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -543,8 +551,10 @@ impl BlocklistConnFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.conn_state, start_time_dt.to_rfc3339(), @@ -565,11 +575,11 @@ impl BlocklistConnFields { pub struct BlocklistConn { pub sensor: String, pub time: DateTime, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub conn_state: String, @@ -591,12 +601,14 @@ impl fmt::Display for BlocklistConn { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} conn_state={:?} start_time={:?} duration={:?} service={:?} orig_bytes={:?} resp_bytes={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} conn_state={:?} start_time={:?} duration={:?} service={:?} orig_bytes={:?} resp_bytes={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.conn_state, self.start_time.to_rfc3339(), @@ -618,11 +630,11 @@ impl BlocklistConn { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, conn_state: fields.conn_state, diff --git a/src/event/dcerpc.rs b/src/event/dcerpc.rs index b41ac3be..3ac3f1d0 100644 --- a/src/event/dcerpc.rs +++ b/src/event/dcerpc.rs @@ -7,17 +7,17 @@ use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; use crate::event::common::{AttrValue, triage_scores_to_string}; -pub type BlocklistDceRpcFields = BlocklistDceRpcFieldsV0_43; +pub type BlocklistDceRpcFields = BlocklistDceRpcFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistDceRpcFieldsV0_43 { +pub struct BlocklistDceRpcFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -39,7 +39,7 @@ impl BlocklistDceRpcFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} rtt={:?} named_pipe={:?} endpoint={:?} operation={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} rtt={:?} named_pipe={:?} endpoint={:?} operation={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -47,8 +47,10 @@ impl BlocklistDceRpcFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -68,11 +70,11 @@ impl BlocklistDceRpcFields { pub struct BlocklistDceRpc { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -94,12 +96,14 @@ impl fmt::Display for BlocklistDceRpc { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} rtt={:?} named_pipe={:?} endpoint={:?} operation={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} rtt={:?} named_pipe={:?} endpoint={:?} operation={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -121,11 +125,11 @@ impl BlocklistDceRpc { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/dhcp.rs b/src/event/dhcp.rs index 9bb52948..4673469d 100644 --- a/src/event/dhcp.rs +++ b/src/event/dhcp.rs @@ -58,17 +58,17 @@ macro_rules! find_dhcp_attr_by_kind { }}; } -pub type BlocklistDhcpFields = BlocklistDhcpFieldsV0_43; +pub type BlocklistDhcpFields = BlocklistDhcpFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistDhcpFieldsV0_43 { +pub struct BlocklistDhcpFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -109,7 +109,7 @@ impl BlocklistDhcpFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} msg_type={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} subnet_mask={:?} router={:?} domain_name_server={:?} req_ip_addr={:?} lease_time={:?} server_id={:?} param_req_list={:?} message={:?} renewal_time={:?} rebinding_time={:?} class_id={:?} client_id_type={:?} client_id={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} msg_type={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} subnet_mask={:?} router={:?} domain_name_server={:?} req_ip_addr={:?} lease_time={:?} server_id={:?} param_req_list={:?} message={:?} renewal_time={:?} rebinding_time={:?} class_id={:?} client_id_type={:?} client_id={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -117,8 +117,10 @@ impl BlocklistDhcpFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -155,11 +157,11 @@ impl BlocklistDhcpFields { pub struct BlocklistDhcp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -194,12 +196,14 @@ impl fmt::Display for BlocklistDhcp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} msg_type={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} subnet_mask={:?} router={:?} domain_name_server={:?} req_ip_addr={:?} lease_time={:?} server_id={:?} param_req_list={:?} message={:?} renewal_time={:?} rebinding_time={:?} class_id={:?} client_id_type={:?} client_id={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} msg_type={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} subnet_mask={:?} router={:?} domain_name_server={:?} req_ip_addr={:?} lease_time={:?} server_id={:?} param_req_list={:?} message={:?} renewal_time={:?} rebinding_time={:?} class_id={:?} client_id_type={:?} client_id={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -237,11 +241,11 @@ impl BlocklistDhcp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/dns.rs b/src/event/dns.rs index a7ccddcf..0750e99a 100644 --- a/src/event/dns.rs +++ b/src/event/dns.rs @@ -47,17 +47,17 @@ macro_rules! find_dns_attr_by_kind { }}; } -pub type DnsEventFields = DnsEventFieldsV0_43; +pub type DnsEventFields = DnsEventFieldsV0_44; #[derive(Deserialize, Serialize)] -pub struct DnsEventFieldsV0_43 { +pub struct DnsEventFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -87,7 +87,7 @@ impl DnsEventFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -95,8 +95,10 @@ impl DnsEventFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -125,11 +127,11 @@ impl DnsEventFields { pub struct DnsCovertChannel { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -159,12 +161,14 @@ impl fmt::Display for DnsCovertChannel { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -195,7 +199,7 @@ impl DnsCovertChannel { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -205,7 +209,7 @@ impl DnsCovertChannel { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -301,11 +305,11 @@ impl Match for DnsCovertChannel { pub struct LockyRansomware { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -335,12 +339,14 @@ impl fmt::Display for LockyRansomware { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -371,7 +377,7 @@ impl LockyRansomware { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -381,7 +387,7 @@ impl LockyRansomware { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -473,17 +479,17 @@ impl Match for LockyRansomware { } } -pub type CryptocurrencyMiningPoolFields = CryptocurrencyMiningPoolFieldsV0_43; +pub type CryptocurrencyMiningPoolFields = CryptocurrencyMiningPoolFieldsV0_44; #[derive(Deserialize, Serialize)] -pub struct CryptocurrencyMiningPoolFieldsV0_43 { +pub struct CryptocurrencyMiningPoolFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -514,7 +520,7 @@ impl CryptocurrencyMiningPoolFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} coins={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} coins={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -522,8 +528,10 @@ impl CryptocurrencyMiningPoolFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -553,11 +561,11 @@ impl CryptocurrencyMiningPoolFields { pub struct CryptocurrencyMiningPool { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -588,12 +596,14 @@ impl fmt::Display for CryptocurrencyMiningPool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} coins={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} coins={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -624,7 +634,7 @@ impl CryptocurrencyMiningPool { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -634,7 +644,7 @@ impl CryptocurrencyMiningPool { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, query: fields.query, @@ -727,17 +737,17 @@ impl Match for CryptocurrencyMiningPool { } } -pub type BlocklistDnsFields = BlocklistDnsFieldsV0_43; +pub type BlocklistDnsFields = BlocklistDnsFieldsV0_44; #[derive(Deserialize, Serialize)] -pub struct BlocklistDnsFieldsV0_43 { +pub struct BlocklistDnsFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -767,7 +777,7 @@ impl BlocklistDnsFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -775,8 +785,10 @@ impl BlocklistDnsFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -805,11 +817,11 @@ impl BlocklistDnsFields { pub struct BlocklistDns { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -839,12 +851,14 @@ impl fmt::Display for BlocklistDns { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} query={:?} answer={:?} trans_id={:?} rtt={:?} qclass={:?} qtype={:?} rcode={:?} aa_flag={:?} tc_flag={:?} rd_flag={:?} ra_flag={:?} ttl={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -874,12 +888,12 @@ impl BlocklistDns { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/ftp.rs b/src/event/ftp.rs index 48fc8c76..534ffe60 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -159,7 +159,7 @@ macro_rules! find_ftp_attr_by_kind { }}; } -pub type FtpBruteForceFields = FtpBruteForceFieldsV0_43; +pub type FtpBruteForceFields = FtpBruteForceFieldsV0_44; impl FtpBruteForceFields { #[must_use] @@ -167,15 +167,17 @@ impl FtpBruteForceFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} resp_addr={:?} resp_port={:?} proto={:?} user_list={:?} start_time={:?} end_time={:?} is_internal={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} user_list={:?} start_time={:?} end_time={:?} is_internal={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.user_list.join(","), start_time_dt.to_rfc3339(), @@ -187,13 +189,13 @@ impl FtpBruteForceFields { } #[derive(Serialize, Deserialize)] -pub struct FtpBruteForceFieldsV0_43 { +pub struct FtpBruteForceFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub user_list: Vec, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -205,14 +207,14 @@ pub struct FtpBruteForceFieldsV0_43 { pub category: Option, } -impl From for FtpBruteForceFieldsV0_43 { +impl From for FtpBruteForceFieldsV0_44 { fn from(value: FtpBruteForceFieldsV0_41) -> Self { Self { sensor: String::new(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: value.src_addr, resp_addr: value.dst_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: value.dst_port, proto: value.proto, user_list: value.user_list, @@ -242,11 +244,11 @@ pub(crate) struct FtpBruteForceFieldsV0_41 { #[derive(Serialize, Deserialize)] pub struct FtpBruteForce { pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_list: Vec, @@ -262,10 +264,12 @@ impl fmt::Display for FtpBruteForce { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "orig_addr={:?} resp_addr={:?} resp_port={:?} proto={:?} user_list={:?} start_time={:?} end_time={:?} is_internal={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} user_list={:?} start_time={:?} end_time={:?} is_internal={:?} triage_scores={:?}", self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.user_list.join(","), self.start_time.to_rfc3339(), @@ -280,11 +284,11 @@ impl FtpBruteForce { pub(super) fn new(time: DateTime, fields: &FtpBruteForceFields) -> Self { FtpBruteForce { sensor: fields.sensor.clone(), - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, time, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, user_list: fields.user_list.clone(), @@ -361,7 +365,7 @@ impl Match for FtpBruteForce { } } -pub type FtpEventFields = FtpEventFieldsV0_43; +pub type FtpEventFields = FtpEventFieldsV0_44; impl FtpEventFields { #[must_use] @@ -375,7 +379,7 @@ impl FtpEventFields { .join(";"); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -383,8 +387,10 @@ impl FtpEventFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -401,14 +407,14 @@ impl FtpEventFields { } #[derive(Debug, Deserialize, Serialize)] -pub struct FtpEventFieldsV0_43 { +pub struct FtpEventFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -428,11 +434,11 @@ pub struct FtpEventFieldsV0_43 { pub struct FtpPlainText { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -460,12 +466,14 @@ impl fmt::Display for FtpPlainText { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -486,12 +494,12 @@ impl FtpPlainText { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -563,11 +571,11 @@ impl Match for FtpPlainText { pub struct BlocklistFtp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -595,12 +603,14 @@ impl fmt::Display for BlocklistFtp { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} user={:?} password={:?} commands={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -621,12 +631,12 @@ impl BlocklistFtp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/http.rs b/src/event/http.rs index 66e7711b..bf284961 100644 --- a/src/event/http.rs +++ b/src/event/http.rs @@ -59,17 +59,17 @@ macro_rules! find_http_attr_by_kind { } pub(super) use find_http_attr_by_kind; -pub type HttpEventFields = HttpEventFieldsV0_43; +pub type HttpEventFields = HttpEventFieldsV0_44; #[derive(Deserialize, Serialize)] -pub struct HttpEventFieldsV0_43 { +pub struct HttpEventFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -107,7 +107,7 @@ impl HttpEventFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -115,8 +115,10 @@ impl HttpEventFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -149,17 +151,17 @@ impl HttpEventFields { } } -pub type RepeatedHttpSessionsFields = RepeatedHttpSessionsFieldsV0_43; +pub type RepeatedHttpSessionsFields = RepeatedHttpSessionsFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct RepeatedHttpSessionsFieldsV0_43 { +pub struct RepeatedHttpSessionsFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -175,7 +177,7 @@ impl RepeatedHttpSessionsFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -183,8 +185,10 @@ impl RepeatedHttpSessionsFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), @@ -197,11 +201,11 @@ impl RepeatedHttpSessionsFields { pub struct RepeatedHttpSessions { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -215,12 +219,14 @@ impl fmt::Display for RepeatedHttpSessions { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), @@ -234,11 +240,11 @@ impl RepeatedHttpSessions { RepeatedHttpSessions { time, sensor: fields.sensor.clone(), - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -311,20 +317,20 @@ impl Match for RepeatedHttpSessions { } } -pub type HttpThreatFields = HttpThreatFieldsV0_43; +pub type HttpThreatFields = HttpThreatFieldsV0_44; #[derive(Debug, Deserialize, Serialize)] #[allow(clippy::module_name_repetitions)] -pub struct HttpThreatFieldsV0_43 { +pub struct HttpThreatFieldsV0_44 { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -367,7 +373,7 @@ impl HttpThreatFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -375,8 +381,10 @@ impl HttpThreatFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -435,11 +443,11 @@ pub struct HttpThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -482,12 +490,14 @@ impl fmt::Display for HttpThreat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -531,12 +541,12 @@ impl HttpThreat { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -666,17 +676,17 @@ impl Match for HttpThreat { } } -pub type DgaFields = DgaFieldsV0_43; +pub type DgaFields = DgaFieldsV0_44; #[derive(Debug, Deserialize, Serialize)] -pub struct DgaFieldsV0_43 { +pub struct DgaFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -714,7 +724,7 @@ impl DgaFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -722,8 +732,10 @@ impl DgaFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -761,11 +773,11 @@ pub struct DomainGenerationAlgorithm { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -803,12 +815,14 @@ impl fmt::Display for DomainGenerationAlgorithm { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -847,12 +861,12 @@ impl DomainGenerationAlgorithm { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -956,11 +970,11 @@ impl Match for DomainGenerationAlgorithm { pub struct NonBrowser { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -998,12 +1012,14 @@ impl fmt::Display for NonBrowser { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -1041,7 +1057,7 @@ impl NonBrowser { NonBrowser { time, sensor: fields.sensor.clone(), - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -1051,7 +1067,7 @@ impl NonBrowser { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, method: fields.method.clone(), @@ -1154,11 +1170,11 @@ pub type BlocklistHttpFields = DgaFields; pub struct BlocklistHttp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -1196,12 +1212,14 @@ impl fmt::Display for BlocklistHttp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} method={:?} host={:?} uri={:?} referer={:?} version={:?} user_agent={:?} request_len={:?} response_len={:?} status_code={:?} status_msg={:?} username={:?} password={:?} cookie={:?} content_encoding={:?} content_type={:?} cache_control={:?} filenames={:?} mime_types={:?} body={:?} state={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -1239,12 +1257,12 @@ impl BlocklistHttp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/kerberos.rs b/src/event/kerberos.rs index 8074d7e7..bc94fbcd 100644 --- a/src/event/kerberos.rs +++ b/src/event/kerberos.rs @@ -42,17 +42,17 @@ macro_rules! find_kerberos_attr_by_kind { }}; } -pub type BlocklistKerberosFields = BlocklistKerberosFieldsV0_43; +pub type BlocklistKerberosFields = BlocklistKerberosFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistKerberosFieldsV0_43 { +pub struct BlocklistKerberosFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -79,7 +79,7 @@ impl BlocklistKerberosFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client_time={:?} server_time={:?} error_code={:?} client_realm={:?} cname_type={:?} client_name={:?} realm={:?} sname_type={:?} service_name={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client_time={:?} server_time={:?} error_code={:?} client_realm={:?} cname_type={:?} client_name={:?} realm={:?} sname_type={:?} service_name={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -87,8 +87,10 @@ impl BlocklistKerberosFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -114,11 +116,11 @@ impl BlocklistKerberosFields { pub struct BlocklistKerberos { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -145,12 +147,14 @@ impl fmt::Display for BlocklistKerberos { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client_time={:?} server_time={:?} error_code={:?} client_realm={:?} cname_type={:?} client_name={:?} realm={:?} sname_type={:?} service_name={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client_time={:?} server_time={:?} error_code={:?} client_realm={:?} cname_type={:?} client_name={:?} realm={:?} sname_type={:?} service_name={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -177,11 +181,11 @@ impl BlocklistKerberos { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ldap.rs b/src/event/ldap.rs index 55ae6e40..1e3c6f5e 100644 --- a/src/event/ldap.rs +++ b/src/event/ldap.rs @@ -47,16 +47,16 @@ macro_rules! find_ldap_attr_by_kind { }}; } -pub type LdapBruteForceFields = LdapBruteForceFieldsV0_43; +pub type LdapBruteForceFields = LdapBruteForceFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct LdapBruteForceFieldsV0_43 { +pub struct LdapBruteForceFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub user_pw_list: Vec<(String, String)>, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -73,15 +73,17 @@ impl LdapBruteForceFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} resp_addr={:?} resp_port={:?} proto={:?} user_pw_list={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} user_pw_list={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), get_user_pw_list(&self.user_pw_list), start_time_dt.to_rfc3339(), @@ -106,11 +108,11 @@ fn get_user_pw_list(user_pw_list: &[(String, String)]) -> String { #[derive(Serialize, Deserialize)] pub struct LdapBruteForce { pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub user_pw_list: Vec<(String, String)>, @@ -125,10 +127,12 @@ impl fmt::Display for LdapBruteForce { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "orig_addr={:?} resp_addr={:?} resp_port={:?} proto={:?} user_pw_list={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} user_pw_list={:?} start_time={:?} end_time={:?} triage_scores={:?}", self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), get_user_pw_list(&self.user_pw_list), self.start_time.to_rfc3339(), @@ -142,11 +146,11 @@ impl LdapBruteForce { pub(super) fn new(time: DateTime, fields: &LdapBruteForceFields) -> Self { LdapBruteForce { sensor: fields.sensor.clone(), - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, time, orig_addr: fields.orig_addr, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, user_pw_list: fields.user_pw_list.clone(), @@ -219,17 +223,17 @@ impl Match for LdapBruteForce { } } -pub type LdapEventFields = LdapEventFieldsV0_43; +pub type LdapEventFields = LdapEventFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct LdapEventFieldsV0_43 { +pub struct LdapEventFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -254,7 +258,7 @@ impl LdapEventFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} message_id={:?} version={:?} opcode={:?} result={:?} diagnostic_message={:?} object={:?} argument={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} message_id={:?} version={:?} opcode={:?} result={:?} diagnostic_message={:?} object={:?} argument={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -262,8 +266,10 @@ impl LdapEventFields { self.sensor.clone(), self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -287,11 +293,11 @@ impl LdapEventFields { pub struct LdapPlainText { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -316,12 +322,14 @@ impl fmt::Display for LdapPlainText { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} message_id={:?} version={:?} opcode={:?} result={:?} diagnostic_message={:?} object={:?} argument={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} message_id={:?} version={:?} opcode={:?} result={:?} diagnostic_message={:?} object={:?} argument={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -346,12 +354,12 @@ impl LdapPlainText { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, @@ -427,11 +435,11 @@ impl Match for LdapPlainText { pub struct BlocklistLdap { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -486,12 +494,12 @@ impl BlocklistLdap { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/malformed_dns.rs b/src/event/malformed_dns.rs index 16741be3..ff7ecf42 100644 --- a/src/event/malformed_dns.rs +++ b/src/event/malformed_dns.rs @@ -31,17 +31,17 @@ macro_rules! find_malformed_dns_attr_by_kind { }}; } -pub type BlocklistMalformedDnsFields = BlocklistMalformedDnsFieldsV0_43; +pub type BlocklistMalformedDnsFields = BlocklistMalformedDnsFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistMalformedDnsFieldsV0_43 { +pub struct BlocklistMalformedDnsFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -71,7 +71,7 @@ impl BlocklistMalformedDnsFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} trans_id={:?} flags={:?} question_count={:?} answer_count={:?} authority_count={:?} additional_count={:?} query_count={:?} resp_count={:?} query_bytes={:?} resp_bytes={:?} query_body={:?} resp_body={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} trans_id={:?} flags={:?} question_count={:?} answer_count={:?} authority_count={:?} additional_count={:?} query_count={:?} resp_count={:?} query_bytes={:?} resp_bytes={:?} query_body={:?} resp_body={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -79,8 +79,10 @@ impl BlocklistMalformedDnsFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -116,11 +118,11 @@ fn format_vec_vec_u8(data: &[Vec]) -> String { pub struct BlocklistMalformedDns { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -152,12 +154,14 @@ impl fmt::Display for BlocklistMalformedDns { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} trans_id={:?} flags={:?} question_count={:?} answer_count={:?} authority_count={:?} additional_count={:?} query_count={:?} resp_count={:?} query_bytes={:?} resp_bytes={:?} query_body={:?} resp_body={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} trans_id={:?} flags={:?} question_count={:?} answer_count={:?} authority_count={:?} additional_count={:?} query_count={:?} resp_count={:?} query_bytes={:?} resp_bytes={:?} query_body={:?} resp_body={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_str, self.duration.to_string(), @@ -187,11 +191,11 @@ impl BlocklistMalformedDns { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/mqtt.rs b/src/event/mqtt.rs index bfebde9f..97bc7342 100644 --- a/src/event/mqtt.rs +++ b/src/event/mqtt.rs @@ -43,17 +43,17 @@ macro_rules! find_mqtt_attr_by_kind { }}; } -pub type BlocklistMqttFields = BlocklistMqttFieldsV0_43; +pub type BlocklistMqttFields = BlocklistMqttFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistMqttFieldsV0_43 { +pub struct BlocklistMqttFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -78,7 +78,7 @@ impl BlocklistMqttFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} version={:?} client_id={:?} connack_reason={:?} subscribe={:?} suback_reason={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} version={:?} client_id={:?} connack_reason={:?} subscribe={:?} suback_reason={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -86,8 +86,10 @@ impl BlocklistMqttFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -110,11 +112,11 @@ impl BlocklistMqttFields { pub struct BlocklistMqtt { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -138,12 +140,14 @@ impl fmt::Display for BlocklistMqtt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} version={:?} client_id={:?} connack_reason={:?} subscribe={:?} suback_reason={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} version={:?} client_id={:?} connack_reason={:?} subscribe={:?} suback_reason={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -167,11 +171,11 @@ impl BlocklistMqtt { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/network.rs b/src/event/network.rs index 7e581b27..888c925c 100644 --- a/src/event/network.rs +++ b/src/event/network.rs @@ -38,14 +38,14 @@ pub struct NetworkThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - #[serde(default)] - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, - pub resp_addr: IpAddr, #[serde(default)] - pub dst_country_code: [u8; 2], + pub orig_country_code: [u8; 2], + pub resp_addr: IpAddr, pub resp_port: u16, + #[serde(default)] + pub resp_country_code: [u8; 2], pub proto: u8, pub service: String, #[serde(with = "ts_nanoseconds")] @@ -70,7 +70,7 @@ impl NetworkThreat { #[must_use] pub fn syslog_rfc5424(&self) -> String { format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} service={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} content={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} service={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} content={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -78,8 +78,10 @@ impl NetworkThreat { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.service, self.start_time.to_rfc3339(), @@ -103,12 +105,14 @@ impl fmt::Display for NetworkThreat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} service={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} content={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} service={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} content={:?} db_name={:?} rule_id={:?} matched_to={:?} cluster_id={:?} attack_kind={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.service, self.start_time.to_rfc3339(), diff --git a/src/event/nfs.rs b/src/event/nfs.rs index e72df908..f3ac8127 100644 --- a/src/event/nfs.rs +++ b/src/event/nfs.rs @@ -35,17 +35,17 @@ macro_rules! find_nfs_attr_by_kind { }}; } -pub type BlocklistNfsFields = BlocklistNfsFieldsV0_43; +pub type BlocklistNfsFields = BlocklistNfsFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistNfsFieldsV0_43 { +pub struct BlocklistNfsFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -65,7 +65,7 @@ impl BlocklistNfsFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} read_files={:?} write_files={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} read_files={:?} write_files={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -73,8 +73,10 @@ impl BlocklistNfsFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -93,11 +95,11 @@ impl BlocklistNfsFields { pub struct BlocklistNfs { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -116,12 +118,14 @@ impl fmt::Display for BlocklistNfs { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} read_files={:?} write_files={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} read_files={:?} write_files={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -141,11 +145,11 @@ impl BlocklistNfs { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ntlm.rs b/src/event/ntlm.rs index 784a9379..474ec9cf 100644 --- a/src/event/ntlm.rs +++ b/src/event/ntlm.rs @@ -34,17 +34,17 @@ macro_rules! find_ntlm_attr_by_kind { }}; } -pub type BlocklistNtlmFields = BlocklistNtlmFieldsV0_43; +pub type BlocklistNtlmFields = BlocklistNtlmFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistNtlmFieldsV0_43 { +pub struct BlocklistNtlmFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -67,7 +67,7 @@ impl BlocklistNtlmFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} username={:?} hostname={:?} domainname={:?} success={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} username={:?} hostname={:?} domainname={:?} success={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -75,8 +75,10 @@ impl BlocklistNtlmFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -98,11 +100,11 @@ impl BlocklistNtlmFields { pub struct BlocklistNtlm { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -124,12 +126,14 @@ impl fmt::Display for BlocklistNtlm { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} username={:?} hostname={:?} domainname={:?} success={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} protocol={:?} username={:?} hostname={:?} domainname={:?} success={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -151,11 +155,11 @@ impl BlocklistNtlm { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/radius.rs b/src/event/radius.rs index 96efba13..25d2048a 100644 --- a/src/event/radius.rs +++ b/src/event/radius.rs @@ -43,17 +43,17 @@ macro_rules! find_radius_attr_by_kind { }}; } -pub type BlocklistRadiusFields = BlocklistRadiusFieldsV0_43; +pub type BlocklistRadiusFields = BlocklistRadiusFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistRadiusFieldsV0_43 { +pub struct BlocklistRadiusFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -85,7 +85,7 @@ impl BlocklistRadiusFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} id={:?} code={:?} resp_code={:?} auth={:?} resp_auth={:?} user_name={:?} user_passwd={:?} chap_passwd={:?} nas_ip={:?} nas_port={:?} state={:?} nas_id={:?} nas_port_type={:?} message={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} id={:?} code={:?} resp_code={:?} auth={:?} resp_auth={:?} user_name={:?} user_passwd={:?} chap_passwd={:?} nas_ip={:?} nas_port={:?} state={:?} nas_id={:?} nas_port_type={:?} message={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -93,8 +93,10 @@ impl BlocklistRadiusFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -124,11 +126,11 @@ impl BlocklistRadiusFields { pub struct BlocklistRadius { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -162,12 +164,14 @@ impl fmt::Display for BlocklistRadius { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} id={:?} code={:?} resp_code={:?} auth={:?} resp_auth={:?} user_name={:?} user_passwd={:?} chap_passwd={:?} nas_ip={:?} nas_port={:?} state={:?} nas_id={:?} nas_port_type={:?} message={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} id={:?} code={:?} resp_code={:?} auth={:?} resp_auth={:?} user_name={:?} user_passwd={:?} chap_passwd={:?} nas_ip={:?} nas_port={:?} state={:?} nas_id={:?} nas_port_type={:?} message={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_str, self.duration.to_string(), @@ -199,11 +203,11 @@ impl BlocklistRadius { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/rdp.rs b/src/event/rdp.rs index e3628f48..c7d03a45 100644 --- a/src/event/rdp.rs +++ b/src/event/rdp.rs @@ -35,15 +35,15 @@ macro_rules! find_rdp_attr_by_kind { }}; } -pub type RdpBruteForceFields = RdpBruteForceFieldsV0_43; +pub type RdpBruteForceFields = RdpBruteForceFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct RdpBruteForceFieldsV0_43 { +pub struct RdpBruteForceFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addrs: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -59,13 +59,14 @@ impl RdpBruteForceFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), @@ -79,10 +80,10 @@ impl RdpBruteForceFields { pub struct RdpBruteForce { pub sensor: String, pub time: DateTime, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub resp_addrs: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, pub start_time: DateTime, pub end_time: DateTime, pub proto: u8, @@ -95,8 +96,9 @@ impl fmt::Display for RdpBruteForce { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "orig_addr={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", self.orig_addr.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), @@ -111,10 +113,10 @@ impl RdpBruteForce { RdpBruteForce { sensor: fields.sensor.clone(), time, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, resp_addrs: fields.resp_addrs.clone(), - dst_country_codes: fields.dst_country_codes.clone(), + resp_country_codes: fields.resp_country_codes.clone(), start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), proto: fields.proto, @@ -186,17 +188,17 @@ impl Match for RdpBruteForce { } } -pub type BlocklistRdpFields = BlocklistRdpFieldsV0_43; +pub type BlocklistRdpFields = BlocklistRdpFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistRdpFieldsV0_43 { +pub struct BlocklistRdpFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -215,7 +217,7 @@ impl BlocklistRdpFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} cookie={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} cookie={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -223,8 +225,10 @@ impl BlocklistRdpFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -241,11 +245,11 @@ impl BlocklistRdpFields { pub struct BlocklistRdp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -263,12 +267,14 @@ impl fmt::Display for BlocklistRdp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} cookie={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} cookie={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -287,11 +293,11 @@ impl BlocklistRdp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/smb.rs b/src/event/smb.rs index 087b7849..0315fe84 100644 --- a/src/event/smb.rs +++ b/src/event/smb.rs @@ -40,17 +40,17 @@ macro_rules! find_smb_attr_by_kind { }}; } -pub type BlocklistSmbFields = BlocklistSmbFieldsV0_43; +pub type BlocklistSmbFields = BlocklistSmbFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistSmbFieldsV0_43 { +pub struct BlocklistSmbFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -79,7 +79,7 @@ impl BlocklistSmbFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} command={:?} path={:?} service={:?} file_name={:?} file_size={:?} resource_type={:?} fid={:?} create_time={:?} access_time={:?} write_time={:?} change_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} command={:?} path={:?} service={:?} file_name={:?} file_size={:?} resource_type={:?} fid={:?} create_time={:?} access_time={:?} write_time={:?} change_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -87,8 +87,10 @@ impl BlocklistSmbFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -116,11 +118,11 @@ impl BlocklistSmbFields { pub struct BlocklistSmb { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -148,12 +150,14 @@ impl fmt::Display for BlocklistSmb { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} command={:?} path={:?} service={:?} file_name={:?} file_size={:?} resource_type={:?} fid={:?} create_time={:?} access_time={:?} write_time={:?} change_time={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} command={:?} path={:?} service={:?} file_name={:?} file_size={:?} resource_type={:?} fid={:?} create_time={:?} access_time={:?} write_time={:?} change_time={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -181,11 +185,11 @@ impl BlocklistSmb { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/smtp.rs b/src/event/smtp.rs index e99586ff..ae49485a 100644 --- a/src/event/smtp.rs +++ b/src/event/smtp.rs @@ -36,17 +36,17 @@ macro_rules! find_smtp_attr_by_kind { }}; } -pub type BlocklistSmtpFields = BlocklistSmtpFieldsV0_43; +pub type BlocklistSmtpFields = BlocklistSmtpFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistSmtpFieldsV0_43 { +pub struct BlocklistSmtpFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -71,7 +71,7 @@ impl BlocklistSmtpFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} mailfrom={:?} date={:?} from={:?} to={:?} subject={:?} agent={:?} state={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} mailfrom={:?} date={:?} from={:?} to={:?} subject={:?} agent={:?} state={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -79,8 +79,10 @@ impl BlocklistSmtpFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -104,11 +106,11 @@ impl BlocklistSmtpFields { pub struct BlocklistSmtp { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -132,12 +134,14 @@ impl fmt::Display for BlocklistSmtp { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} mailfrom={:?} date={:?} from={:?} to={:?} subject={:?} agent={:?} state={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} mailfrom={:?} date={:?} from={:?} to={:?} subject={:?} agent={:?} state={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -162,11 +166,11 @@ impl BlocklistSmtp { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/ssh.rs b/src/event/ssh.rs index 32c68625..f68ca3e6 100644 --- a/src/event/ssh.rs +++ b/src/event/ssh.rs @@ -44,17 +44,17 @@ macro_rules! find_ssh_attr_by_kind { }}; } -pub type BlocklistSshFields = BlocklistSshFieldsV0_43; +pub type BlocklistSshFields = BlocklistSshFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistSshFieldsV0_43 { +pub struct BlocklistSshFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -85,7 +85,7 @@ impl BlocklistSshFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client={:?} server={:?} cipher_alg={:?} mac_alg={:?} compression_alg={:?} kex_alg={:?} host_key_alg={:?} hassh_algorithms={:?} hassh={:?} hassh_server_algorithms={:?} hassh_server={:?} client_shka={:?} server_shka={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client={:?} server={:?} cipher_alg={:?} mac_alg={:?} compression_alg={:?} kex_alg={:?} host_key_alg={:?} hassh_algorithms={:?} hassh={:?} hassh_server_algorithms={:?} hassh_server={:?} client_shka={:?} server_shka={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -93,8 +93,10 @@ impl BlocklistSshFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -124,11 +126,11 @@ impl BlocklistSshFields { pub struct BlocklistSsh { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -158,12 +160,14 @@ impl fmt::Display for BlocklistSsh { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client={:?} server={:?} cipher_alg={:?} mac_alg={:?} compression_alg={:?} kex_alg={:?} host_key_alg={:?} hassh_algorithms={:?} hassh={:?} hassh_server_algorithms={:?} hassh_server={:?} client_shka={:?} server_shka={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} client={:?} server={:?} cipher_alg={:?} mac_alg={:?} compression_alg={:?} kex_alg={:?} host_key_alg={:?} hassh_algorithms={:?} hassh={:?} hassh_server_algorithms={:?} hassh_server={:?} client_shka={:?} server_shka={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -194,11 +198,11 @@ impl BlocklistSsh { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/tls.rs b/src/event/tls.rs index 010a86ef..dc2ff583 100644 --- a/src/event/tls.rs +++ b/src/event/tls.rs @@ -68,17 +68,17 @@ macro_rules! find_tls_attr_by_kind { }}; } -pub type BlocklistTlsFields = BlocklistTlsFieldsV0_43; +pub type BlocklistTlsFields = BlocklistTlsFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct BlocklistTlsFieldsV0_43 { +pub struct BlocklistTlsFieldsV0_44 { pub sensor: String, - pub src_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -117,7 +117,7 @@ impl BlocklistTlsFields { pub fn syslog_rfc5424(&self) -> String { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -125,8 +125,10 @@ impl BlocklistTlsFields { self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), start_time_dt.to_rfc3339(), self.duration.to_string(), @@ -164,11 +166,11 @@ impl BlocklistTlsFields { pub struct BlocklistTls { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -207,12 +209,14 @@ impl fmt::Display for BlocklistTls { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -252,11 +256,11 @@ impl BlocklistTls { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -346,11 +350,11 @@ impl Match for BlocklistTls { pub struct SuspiciousTlsTraffic { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -389,12 +393,14 @@ impl fmt::Display for SuspiciousTlsTraffic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?} triage_scores={:?}", + "sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} server_name={:?} alpn_protocol={:?} ja3={:?} version={:?} client_cipher_suites={:?} client_extensions={:?} cipher={:?} extensions={:?} ja3s={:?} serial={:?} subject_country={:?} subject_org_name={:?} subject_common_name={:?} validity_not_before={:?} validity_not_after={:?} subject_alt_name={:?} issuer_country={:?} issuer_org_name={:?} issuer_org_unit_name={:?} issuer_common_name={:?} last_alert={:?} confidence={:?} triage_scores={:?}", self.sensor, self.orig_addr.to_string(), self.orig_port.to_string(), + std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), self.resp_port.to_string(), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), self.start_time.to_rfc3339(), self.duration.to_string(), @@ -434,12 +440,12 @@ impl SuspiciousTlsTraffic { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, duration: fields.duration, diff --git a/src/event/tor.rs b/src/event/tor.rs index 10e9686a..2a8e9ed5 100644 --- a/src/event/tor.rs +++ b/src/event/tor.rs @@ -17,11 +17,11 @@ use crate::event::{ pub struct TorConnection { pub time: DateTime, pub sensor: String, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -102,7 +102,7 @@ impl TorConnection { TorConnection { time, sensor: fields.sensor.clone(), - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, @@ -112,7 +112,7 @@ impl TorConnection { orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, method: fields.method.clone(), @@ -210,11 +210,11 @@ impl Match for TorConnection { pub struct TorConnectionConn { pub sensor: String, pub time: DateTime, - pub src_country_code: [u8; 2], + pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, pub resp_addr: IpAddr, - pub dst_country_code: [u8; 2], + pub resp_country_code: [u8; 2], pub resp_port: u16, pub proto: u8, pub start_time: DateTime, @@ -263,12 +263,12 @@ impl TorConnectionConn { Self { time, sensor: fields.sensor, - src_country_code: fields.src_country_code, + orig_country_code: fields.orig_country_code, start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, resp_addr: fields.resp_addr, - dst_country_code: fields.dst_country_code, + resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, proto: fields.proto, conn_state: fields.conn_state, @@ -357,10 +357,10 @@ mod tests { .unwrap(); BlocklistConnFields { sensor: "test-sensor".to_string(), - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: "192.168.1.100".parse().unwrap(), orig_port: 12345, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_addr: "198.51.100.1".parse().unwrap(), resp_port: 443, proto: 6, diff --git a/src/event/unusual_destination_pattern.rs b/src/event/unusual_destination_pattern.rs index 12573b4a..31d28149 100644 --- a/src/event/unusual_destination_pattern.rs +++ b/src/event/unusual_destination_pattern.rs @@ -7,17 +7,17 @@ use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; use crate::event::common::{AttrValue, triage_scores_to_string}; -pub type UnusualDestinationPatternFields = UnusualDestinationPatternFieldsV0_43; +pub type UnusualDestinationPatternFields = UnusualDestinationPatternFieldsV0_44; #[derive(Serialize, Deserialize)] -pub struct UnusualDestinationPatternFieldsV0_43 { +pub struct UnusualDestinationPatternFieldsV0_44 { pub sensor: String, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub end_time: i64, pub destination_ips: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, @@ -64,7 +64,7 @@ pub struct UnusualDestinationPattern { pub start_time: DateTime, pub end_time: DateTime, pub destination_ips: Vec, - pub dst_country_codes: Vec<[u8; 2]>, + pub resp_country_codes: Vec<[u8; 2]>, pub count: usize, pub expected_mean: f64, pub std_deviation: f64, @@ -100,7 +100,7 @@ impl UnusualDestinationPattern { start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), destination_ips: fields.destination_ips, - dst_country_codes: fields.dst_country_codes, + resp_country_codes: fields.resp_country_codes, count: fields.count, expected_mean: fields.expected_mean, std_deviation: fields.std_deviation, diff --git a/src/lib.rs b/src/lib.rs index 3f1628e6..65db043e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ pub use self::top_n::{ ClusterTrend, ElementCount, LineSegment, Regression, StructuredColumnType, TopTrendsByColumn, }; pub use self::types::{EventCategory, HostNetworkGroup, Qualifier, Status}; -pub use self::util::find_ip_country; +pub use self::util::{country_code_to_bytes, find_ip_country}; const DEFAULT_STATES: &str = "states.db"; const EXCLUSIVE: bool = true; diff --git a/src/migration.rs b/src/migration.rs index a5295ce5..8dab0c44 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -241,7 +241,7 @@ fn map_names_v0_42_without_account_policy() -> Vec<&'static str> { .collect() } -fn migrate_0_42_to_0_43(data_dir: &Path, locator: Option<&ip2location::DB>) -> Result<()> { +fn migrate_0_42_to_0_43(data_dir: &Path, _locator: Option<&ip2location::DB>) -> Result<()> { let db_path = data_dir.join("states.db"); // Step 1: Drop "account policy" column family if it exists (from 0.42) @@ -1106,7 +1106,7 @@ trait ResolveCountryCodes { /// Returns the 2-letter country code, or "XX" if the lookup fails or returns /// an invalid code. fn country_code_to_bytes(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { - crate::util::find_ip_country(locator, addr) + crate::util::country_code_to_bytes(&crate::util::find_ip_country(locator, addr)) } // ============================================================================= @@ -1126,15 +1126,15 @@ use crate::event::{ impl ResolveCountryCodes for PortScanFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for MultiHostPortScanFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_codes = self + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_codes = self .resp_addrs .iter() .map(|addr| country_code_to_bytes(locator, *addr)) @@ -1144,75 +1144,75 @@ impl ResolveCountryCodes for MultiHostPortScanFields { impl ResolveCountryCodes for ExternalDdosFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_codes = self + self.orig_country_codes = self .orig_addrs .iter() .map(|addr| country_code_to_bytes(locator, *addr)) .collect(); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistConnFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for DnsEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for CryptocurrencyMiningPoolFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDnsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for HttpEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for RepeatedHttpSessionsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for HttpThreatFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for DgaFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for RdpBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_codes = self + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_codes = self .resp_addrs .iter() .map(|addr| country_code_to_bytes(locator, *addr)) @@ -1222,133 +1222,133 @@ impl ResolveCountryCodes for RdpBruteForceFields { impl ResolveCountryCodes for BlocklistRdpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for FtpBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for FtpEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for LdapBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for LdapEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSshFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistTlsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistKerberosFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSmtpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistNfsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDhcpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDceRpcFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistNtlmFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSmbFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistMqttFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistBootpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistRadiusFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistMalformedDnsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } impl ResolveCountryCodes for UnusualDestinationPatternFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.dst_country_codes = self + self.resp_country_codes = self .destination_ips .iter() .map(|addr| country_code_to_bytes(locator, *addr)) @@ -1358,8 +1358,8 @@ impl ResolveCountryCodes for UnusualDestinationPatternFields { impl ResolveCountryCodes for NetworkThreat { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.src_country_code = country_code_to_bytes(locator, self.orig_addr); - self.dst_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); } } diff --git a/src/migration/migration_structures.rs b/src/migration/migration_structures.rs index 11f173e0..f9524160 100644 --- a/src/migration/migration_structures.rs +++ b/src/migration/migration_structures.rs @@ -108,22 +108,22 @@ pub(crate) struct NetworkValueV0_43 { } // ============================================================================= -// Event Fields V0_42 structures (before src_country_code/dst_country_code) -// These structs represent event field schemas from version 0.42.x without -// country code fields. From 0.43.x, country code fields were added. +// Event Fields V0_43 structures (before orig_country_code/resp_country_code) +// These structs represent event field schemas from version 0.43.x without +// country code fields. From 0.44.x, country code fields were added. // ============================================================================= -/// FTP Command structure for `V0_42` migration +/// FTP Command structure for `V0_43` migration #[derive(Clone, Deserialize, Serialize)] -pub(crate) struct FtpCommandV0_42 { +pub(crate) struct FtpCommandV0_43 { pub command: String, pub reply_code: String, pub reply_msg: String, } -/// Port scan fields from version 0.42.x (before country codes were added) +/// Port scan fields from version 0.43.x (before country codes were added) #[derive(Serialize, Deserialize)] -pub(crate) struct PortScanFieldsV0_42 { +pub(crate) struct PortScanFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub resp_addr: IpAddr, @@ -135,9 +135,9 @@ pub(crate) struct PortScanFieldsV0_42 { pub category: Option, } -/// Multi-host port scan fields from version 0.42.x +/// Multi-host port scan fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct MultiHostPortScanFieldsV0_42 { +pub(crate) struct MultiHostPortScanFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub resp_port: u16, @@ -149,9 +149,9 @@ pub(crate) struct MultiHostPortScanFieldsV0_42 { pub category: Option, } -/// External `DDoS` fields from version 0.42.x +/// External `DDoS` fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct ExternalDdosFieldsV0_42 { +pub(crate) struct ExternalDdosFieldsV0_43 { pub sensor: String, pub orig_addrs: Vec, pub resp_addr: IpAddr, @@ -162,9 +162,9 @@ pub(crate) struct ExternalDdosFieldsV0_42 { pub category: Option, } -/// Blocklist connection fields from version 0.42.x +/// Blocklist connection fields from version 0.43.x #[derive(Deserialize, Serialize)] -pub(crate) struct BlocklistConnFieldsV0_42 { +pub(crate) struct BlocklistConnFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -185,10 +185,10 @@ pub(crate) struct BlocklistConnFieldsV0_42 { pub category: Option, } -/// DNS event fields from version 0.42.x +/// DNS event fields from version 0.43.x #[allow(clippy::struct_excessive_bools)] #[derive(Deserialize, Serialize)] -pub(crate) struct DnsEventFieldsV0_42 { +pub(crate) struct DnsEventFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -217,10 +217,10 @@ pub(crate) struct DnsEventFieldsV0_42 { pub category: Option, } -/// Cryptocurrency mining pool fields from version 0.42.x +/// Cryptocurrency mining pool fields from version 0.43.x #[allow(clippy::struct_excessive_bools)] #[derive(Deserialize, Serialize)] -pub(crate) struct CryptocurrencyMiningPoolFieldsV0_42 { +pub(crate) struct CryptocurrencyMiningPoolFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -250,10 +250,10 @@ pub(crate) struct CryptocurrencyMiningPoolFieldsV0_42 { pub category: Option, } -/// Blocklist DNS fields from version 0.42.x +/// Blocklist DNS fields from version 0.43.x #[allow(clippy::struct_excessive_bools)] #[derive(Deserialize, Serialize)] -pub(crate) struct BlocklistDnsFieldsV0_42 { +pub(crate) struct BlocklistDnsFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -282,9 +282,9 @@ pub(crate) struct BlocklistDnsFieldsV0_42 { pub category: Option, } -/// HTTP event fields from version 0.42.x +/// HTTP event fields from version 0.43.x #[derive(Deserialize, Serialize)] -pub(crate) struct HttpEventFieldsV0_42 { +pub(crate) struct HttpEventFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -321,9 +321,9 @@ pub(crate) struct HttpEventFieldsV0_42 { pub category: Option, } -/// Repeated HTTP sessions fields from version 0.42.x +/// Repeated HTTP sessions fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct RepeatedHttpSessionsFieldsV0_42 { +pub(crate) struct RepeatedHttpSessionsFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -336,9 +336,9 @@ pub(crate) struct RepeatedHttpSessionsFieldsV0_42 { pub category: Option, } -/// HTTP threat fields from version 0.42.x +/// HTTP threat fields from version 0.43.x #[derive(Deserialize, Serialize)] -pub(crate) struct HttpThreatFieldsV0_42 { +pub(crate) struct HttpThreatFieldsV0_43 { #[serde(with = "chrono::serde::ts_nanoseconds")] pub time: DateTime, pub sensor: String, @@ -382,9 +382,9 @@ pub(crate) struct HttpThreatFieldsV0_42 { pub category: Option, } -/// DGA fields from version 0.42.x +/// DGA fields from version 0.43.x #[derive(Deserialize, Serialize)] -pub(crate) struct DgaFieldsV0_42 { +pub(crate) struct DgaFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -421,9 +421,9 @@ pub(crate) struct DgaFieldsV0_42 { pub category: Option, } -/// RDP brute force fields from version 0.42.x +/// RDP brute force fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct RdpBruteForceFieldsV0_42 { +pub(crate) struct RdpBruteForceFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub resp_addrs: Vec, @@ -434,9 +434,9 @@ pub(crate) struct RdpBruteForceFieldsV0_42 { pub category: Option, } -/// Blocklist RDP fields from version 0.42.x +/// Blocklist RDP fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistRdpFieldsV0_42 { +pub(crate) struct BlocklistRdpFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -454,9 +454,9 @@ pub(crate) struct BlocklistRdpFieldsV0_42 { pub category: Option, } -/// FTP brute force fields from version 0.42.x +/// FTP brute force fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct FtpBruteForceFieldsV0_42 { +pub(crate) struct FtpBruteForceFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub resp_addr: IpAddr, @@ -470,9 +470,9 @@ pub(crate) struct FtpBruteForceFieldsV0_42 { pub category: Option, } -/// FTP event fields from version 0.42.x +/// FTP event fields from version 0.43.x #[derive(Deserialize, Serialize)] -pub(crate) struct FtpEventFieldsV0_42 { +pub(crate) struct FtpEventFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -487,14 +487,14 @@ pub(crate) struct FtpEventFieldsV0_42 { pub resp_l2_bytes: u64, pub user: String, pub password: String, - pub commands: Vec, + pub commands: Vec, pub confidence: f32, pub category: Option, } -/// LDAP brute force fields from version 0.42.x +/// LDAP brute force fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct LdapBruteForceFieldsV0_42 { +pub(crate) struct LdapBruteForceFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub resp_addr: IpAddr, @@ -507,9 +507,9 @@ pub(crate) struct LdapBruteForceFieldsV0_42 { pub category: Option, } -/// LDAP event fields from version 0.42.x +/// LDAP event fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct LdapEventFieldsV0_42 { +pub(crate) struct LdapEventFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -533,9 +533,9 @@ pub(crate) struct LdapEventFieldsV0_42 { pub category: Option, } -/// Blocklist SSH fields from version 0.42.x +/// Blocklist SSH fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistSshFieldsV0_42 { +pub(crate) struct BlocklistSshFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -565,9 +565,9 @@ pub(crate) struct BlocklistSshFieldsV0_42 { pub category: Option, } -/// Blocklist TLS fields from version 0.42.x +/// Blocklist TLS fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistTlsFieldsV0_42 { +pub(crate) struct BlocklistTlsFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -605,9 +605,9 @@ pub(crate) struct BlocklistTlsFieldsV0_42 { pub category: Option, } -/// Blocklist Kerberos fields from version 0.42.x +/// Blocklist Kerberos fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistKerberosFieldsV0_42 { +pub(crate) struct BlocklistKerberosFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -633,9 +633,9 @@ pub(crate) struct BlocklistKerberosFieldsV0_42 { pub category: Option, } -/// Blocklist SMTP fields from version 0.42.x +/// Blocklist SMTP fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistSmtpFieldsV0_42 { +pub(crate) struct BlocklistSmtpFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -659,9 +659,9 @@ pub(crate) struct BlocklistSmtpFieldsV0_42 { pub category: Option, } -/// Blocklist NFS fields from version 0.42.x +/// Blocklist NFS fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistNfsFieldsV0_42 { +pub(crate) struct BlocklistNfsFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -680,9 +680,9 @@ pub(crate) struct BlocklistNfsFieldsV0_42 { pub category: Option, } -/// Blocklist DHCP fields from version 0.42.x +/// Blocklist DHCP fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistDhcpFieldsV0_42 { +pub(crate) struct BlocklistDhcpFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -717,9 +717,9 @@ pub(crate) struct BlocklistDhcpFieldsV0_42 { pub category: Option, } -/// Blocklist DCE-RPC fields from version 0.42.x +/// Blocklist DCE-RPC fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistDceRpcFieldsV0_42 { +pub(crate) struct BlocklistDceRpcFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -740,9 +740,9 @@ pub(crate) struct BlocklistDceRpcFieldsV0_42 { pub category: Option, } -/// Blocklist NTLM fields from version 0.42.x +/// Blocklist NTLM fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistNtlmFieldsV0_42 { +pub(crate) struct BlocklistNtlmFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -764,9 +764,9 @@ pub(crate) struct BlocklistNtlmFieldsV0_42 { pub category: Option, } -/// Blocklist SMB fields from version 0.42.x +/// Blocklist SMB fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistSmbFieldsV0_42 { +pub(crate) struct BlocklistSmbFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -794,9 +794,9 @@ pub(crate) struct BlocklistSmbFieldsV0_42 { pub category: Option, } -/// Blocklist MQTT fields from version 0.42.x +/// Blocklist MQTT fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistMqttFieldsV0_42 { +pub(crate) struct BlocklistMqttFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -819,9 +819,9 @@ pub(crate) struct BlocklistMqttFieldsV0_42 { pub category: Option, } -/// Blocklist BOOTP fields from version 0.42.x +/// Blocklist BOOTP fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistBootpFieldsV0_42 { +pub(crate) struct BlocklistBootpFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -849,9 +849,9 @@ pub(crate) struct BlocklistBootpFieldsV0_42 { pub category: Option, } -/// Blocklist Radius fields from version 0.42.x +/// Blocklist Radius fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistRadiusFieldsV0_42 { +pub(crate) struct BlocklistRadiusFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -882,9 +882,9 @@ pub(crate) struct BlocklistRadiusFieldsV0_42 { pub category: Option, } -/// Blocklist malformed DNS fields from version 0.42.x +/// Blocklist malformed DNS fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct BlocklistMalformedDnsFieldsV0_42 { +pub(crate) struct BlocklistMalformedDnsFieldsV0_43 { pub sensor: String, pub orig_addr: IpAddr, pub orig_port: u16, @@ -913,9 +913,9 @@ pub(crate) struct BlocklistMalformedDnsFieldsV0_42 { pub category: Option, } -/// Unusual destination pattern fields from version 0.42.x +/// Unusual destination pattern fields from version 0.43.x #[derive(Serialize, Deserialize)] -pub(crate) struct UnusualDestinationPatternFieldsV0_42 { +pub(crate) struct UnusualDestinationPatternFieldsV0_43 { pub sensor: String, pub start_time: i64, pub end_time: i64, @@ -929,7 +929,7 @@ pub(crate) struct UnusualDestinationPatternFieldsV0_42 { } // ============================================================================= -// From trait implementations for V0_42 -> V0_43 conversions +// From trait implementations for V0_43 -> V0_44 conversions // These enable migrating old event fields to new format with country codes // ============================================================================= @@ -945,14 +945,14 @@ use crate::event::{ UnusualDestinationPatternFields, }; -impl From for PortScanFields { - fn from(old: PortScanFieldsV0_42) -> Self { +impl From for PortScanFields { + fn from(old: PortScanFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_ports: old.resp_ports, start_time: old.start_time, end_time: old.end_time, @@ -963,16 +963,16 @@ impl From for PortScanFields { } } -impl From for MultiHostPortScanFields { - fn from(old: MultiHostPortScanFieldsV0_42) -> Self { - let dst_country_codes = vec![*b"XX"; old.resp_addrs.len()]; +impl From for MultiHostPortScanFields { + fn from(old: MultiHostPortScanFieldsV0_43) -> Self { + let resp_country_codes = vec![*b"XX"; old.resp_addrs.len()]; Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, resp_port: old.resp_port, resp_addrs: old.resp_addrs, - dst_country_codes, + resp_country_codes, proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -982,15 +982,15 @@ impl From for MultiHostPortScanFields { } } -impl From for ExternalDdosFields { - fn from(old: ExternalDdosFieldsV0_42) -> Self { - let src_country_codes = vec![*b"XX"; old.orig_addrs.len()]; +impl From for ExternalDdosFields { + fn from(old: ExternalDdosFieldsV0_43) -> Self { + let orig_country_codes = vec![*b"XX"; old.orig_addrs.len()]; Self { sensor: old.sensor, orig_addrs: old.orig_addrs, - src_country_codes, + orig_country_codes, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -1000,15 +1000,15 @@ impl From for ExternalDdosFields { } } -impl From for BlocklistConnFields { - fn from(old: BlocklistConnFieldsV0_42) -> Self { +impl From for BlocklistConnFields { + fn from(old: BlocklistConnFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, conn_state: old.conn_state, @@ -1027,15 +1027,15 @@ impl From for BlocklistConnFields { } } -impl From for DnsEventFields { - fn from(old: DnsEventFieldsV0_42) -> Self { +impl From for DnsEventFields { + fn from(old: DnsEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1062,15 +1062,15 @@ impl From for DnsEventFields { } } -impl From for CryptocurrencyMiningPoolFields { - fn from(old: CryptocurrencyMiningPoolFieldsV0_42) -> Self { +impl From for CryptocurrencyMiningPoolFields { + fn from(old: CryptocurrencyMiningPoolFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1098,15 +1098,15 @@ impl From for CryptocurrencyMiningPoolField } } -impl From for BlocklistDnsFields { - fn from(old: BlocklistDnsFieldsV0_42) -> Self { +impl From for BlocklistDnsFields { + fn from(old: BlocklistDnsFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1133,15 +1133,15 @@ impl From for BlocklistDnsFields { } } -impl From for HttpEventFields { - fn from(old: HttpEventFieldsV0_42) -> Self { +impl From for HttpEventFields { + fn from(old: HttpEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1176,15 +1176,15 @@ impl From for HttpEventFields { } } -impl From for RepeatedHttpSessionsFields { - fn from(old: RepeatedHttpSessionsFieldsV0_42) -> Self { +impl From for RepeatedHttpSessionsFields { + fn from(old: RepeatedHttpSessionsFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1195,16 +1195,16 @@ impl From for RepeatedHttpSessionsFields { } } -impl From for HttpThreatFields { - fn from(old: HttpThreatFieldsV0_42) -> Self { +impl From for HttpThreatFields { + fn from(old: HttpThreatFieldsV0_43) -> Self { Self { time: old.time, sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1244,15 +1244,15 @@ impl From for HttpThreatFields { } } -impl From for DgaFields { - fn from(old: DgaFieldsV0_42) -> Self { +impl From for DgaFields { + fn from(old: DgaFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1287,15 +1287,15 @@ impl From for DgaFields { } } -impl From for RdpBruteForceFields { - fn from(old: RdpBruteForceFieldsV0_42) -> Self { - let dst_country_codes = vec![*b"XX"; old.resp_addrs.len()]; +impl From for RdpBruteForceFields { + fn from(old: RdpBruteForceFieldsV0_43) -> Self { + let resp_country_codes = vec![*b"XX"; old.resp_addrs.len()]; Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, resp_addrs: old.resp_addrs, - dst_country_codes, + resp_country_codes, start_time: old.start_time, end_time: old.end_time, proto: old.proto, @@ -1305,15 +1305,15 @@ impl From for RdpBruteForceFields { } } -impl From for BlocklistRdpFields { - fn from(old: BlocklistRdpFieldsV0_42) -> Self { +impl From for BlocklistRdpFields { + fn from(old: BlocklistRdpFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1329,14 +1329,14 @@ impl From for BlocklistRdpFields { } } -impl From for FtpBruteForceFields { - fn from(old: FtpBruteForceFieldsV0_42) -> Self { +impl From for FtpBruteForceFields { + fn from(old: FtpBruteForceFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, user_list: old.user_list, @@ -1349,14 +1349,14 @@ impl From for FtpBruteForceFields { } } -impl From for FtpCommand { - fn from(old: FtpCommandV0_42) -> Self { +impl From for FtpCommand { + fn from(old: FtpCommandV0_43) -> Self { use std::net::{IpAddr, Ipv4Addr}; Self { command: old.command, reply_code: old.reply_code, reply_msg: old.reply_msg, - // New fields added after V0_42 - use sensible defaults + // New fields added after V0_43 - use sensible defaults data_passive: false, data_orig_addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), data_resp_addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), @@ -1368,15 +1368,15 @@ impl From for FtpCommand { } } -impl From for FtpEventFields { - fn from(old: FtpEventFieldsV0_42) -> Self { +impl From for FtpEventFields { + fn from(old: FtpEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1394,14 +1394,14 @@ impl From for FtpEventFields { } } -impl From for LdapBruteForceFields { - fn from(old: LdapBruteForceFieldsV0_42) -> Self { +impl From for LdapBruteForceFields { + fn from(old: LdapBruteForceFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, user_pw_list: old.user_pw_list, @@ -1413,15 +1413,15 @@ impl From for LdapBruteForceFields { } } -impl From for LdapEventFields { - fn from(old: LdapEventFieldsV0_42) -> Self { +impl From for LdapEventFields { + fn from(old: LdapEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1443,15 +1443,15 @@ impl From for LdapEventFields { } } -impl From for BlocklistSshFields { - fn from(old: BlocklistSshFieldsV0_42) -> Self { +impl From for BlocklistSshFields { + fn from(old: BlocklistSshFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1479,15 +1479,15 @@ impl From for BlocklistSshFields { } } -impl From for BlocklistTlsFields { - fn from(old: BlocklistTlsFieldsV0_42) -> Self { +impl From for BlocklistTlsFields { + fn from(old: BlocklistTlsFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1523,15 +1523,15 @@ impl From for BlocklistTlsFields { } } -impl From for BlocklistKerberosFields { - fn from(old: BlocklistKerberosFieldsV0_42) -> Self { +impl From for BlocklistKerberosFields { + fn from(old: BlocklistKerberosFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1555,15 +1555,15 @@ impl From for BlocklistKerberosFields { } } -impl From for BlocklistSmtpFields { - fn from(old: BlocklistSmtpFieldsV0_42) -> Self { +impl From for BlocklistSmtpFields { + fn from(old: BlocklistSmtpFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1585,15 +1585,15 @@ impl From for BlocklistSmtpFields { } } -impl From for BlocklistNfsFields { - fn from(old: BlocklistNfsFieldsV0_42) -> Self { +impl From for BlocklistNfsFields { + fn from(old: BlocklistNfsFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1610,15 +1610,15 @@ impl From for BlocklistNfsFields { } } -impl From for BlocklistDhcpFields { - fn from(old: BlocklistDhcpFieldsV0_42) -> Self { +impl From for BlocklistDhcpFields { + fn from(old: BlocklistDhcpFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1651,15 +1651,15 @@ impl From for BlocklistDhcpFields { } } -impl From for BlocklistDceRpcFields { - fn from(old: BlocklistDceRpcFieldsV0_42) -> Self { +impl From for BlocklistDceRpcFields { + fn from(old: BlocklistDceRpcFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1678,15 +1678,15 @@ impl From for BlocklistDceRpcFields { } } -impl From for BlocklistNtlmFields { - fn from(old: BlocklistNtlmFieldsV0_42) -> Self { +impl From for BlocklistNtlmFields { + fn from(old: BlocklistNtlmFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1706,15 +1706,15 @@ impl From for BlocklistNtlmFields { } } -impl From for BlocklistSmbFields { - fn from(old: BlocklistSmbFieldsV0_42) -> Self { +impl From for BlocklistSmbFields { + fn from(old: BlocklistSmbFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1740,15 +1740,15 @@ impl From for BlocklistSmbFields { } } -impl From for BlocklistMqttFields { - fn from(old: BlocklistMqttFieldsV0_42) -> Self { +impl From for BlocklistMqttFields { + fn from(old: BlocklistMqttFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1769,15 +1769,15 @@ impl From for BlocklistMqttFields { } } -impl From for BlocklistBootpFields { - fn from(old: BlocklistBootpFieldsV0_42) -> Self { +impl From for BlocklistBootpFields { + fn from(old: BlocklistBootpFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1803,15 +1803,15 @@ impl From for BlocklistBootpFields { } } -impl From for BlocklistRadiusFields { - fn from(old: BlocklistRadiusFieldsV0_42) -> Self { +impl From for BlocklistRadiusFields { + fn from(old: BlocklistRadiusFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1840,15 +1840,15 @@ impl From for BlocklistRadiusFields { } } -impl From for BlocklistMalformedDnsFields { - fn from(old: BlocklistMalformedDnsFieldsV0_42) -> Self { +impl From for BlocklistMalformedDnsFields { + fn from(old: BlocklistMalformedDnsFieldsV0_43) -> Self { Self { sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, @@ -1875,15 +1875,15 @@ impl From for BlocklistMalformedDnsFields { } } -impl From for UnusualDestinationPatternFields { - fn from(old: UnusualDestinationPatternFieldsV0_42) -> Self { - let dst_country_codes = vec![*b"XX"; old.destination_ips.len()]; +impl From for UnusualDestinationPatternFields { + fn from(old: UnusualDestinationPatternFieldsV0_43) -> Self { + let resp_country_codes = vec![*b"XX"; old.destination_ips.len()]; Self { sensor: old.sensor, start_time: old.start_time, end_time: old.end_time, destination_ips: old.destination_ips, - dst_country_codes, + resp_country_codes, count: old.count, expected_mean: old.expected_mean, std_deviation: old.std_deviation, @@ -1894,9 +1894,9 @@ impl From for UnusualDestinationPatternFie } } -/// Network threat from version 0.42.x (before country codes were added) +/// Network threat from version 0.43.x (before country codes were added) #[derive(Deserialize, Serialize)] -pub(crate) struct NetworkThreatV0_42 { +pub(crate) struct NetworkThreatV0_43 { #[serde(with = "chrono::serde::ts_nanoseconds")] pub time: DateTime, pub sensor: String, @@ -1926,16 +1926,16 @@ pub(crate) struct NetworkThreatV0_42 { use crate::event::NetworkThreat; -impl From for NetworkThreat { - fn from(old: NetworkThreatV0_42) -> Self { +impl From for NetworkThreat { + fn from(old: NetworkThreatV0_43) -> Self { Self { time: old.time, sensor: old.sensor, - src_country_code: *b"XX", + orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, resp_addr: old.resp_addr, - dst_country_code: *b"XX", + resp_country_code: *b"XX", resp_port: old.resp_port, proto: old.proto, service: old.service, diff --git a/src/util.rs b/src/util.rs index 333b10bf..8ce9d30b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -3,7 +3,7 @@ use std::net::IpAddr; /// The unknown country code, used when lookup fails or returns an invalid code. -pub const UNKNOWN_COUNTRY_CODE: [u8; 2] = *b"XX"; +pub const UNKNOWN_COUNTRY_CODE: &str = "XX"; /// Looks up the country code for the given IP address. /// @@ -17,26 +17,31 @@ pub const UNKNOWN_COUNTRY_CODE: [u8; 2] = *b"XX"; /// Returns the two-letter country code for the IP address, or "XX" if the lookup fails /// or the returned code is not a valid two-letter alphabetic code. #[must_use] -pub fn find_ip_country(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { +pub fn find_ip_country(locator: &ip2location::DB, addr: IpAddr) -> String { locator .ip_lookup(addr) .map(|r| get_record_country_short_name(&r)) .ok() .flatten() - .and_then(|code| validate_country_code(&code)) - .unwrap_or(UNKNOWN_COUNTRY_CODE) + .filter(|code| is_valid_country_code(code)) + .unwrap_or_else(|| UNKNOWN_COUNTRY_CODE.to_string()) } /// Validates that the given country code is a valid two-letter alphabetic code. -/// -/// Returns `Some([u8; 2])` if valid, `None` otherwise. -/// This filters out invalid values like "-" that `IP2Location` may return. -fn validate_country_code(code: &str) -> Option<[u8; 2]> { +fn is_valid_country_code(code: &str) -> bool { + let bytes = code.as_bytes(); + bytes.len() == 2 && bytes[0].is_ascii_alphabetic() && bytes[1].is_ascii_alphabetic() +} + +/// Converts a country code string to a 2-byte array. +/// Returns `[b'X', b'X']` if the code is invalid. +#[must_use] +pub fn country_code_to_bytes(code: &str) -> [u8; 2] { let bytes = code.as_bytes(); - if bytes.len() == 2 && bytes[0].is_ascii_alphabetic() && bytes[1].is_ascii_alphabetic() { - Some([bytes[0], bytes[1]]) + if bytes.len() == 2 { + [bytes[0], bytes[1]] } else { - None + *b"XX" } } From ac4b0e767974025cad8087389294d189f1ee1c38 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 00:27:36 +0000 Subject: [PATCH 08/12] Normalize migration country codes and field order --- src/backup.rs | 4 +- src/migration.rs | 136 +++++++++++++------------- src/migration/migration_structures.rs | 128 ++++++++++++------------ 3 files changed, 134 insertions(+), 134 deletions(-) diff --git a/src/backup.rs b/src/backup.rs index 7ccdc9ff..8c4d4d04 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -109,12 +109,12 @@ mod tests { let codec = bincode::DefaultOptions::new(); let fields = DnsEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) diff --git a/src/migration.rs b/src/migration.rs index 8dab0c44..60f9f287 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -113,7 +113,7 @@ const COMPATIBLE_VERSION_REQ: &str = ">=0.44.0-alpha.2,<0.44.0-alpha.3"; /// * `data_dir` - Path to the data directory containing the database /// * `backup_dir` - Path to the backup directory /// * `locator` - Optional IP geolocation database for resolving country codes during migration. -/// If `None`, country code fields will be set to `None` for migrated records. +/// If `None`, country code fields will be set to "ZZ" (unknown) for migrated records. /// /// # Errors /// @@ -1102,10 +1102,10 @@ trait ResolveCountryCodes { fn resolve_country_codes(&mut self, locator: &ip2location::DB); } -/// Converts an IP address to a country code using the ip2location database. -/// Returns the 2-letter country code, or "XX" if the lookup fails or returns -/// an invalid code. -fn country_code_to_bytes(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { +/// Looks up the country code for an IP address using the ip2location database. +/// Returns the 2-letter country code as bytes, or "XX" if the lookup fails or +/// returns an invalid code. +fn lookup_country_code(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { crate::util::country_code_to_bytes(&crate::util::find_ip_country(locator, addr)) } @@ -1126,18 +1126,18 @@ use crate::event::{ impl ResolveCountryCodes for PortScanFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for MultiHostPortScanFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); self.resp_country_codes = self .resp_addrs .iter() - .map(|addr| country_code_to_bytes(locator, *addr)) + .map(|addr| lookup_country_code(locator, *addr)) .collect(); } } @@ -1147,202 +1147,202 @@ impl ResolveCountryCodes for ExternalDdosFields { self.orig_country_codes = self .orig_addrs .iter() - .map(|addr| country_code_to_bytes(locator, *addr)) + .map(|addr| lookup_country_code(locator, *addr)) .collect(); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistConnFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for DnsEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for CryptocurrencyMiningPoolFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDnsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for HttpEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for RepeatedHttpSessionsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for HttpThreatFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for DgaFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for RdpBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); self.resp_country_codes = self .resp_addrs .iter() - .map(|addr| country_code_to_bytes(locator, *addr)) + .map(|addr| lookup_country_code(locator, *addr)) .collect(); } } impl ResolveCountryCodes for BlocklistRdpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for FtpBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for FtpEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for LdapBruteForceFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for LdapEventFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSshFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistTlsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistKerberosFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSmtpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistNfsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDhcpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistDceRpcFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistNtlmFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistSmbFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistMqttFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistBootpFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistRadiusFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } impl ResolveCountryCodes for BlocklistMalformedDnsFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } @@ -1351,15 +1351,15 @@ impl ResolveCountryCodes for UnusualDestinationPatternFields { self.resp_country_codes = self .destination_ips .iter() - .map(|addr| country_code_to_bytes(locator, *addr)) + .map(|addr| lookup_country_code(locator, *addr)) .collect(); } } impl ResolveCountryCodes for NetworkThreat { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = country_code_to_bytes(locator, self.orig_addr); - self.resp_country_code = country_code_to_bytes(locator, self.resp_addr); + self.orig_country_code = lookup_country_code(locator, self.orig_addr); + self.resp_country_code = lookup_country_code(locator, self.resp_addr); } } diff --git a/src/migration/migration_structures.rs b/src/migration/migration_structures.rs index f9524160..f056f32e 100644 --- a/src/migration/migration_structures.rs +++ b/src/migration/migration_structures.rs @@ -949,10 +949,10 @@ impl From for PortScanFields { fn from(old: PortScanFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", + resp_country_code: *b"ZZ", resp_ports: old.resp_ports, start_time: old.start_time, end_time: old.end_time, @@ -965,14 +965,14 @@ impl From for PortScanFields { impl From for MultiHostPortScanFields { fn from(old: MultiHostPortScanFieldsV0_43) -> Self { - let resp_country_codes = vec![*b"XX"; old.resp_addrs.len()]; + let resp_country_codes = vec![*b"ZZ"; old.resp_addrs.len()]; Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, - resp_port: old.resp_port, + orig_country_code: *b"ZZ", resp_addrs: old.resp_addrs, resp_country_codes, + resp_port: old.resp_port, proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -984,13 +984,13 @@ impl From for MultiHostPortScanFields { impl From for ExternalDdosFields { fn from(old: ExternalDdosFieldsV0_43) -> Self { - let orig_country_codes = vec![*b"XX"; old.orig_addrs.len()]; + let orig_country_codes = vec![*b"ZZ"; old.orig_addrs.len()]; Self { sensor: old.sensor, orig_addrs: old.orig_addrs, orig_country_codes, resp_addr: old.resp_addr, - resp_country_code: *b"XX", + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -1004,12 +1004,12 @@ impl From for BlocklistConnFields { fn from(old: BlocklistConnFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, conn_state: old.conn_state, start_time: old.start_time, @@ -1031,12 +1031,12 @@ impl From for DnsEventFields { fn from(old: DnsEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1066,12 +1066,12 @@ impl From for CryptocurrencyMiningPoolField fn from(old: CryptocurrencyMiningPoolFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1102,12 +1102,12 @@ impl From for BlocklistDnsFields { fn from(old: BlocklistDnsFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1137,12 +1137,12 @@ impl From for HttpEventFields { fn from(old: HttpEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1180,12 +1180,12 @@ impl From for RepeatedHttpSessionsFields { fn from(old: RepeatedHttpSessionsFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, end_time: old.end_time, @@ -1200,12 +1200,12 @@ impl From for HttpThreatFields { Self { time: old.time, sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1248,12 +1248,12 @@ impl From for DgaFields { fn from(old: DgaFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1289,11 +1289,11 @@ impl From for DgaFields { impl From for RdpBruteForceFields { fn from(old: RdpBruteForceFieldsV0_43) -> Self { - let resp_country_codes = vec![*b"XX"; old.resp_addrs.len()]; + let resp_country_codes = vec![*b"ZZ"; old.resp_addrs.len()]; Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, + orig_country_code: *b"ZZ", resp_addrs: old.resp_addrs, resp_country_codes, start_time: old.start_time, @@ -1309,12 +1309,12 @@ impl From for BlocklistRdpFields { fn from(old: BlocklistRdpFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1333,11 +1333,11 @@ impl From for FtpBruteForceFields { fn from(old: FtpBruteForceFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, user_list: old.user_list, start_time: old.start_time, @@ -1372,12 +1372,12 @@ impl From for FtpEventFields { fn from(old: FtpEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1398,11 +1398,11 @@ impl From for LdapBruteForceFields { fn from(old: LdapBruteForceFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, user_pw_list: old.user_pw_list, start_time: old.start_time, @@ -1417,12 +1417,12 @@ impl From for LdapEventFields { fn from(old: LdapEventFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1447,12 +1447,12 @@ impl From for BlocklistSshFields { fn from(old: BlocklistSshFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1483,12 +1483,12 @@ impl From for BlocklistTlsFields { fn from(old: BlocklistTlsFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1527,12 +1527,12 @@ impl From for BlocklistKerberosFields { fn from(old: BlocklistKerberosFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1559,12 +1559,12 @@ impl From for BlocklistSmtpFields { fn from(old: BlocklistSmtpFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1589,12 +1589,12 @@ impl From for BlocklistNfsFields { fn from(old: BlocklistNfsFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1614,12 +1614,12 @@ impl From for BlocklistDhcpFields { fn from(old: BlocklistDhcpFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1655,12 +1655,12 @@ impl From for BlocklistDceRpcFields { fn from(old: BlocklistDceRpcFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1682,12 +1682,12 @@ impl From for BlocklistNtlmFields { fn from(old: BlocklistNtlmFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1710,12 +1710,12 @@ impl From for BlocklistSmbFields { fn from(old: BlocklistSmbFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1744,12 +1744,12 @@ impl From for BlocklistMqttFields { fn from(old: BlocklistMqttFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1773,12 +1773,12 @@ impl From for BlocklistBootpFields { fn from(old: BlocklistBootpFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1807,12 +1807,12 @@ impl From for BlocklistRadiusFields { fn from(old: BlocklistRadiusFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1844,12 +1844,12 @@ impl From for BlocklistMalformedDnsFields { fn from(old: BlocklistMalformedDnsFieldsV0_43) -> Self { Self { sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, start_time: old.start_time, duration: old.duration, @@ -1877,7 +1877,7 @@ impl From for BlocklistMalformedDnsFields { impl From for UnusualDestinationPatternFields { fn from(old: UnusualDestinationPatternFieldsV0_43) -> Self { - let resp_country_codes = vec![*b"XX"; old.destination_ips.len()]; + let resp_country_codes = vec![*b"ZZ"; old.destination_ips.len()]; Self { sensor: old.sensor, start_time: old.start_time, @@ -1931,12 +1931,12 @@ impl From for NetworkThreat { Self { time: old.time, sensor: old.sensor, - orig_country_code: *b"XX", orig_addr: old.orig_addr, orig_port: old.orig_port, + orig_country_code: *b"ZZ", resp_addr: old.resp_addr, - resp_country_code: *b"XX", resp_port: old.resp_port, + resp_country_code: *b"ZZ", proto: old.proto, service: old.service, start_time: old.start_time, From aa90d1cca23393131b07d54eec7c55c2e2972589 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Sun, 18 Jan 2026 02:33:24 +0000 Subject: [PATCH 09/12] Add raw event iterator/update; fix country-code --- src/event.rs | 67 +++++++++++++++ src/migration.rs | 220 ++++++++++++++++++----------------------------- 2 files changed, 151 insertions(+), 136 deletions(-) diff --git a/src/event.rs b/src/event.rs index 37fe670b..20674d5f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -2393,6 +2393,53 @@ impl<'a> EventDb<'a> { EventIterator { inner: iter } } + /// Creates a raw iterator over key-value pairs for migration purposes. + /// + /// Unlike `iter_forward`, this returns raw bytes without deserializing the event fields. + /// This is useful for migrations that need to transform data between formats. + #[must_use] + pub fn raw_iter(&self) -> RawEventIterator<'_> { + let iter = self.inner.iterator(IteratorMode::Start); + RawEventIterator { inner: iter } + } + + /// Updates a raw key-value pair in the database. + /// + /// This method is intended for migration purposes where raw bytes need to be + /// updated without going through the normal event deserialization/serialization. + /// + /// # Errors + /// + /// Returns an error if a database operation fails. + pub fn raw_update(&self, key: &[u8], old_value: &[u8], new_value: &[u8]) -> Result<()> { + loop { + let txn = self.inner.transaction(); + if let Some(current_value) = txn + .get_for_update(key, super::EXCLUSIVE) + .context("cannot read from event database")? + { + if old_value != current_value.as_slice() { + bail!("old value mismatch"); + } + } else { + bail!("no such entry"); + } + + txn.put(key, new_value) + .context("failed to write new entry")?; + + match txn.commit() { + Ok(()) => break, + Err(e) => { + if !e.as_ref().starts_with("Resource busy:") { + return Err(e).context("failed to update entry"); + } + } + } + } + Ok(()) + } + /// Stores a new event into the database. /// /// # Errors @@ -2880,6 +2927,26 @@ pub enum InvalidEvent { Value(Box<[u8]>), } +/// A raw iterator over event key-value pairs for migration purposes. +/// +/// This iterator returns raw bytes without deserializing the event fields, +/// which is useful for migrations that need to transform data between formats. +#[allow(clippy::module_name_repetitions)] +pub struct RawEventIterator<'i> { + inner: rocksdb::DBIteratorWithThreadMode< + 'i, + rocksdb::OptimisticTransactionDB, + >, +} + +impl Iterator for RawEventIterator<'_> { + type Item = (Box<[u8]>, Box<[u8]>); + + fn next(&mut self) -> Option { + self.inner.next().and_then(Result::ok) + } +} + pub type Id = u32; #[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] diff --git a/src/migration.rs b/src/migration.rs index 60f9f287..e8c7d787 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -128,7 +128,7 @@ pub fn migrate_data_dir>( type Migration = ( VersionReq, Version, - fn(&Path, Option<&ip2location::DB>) -> anyhow::Result<()>, + fn(&Path, &Path, Option<&ip2location::DB>) -> anyhow::Result<()>, ); let data_dir = data_dir.as_ref(); @@ -181,7 +181,7 @@ pub fn migrate_data_dir>( .find(|(req, _to, _m)| req.matches(&version)) { info!("Migrating database to {to}"); - m(data_dir, locator)?; + m(data_dir, backup_dir, locator)?; version = to.clone(); if compatible.matches(&version) { create_version_file(&backup).context("failed to update VERSION")?; @@ -241,7 +241,11 @@ fn map_names_v0_42_without_account_policy() -> Vec<&'static str> { .collect() } -fn migrate_0_42_to_0_43(data_dir: &Path, _locator: Option<&ip2location::DB>) -> Result<()> { +fn migrate_0_42_to_0_43( + data_dir: &Path, + _backup_dir: &Path, + _locator: Option<&ip2location::DB>, +) -> Result<()> { let db_path = data_dir.join("states.db"); // Step 1: Drop "account policy" column family if it exists (from 0.42) @@ -256,17 +260,22 @@ fn migrate_0_42_to_0_43(data_dir: &Path, _locator: Option<&ip2location::DB>) -> Ok(()) } -fn migrate_0_43_to_0_44(data_dir: &Path, locator: Option<&ip2location::DB>) -> Result<()> { - let db_path = data_dir.join("states.db"); - +fn migrate_0_43_to_0_44( + data_dir: &Path, + backup_dir: &Path, + locator: Option<&ip2location::DB>, +) -> Result<()> { // Step 1: Migrate network tags to customer-scoped format + // This requires direct database access for low-level meta column family operations migrate_network_tags_to_customer_scoped(data_dir)?; // Step 2: Migrate Network table to enforce global name uniqueness migrate_network_cf(data_dir)?; - // Step 3: Migrate event fields to add country codes - migrate_event_country_codes(&db_path, locator)?; + // Step 3: Migrate event fields to add country codes using Store abstraction + let store = crate::Store::new(data_dir, backup_dir) + .context("Failed to open Store for event migration")?; + migrate_event_country_codes(&store, locator)?; Ok(()) } @@ -849,7 +858,10 @@ fn migrate_network_cf_inner( /// Migrates event fields from `V0_43` format (without country codes) to `V0_44` format /// (with country codes). If a locator is provided, country codes are resolved from /// IP addresses. Otherwise, country codes are set to None. -fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB>) -> Result<()> { +fn migrate_event_country_codes( + store: &crate::Store, + locator: Option<&ip2location::DB>, +) -> Result<()> { use num_traits::FromPrimitive; use crate::migration::migration_structures::{ @@ -868,22 +880,12 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> info!("Migrating event fields to add country codes"); - let mut opts = rocksdb::Options::default(); - opts.create_if_missing(false); - opts.create_missing_column_families(false); - - let db: rocksdb::OptimisticTransactionDB = - rocksdb::OptimisticTransactionDB::open_cf(&opts, db_path, crate::tables::MAP_NAMES) - .context("Failed to open database for event migration")?; + let events = store.events(); - // Collect all events that need migration - // Events are stored in the default column family - let entries_to_migrate: Vec<(Vec, Vec)> = db - .iterator(rocksdb::IteratorMode::Start) - .filter_map(|item| match item { - Ok((key, value)) => Some((key.to_vec(), value.to_vec())), - Err(_) => None, - }) + // Collect all events that need migration using raw iterator + let entries_to_migrate: Vec<(Vec, Vec)> = events + .raw_iter() + .map(|(key, value)| (key.to_vec(), value.to_vec())) .collect(); if entries_to_migrate.is_empty() { @@ -893,20 +895,10 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> info!("Found {} events to migrate", entries_to_migrate.len()); - let txn = db.transaction(); let mut migrated_count = 0usize; let mut skipped_count = 0usize; for (key, value) in &entries_to_migrate { - // Deserialize the EventMessage wrapper - let event_msg: crate::EventMessage = - if let Ok(msg) = bincode::DefaultOptions::new().deserialize(value) { - msg - } else { - skipped_count += 1; - continue; - }; - // Extract the event kind from the key (bits 32-63 of the 128-bit key) let kind_value = if key.len() >= 16 { let key_i128 = i128::from_be_bytes(key[..16].try_into().unwrap_or([0; 16])); @@ -922,143 +914,109 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> }; // Migrate the fields based on event kind + // Events store raw field bytes directly (not EventMessage wrapper) let new_fields: Vec = match kind { EventKind::DnsCovertChannel | EventKind::LockyRansomware => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? + } + EventKind::HttpThreat => { + migrate_fields::(value, locator)? + } + EventKind::RdpBruteForce => { + migrate_fields::(value, locator)? } - EventKind::HttpThreat => migrate_fields::( - &event_msg.fields, - locator, - )?, - EventKind::RdpBruteForce => migrate_fields::< - RdpBruteForceFieldsV0_43, - RdpBruteForceFields, - >(&event_msg.fields, locator)?, EventKind::RepeatedHttpSessions => migrate_fields::< RepeatedHttpSessionsFieldsV0_43, RepeatedHttpSessionsFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, EventKind::TorConnection | EventKind::NonBrowser | EventKind::BlocklistHttp => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? } EventKind::TorConnectionConn | EventKind::BlocklistConn => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? } EventKind::DomainGenerationAlgorithm => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? + } + EventKind::FtpBruteForce => { + migrate_fields::(value, locator)? } - EventKind::FtpBruteForce => migrate_fields::< - FtpBruteForceFieldsV0_43, - FtpBruteForceFields, - >(&event_msg.fields, locator)?, EventKind::FtpPlainText | EventKind::BlocklistFtp => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? } EventKind::PortScan => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? } EventKind::MultiHostPortScan => migrate_fields::< MultiHostPortScanFieldsV0_43, MultiHostPortScanFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, EventKind::ExternalDdos => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? + } + EventKind::LdapBruteForce => { + migrate_fields::(value, locator)? } - EventKind::LdapBruteForce => migrate_fields::< - LdapBruteForceFieldsV0_43, - LdapBruteForceFields, - >(&event_msg.fields, locator)?, EventKind::LdapPlainText | EventKind::BlocklistLdap => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? } EventKind::CryptocurrencyMiningPool => migrate_fields::< CryptocurrencyMiningPoolFieldsV0_43, CryptocurrencyMiningPoolFields, - >(&event_msg.fields, locator)?, - EventKind::BlocklistBootp => migrate_fields::< - BlocklistBootpFieldsV0_43, - BlocklistBootpFields, - >(&event_msg.fields, locator)?, - EventKind::BlocklistDceRpc => migrate_fields::< - BlocklistDceRpcFieldsV0_43, - BlocklistDceRpcFields, - >(&event_msg.fields, locator)?, - EventKind::BlocklistDhcp => migrate_fields::< - BlocklistDhcpFieldsV0_43, - BlocklistDhcpFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, + EventKind::BlocklistBootp => { + migrate_fields::(value, locator)? + } + EventKind::BlocklistDceRpc => { + migrate_fields::(value, locator)? + } + EventKind::BlocklistDhcp => { + migrate_fields::(value, locator)? + } EventKind::BlocklistDns => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? } EventKind::BlocklistKerberos => migrate_fields::< BlocklistKerberosFieldsV0_43, BlocklistKerberosFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, EventKind::BlocklistMalformedDns => migrate_fields::< BlocklistMalformedDnsFieldsV0_43, BlocklistMalformedDnsFields, - >(&event_msg.fields, locator)?, - EventKind::BlocklistMqtt => migrate_fields::< - BlocklistMqttFieldsV0_43, - BlocklistMqttFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, + EventKind::BlocklistMqtt => { + migrate_fields::(value, locator)? + } EventKind::BlocklistNfs => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? + } + EventKind::BlocklistNtlm => { + migrate_fields::(value, locator)? + } + EventKind::BlocklistRadius => { + migrate_fields::(value, locator)? } - EventKind::BlocklistNtlm => migrate_fields::< - BlocklistNtlmFieldsV0_43, - BlocklistNtlmFields, - >(&event_msg.fields, locator)?, - EventKind::BlocklistRadius => migrate_fields::< - BlocklistRadiusFieldsV0_43, - BlocklistRadiusFields, - >(&event_msg.fields, locator)?, EventKind::BlocklistRdp => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? } EventKind::BlocklistSmb => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? + } + EventKind::BlocklistSmtp => { + migrate_fields::(value, locator)? } - EventKind::BlocklistSmtp => migrate_fields::< - BlocklistSmtpFieldsV0_43, - BlocklistSmtpFields, - >(&event_msg.fields, locator)?, EventKind::BlocklistSsh => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? } EventKind::BlocklistTls | EventKind::SuspiciousTlsTraffic => { - migrate_fields::( - &event_msg.fields, - locator, - )? + migrate_fields::(value, locator)? } EventKind::UnusualDestinationPattern => migrate_fields::< UnusualDestinationPatternFieldsV0_43, UnusualDestinationPatternFields, - >(&event_msg.fields, locator)?, + >(value, locator)?, EventKind::NetworkThreat => { - migrate_fields::(&event_msg.fields, locator)? + migrate_fields::(value, locator)? } // These event types don't have country code fields or use different structures EventKind::WindowsThreat | EventKind::ExtraThreat => { @@ -1069,23 +1027,13 @@ fn migrate_event_country_codes(db_path: &Path, locator: Option<&ip2location::DB> } }; - // Create new EventMessage with migrated fields - let new_event_msg = crate::EventMessage { - time: event_msg.time, - kind: event_msg.kind, - fields: new_fields, - }; - - // Serialize and update - let new_value = bincode::DefaultOptions::new() - .serialize(&new_event_msg) - .context("failed to serialize migrated event")?; - txn.put(key, &new_value) + // Update the event with migrated fields using raw_update + events + .raw_update(key, value, &new_fields) .context("failed to update migrated event")?; migrated_count += 1; } - txn.commit().context("failed to commit event migration")?; info!( "Successfully migrated {} events ({} skipped)", migrated_count, skipped_count From a4a487fbf247d62e9e652f43b008428208ee4325 Mon Sep 17 00:00:00 2001 From: sae-bom Date: Wed, 21 Jan 2026 21:01:28 +0900 Subject: [PATCH 10/12] Clean up code after main implementation - Fixed serialize and deserialize errors by adjusting bincode settings based on real test results - Reordered fields and output to match the added country code - Filled in missing logic for multiple address cases - Refined the event DB API - Cleaned up migration code with additional tests to stabilize the final implementation --- CHANGELOG.md | 9 +- Cargo.toml | 1 + src/event.rs | 211 +++---- src/event/bootp.rs | 8 +- src/event/common.rs | 122 ++-- src/event/conn.rs | 61 +- src/event/dcerpc.rs | 8 +- src/event/dhcp.rs | 8 +- src/event/dns.rs | 58 +- src/event/ftp.rs | 32 +- src/event/http.rs | 56 +- src/event/kerberos.rs | 8 +- src/event/ldap.rs | 28 +- src/event/malformed_dns.rs | 8 +- src/event/mqtt.rs | 8 +- src/event/nfs.rs | 8 +- src/event/ntlm.rs | 8 +- src/event/radius.rs | 8 +- src/event/rdp.rs | 25 +- src/event/smb.rs | 8 +- src/event/smtp.rs | 8 +- src/event/ssh.rs | 8 +- src/event/tls.rs | 18 +- src/event/tor.rs | 28 +- src/event/unusual_destination_pattern.rs | 13 +- src/migration.rs | 731 +++++++++++++---------- 26 files changed, 789 insertions(+), 700 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d17b710..e20dde87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,10 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Added -- Added `orig_country_code` and `resp_country_code` fields to all event-specific - `*Fields` structs and `NetworkThreat`. These fields store 2-letter ISO country - codes as `[u8; 2]`, enabling geographic filtering and analysis of - security events. Country codes can be resolved from IP addresses using an - ip2location database during event creation. +- Added `orig_country_code` and `resp_country_code` fields to event-related + structs that contain origin and response IP addresses. These fields store + 2-letter ISO country codes as `[u8; 2]`, enabling geographic filtering and + analysis of security events. - Updated `migrate_data_dir` function signature to accept an optional `ip2location::DB` parameter for resolving country codes during migration from older database formats. diff --git a/Cargo.toml b/Cargo.toml index e9cda439..5831e478 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ data-encoding = "2" flate2 = "1.0" ip2location = "0.6.0" ipnet = { version = "2", features = ["serde"] } +itertools = "0.14" jiff = "0.2.15" memchr = "2" num-derive = "0.4" diff --git a/src/event.rs b/src/event.rs index 20674d5f..49331c5e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -2393,53 +2393,16 @@ impl<'a> EventDb<'a> { EventIterator { inner: iter } } - /// Creates a raw iterator over key-value pairs for migration purposes. + /// Creates a raw iterator over key-value pairs for the entire events. /// /// Unlike `iter_forward`, this returns raw bytes without deserializing the event fields. /// This is useful for migrations that need to transform data between formats. #[must_use] - pub fn raw_iter(&self) -> RawEventIterator<'_> { + pub fn raw_iter_forward(&self) -> RawEventIterator<'_> { let iter = self.inner.iterator(IteratorMode::Start); RawEventIterator { inner: iter } } - /// Updates a raw key-value pair in the database. - /// - /// This method is intended for migration purposes where raw bytes need to be - /// updated without going through the normal event deserialization/serialization. - /// - /// # Errors - /// - /// Returns an error if a database operation fails. - pub fn raw_update(&self, key: &[u8], old_value: &[u8], new_value: &[u8]) -> Result<()> { - loop { - let txn = self.inner.transaction(); - if let Some(current_value) = txn - .get_for_update(key, super::EXCLUSIVE) - .context("cannot read from event database")? - { - if old_value != current_value.as_slice() { - bail!("old value mismatch"); - } - } else { - bail!("no such entry"); - } - - txn.put(key, new_value) - .context("failed to write new entry")?; - - match txn.commit() { - Ok(()) => break, - Err(e) => { - if !e.as_ref().starts_with("Resource busy:") { - return Err(e).context("failed to update entry"); - } - } - } - } - Ok(()) - } - /// Stores a new event into the database. /// /// # Errors @@ -2927,7 +2890,7 @@ pub enum InvalidEvent { Value(Box<[u8]>), } -/// A raw iterator over event key-value pairs for migration purposes. +/// A raw iterator over event key-value pairs. /// /// This iterator returns raw bytes without deserializing the event fields, /// which is useful for migrations that need to transform data between formats. @@ -3031,12 +2994,12 @@ mod tests { fn example_message(kind: EventKind, category: EventCategory) -> EventMessage { let fields = DnsEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3148,12 +3111,12 @@ mod tests { fn syslog_for_dga() { let fields = DgaFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -3302,12 +3265,12 @@ mod tests { let fields = HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -3375,12 +3338,12 @@ mod tests { fn syslog_for_nonbrowser() { let fields = HttpEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3443,12 +3406,12 @@ mod tests { fn syslog_for_blocklist_http() { let fields = BlocklistHttpFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -3512,12 +3475,12 @@ mod tests { fn syslog_for_lockyransomware() { let fields = DnsEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 4)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -3575,11 +3538,11 @@ mod tests { fn syslog_for_portscan() { let fields = PortScanFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], + resp_country_code: *b"XX", start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -3606,7 +3569,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_country_code="XX" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" resp_country_code="XX" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" confidence="0.3""# ); let port_scan = Event::PortScan(PortScan::new( @@ -3616,7 +3579,7 @@ mod tests { .to_string(); assert_eq!( &port_scan, - r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_country_code="XX" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="PortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addr="127.0.0.2" resp_ports="80,443,8000,8080,8888,8443,9000,9001,9002" resp_country_code="XX" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" proto="6" triage_scores="""# ); } @@ -3624,14 +3587,14 @@ mod tests { fn syslog_for_multihostportscan() { let fields = MultiHostPortScanFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - resp_country_codes: vec![*b"XX", *b"XX"], + orig_country_code: *b"XX", resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], resp_port: 80, + resp_country_codes: vec![*b"XX", *b"XX"], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -3658,7 +3621,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" resp_country_codes="XX,XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# ); let multi_host_port_scan = Event::MultiHostPortScan(MultiHostPortScan::new( @@ -3668,7 +3631,7 @@ mod tests { .to_string(); assert_eq!( &multi_host_port_scan, - r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="MultiHostPortScan" category="Reconnaissance" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_port="80" resp_country_codes="XX,XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# ); } @@ -3676,13 +3639,13 @@ mod tests { fn syslog_for_externalddos() { let fields = ExternalDdosFields { sensor: String::new(), - orig_country_codes: vec![*b"XX", *b"XX"], orig_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - resp_country_code: *b"XX", + orig_country_codes: vec![*b"XX", *b"XX"], resp_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + resp_country_code: *b"XX", start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -3708,7 +3671,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" sensor="" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" sensor="" orig_addrs="127.0.0.2,127.0.0.3" orig_country_codes="XX,XX" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" confidence="0.3""# ); let external_ddos = Event::ExternalDdos(ExternalDdos::new( @@ -3718,19 +3681,19 @@ mod tests { .to_string(); assert_eq!( &external_ddos, - r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" orig_addrs="127.0.0.2,127.0.0.3" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# + r#"time="1970-01-01T01:01:01+00:00" event_kind="ExternalDdos" category="Impact" orig_addrs="127.0.0.2,127.0.0.3" orig_country_codes="XX,XX" resp_addr="127.0.0.1" resp_country_code="XX" proto="6" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:01:02+00:00" triage_scores="""# ); } fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 67, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -3858,12 +3821,12 @@ mod tests { fn syslog_for_blocklist_conn() { let fields = BlocklistConnFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 80, + resp_country_code: *b"XX", proto: 6, conn_state: "SAF".to_string(), start_time: Utc @@ -3912,12 +3875,12 @@ mod tests { fn syslog_for_blocklist_dcerpc() { let fields = BlocklistDceRpcFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 135, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -3965,12 +3928,12 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::from_str("127.0.0.1").unwrap(), orig_port: 68, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::from_str("127.0.0.2").unwrap(), resp_port: 67, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -4105,12 +4068,12 @@ mod tests { fn syslog_for_dnscovertchannel() { let fields = DnsEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4173,12 +4136,12 @@ mod tests { fn syslog_for_cryptocurrencyminingpool() { let fields = CryptocurrencyMiningPoolFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4237,12 +4200,12 @@ mod tests { fn syslog_for_blocklist_dns() { let fields = BlocklistDnsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -4298,11 +4261,11 @@ mod tests { fn syslog_for_ftpbruteforce() { let fields = FtpBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, + resp_country_code: *b"XX", proto: 6, user_list: vec!["user1".to_string(), "user_2".to_string()], start_time: Utc @@ -4365,12 +4328,12 @@ mod tests { let fields = FtpEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4431,12 +4394,12 @@ mod tests { }; FtpEventFields { - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 21, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4563,12 +4526,12 @@ mod tests { .unwrap(); let fields = RepeatedHttpSessionsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, + resp_country_code: *b"XX", proto: 6, start_time: now, end_time: now, @@ -4604,12 +4567,12 @@ mod tests { fn syslog_for_blocklist_kerberos() { let fields = BlocklistKerberosFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 88, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -4664,11 +4627,11 @@ mod tests { fn syslog_for_ldapbruteforce() { let fields = LdapBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, + resp_country_code: *b"XX", proto: 6, user_pw_list: vec![ ("user1".to_string(), "pw1".to_string()), @@ -4718,12 +4681,12 @@ mod tests { fn syslog_for_ldapplaintext() { let fields = LdapEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4775,12 +4738,12 @@ mod tests { fn ldapeventfields() -> LdapEventFields { LdapEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 389, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -4904,12 +4867,12 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1812, + resp_country_code: *b"XX", proto: 17, start_time: 0, duration: 0, @@ -5039,12 +5002,12 @@ mod tests { fn syslog_for_blocklist_mqtt() { let fields = BlocklistMqttFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 1883, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5097,12 +5060,12 @@ mod tests { let fields = NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, service: "http".to_string(), start_time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap(), @@ -5141,12 +5104,12 @@ mod tests { fn syslog_for_blocklist_nfs() { let fields = BlocklistNfsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 2049, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5194,12 +5157,12 @@ mod tests { fn syslog_for_blocklist_ntlm() { let fields = BlocklistNtlmFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5279,12 +5242,12 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5413,13 +5376,13 @@ mod tests { fn syslog_for_rdpbruteforce() { let fields = RdpBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), - resp_country_codes: vec![*b"XX", *b"XX"], + orig_country_code: *b"XX", resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], + resp_country_codes: vec![*b"XX", *b"XX"], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -5446,7 +5409,7 @@ mod tests { let (_, _, syslog_message) = message.unwrap(); assert_eq!( &syslog_message, - r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" confidence="0.3""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" sensor="" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_country_codes="XX,XX" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" confidence="0.3""# ); let rdp_brute_force = Event::RdpBruteForce(RdpBruteForce::new( @@ -5457,7 +5420,7 @@ mod tests { assert_eq!( &rdp_brute_force, - r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" triage_scores="""# + r#"time="1970-01-01T00:01:01+00:00" event_kind="RdpBruteForce" category="Discovery" orig_addr="127.0.0.1" orig_country_code="XX" resp_addrs="127.0.0.2,127.0.0.3" resp_country_codes="XX,XX" start_time="1970-01-01T00:01:01+00:00" end_time="1970-01-01T00:10:02+00:00" proto="6" triage_scores="""# ); } @@ -5465,12 +5428,12 @@ mod tests { fn syslog_for_blocklist_rdp() { let fields = BlocklistRdpFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 3389, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5517,12 +5480,12 @@ mod tests { fn syslog_for_blocklist_smb() { let fields = BlocklistSmbFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 445, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5579,12 +5542,12 @@ mod tests { fn syslog_for_blocklist_smtp() { let fields = BlocklistSmtpFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 25, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5637,12 +5600,12 @@ mod tests { fn syslog_for_blocklist_ssh() { let fields = BlocklistSshFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 22, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5755,12 +5718,12 @@ mod tests { fn syslog_for_blocklist_tls() { let fields = BlocklistTlsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -5836,12 +5799,12 @@ mod tests { resp_pkts: 0, orig_l2_bytes: 0, resp_l2_bytes: 0, - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, + resp_country_code: *b"XX", proto: 6, method: "GET".to_string(), host: "host".to_string(), @@ -5968,12 +5931,12 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, - resp_country_code: *b"XX", + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), resp_port: 443, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) diff --git a/src/event/bootp.rs b/src/event/bootp.rs index 8099faa9..2ae2eb12 100644 --- a/src/event/bootp.rs +++ b/src/event/bootp.rs @@ -118,12 +118,12 @@ pub struct BlocklistBootpFieldsV0_44 { pub struct BlocklistBootp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -186,12 +186,12 @@ impl BlocklistBootp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/common.rs b/src/event/common.rs index 46eeba29..ad830e84 100644 --- a/src/event/common.rs +++ b/src/event/common.rs @@ -1604,12 +1604,12 @@ mod tests { fn blocklist_bootp_fields() -> BlocklistBootpFields { BlocklistBootpFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 67, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1640,12 +1640,12 @@ mod tests { fn blocklist_conn_fields() -> BlocklistConnFields { BlocklistConnFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, conn_state: "SAF".to_string(), start_time: Utc @@ -1669,12 +1669,12 @@ mod tests { fn blocklist_dcerpc_fields() -> BlocklistDceRpcFields { BlocklistDceRpcFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 135, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1698,12 +1698,12 @@ mod tests { fn blocklist_dhcp_fields() -> BlocklistDhcpFields { BlocklistDhcpFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 68, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 67, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1742,12 +1742,12 @@ mod tests { fn blocklist_dns_fields() -> BlocklistDnsFields { BlocklistDnsFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1779,12 +1779,12 @@ mod tests { fn blocklist_http_fields() -> BlocklistHttpFields { BlocklistHttpFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1824,12 +1824,12 @@ mod tests { fn blocklist_kerberos_fields() -> BlocklistKerberosFields { BlocklistKerberosFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 88, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1858,12 +1858,12 @@ mod tests { fn blocklist_mqtt_fields() -> BlocklistMqttFields { BlocklistMqttFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 1883, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1889,12 +1889,12 @@ mod tests { fn blocklist_nfs_fields() -> BlocklistNfsFields { BlocklistNfsFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 2049, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1916,12 +1916,12 @@ mod tests { fn blocklist_ntlm_fields() -> BlocklistNtlmFields { BlocklistNtlmFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 445, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1946,12 +1946,12 @@ mod tests { fn blocklist_rdp_fields() -> BlocklistRdpFields { BlocklistRdpFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 3389, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -1972,12 +1972,12 @@ mod tests { fn blocklist_smb_fields() -> BlocklistSmbFields { BlocklistSmbFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 445, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2008,12 +2008,12 @@ mod tests { fn blocklist_smtp_fields() -> BlocklistSmtpFields { BlocklistSmtpFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 25, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2040,12 +2040,12 @@ mod tests { fn blocklist_ssh_fields() -> BlocklistSshFields { BlocklistSshFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 22, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2078,12 +2078,12 @@ mod tests { fn blocklist_tls_fields() -> BlocklistTlsFields { BlocklistTlsFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 443, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2124,12 +2124,12 @@ mod tests { fn ldap_event_fields() -> LdapEventFields { LdapEventFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 389, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2171,12 +2171,12 @@ mod tests { FtpEventFields { sensor: "collector1".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 21, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2199,11 +2199,11 @@ mod tests { fn port_scan_fields() -> PortScanFields { PortScanFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_ports: vec![80, 443, 8000, 8080, 8888, 8443, 9000, 9001, 9002], + resp_country_code: *b"XX", start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2223,14 +2223,14 @@ mod tests { fn multi_host_port_scan_fields() -> MultiHostPortScanFields { MultiHostPortScanFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + orig_country_code: *b"XX", resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), ], - resp_country_codes: vec![*b"XX", *b"XX"], resp_port: 80, + resp_country_codes: vec![*b"XX", *b"XX"], start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) .unwrap() @@ -2276,12 +2276,12 @@ mod tests { fn crypto_miining_pool_fields() -> CryptocurrencyMiningPoolFields { CryptocurrencyMiningPoolFields { sensor: "sensro".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2314,11 +2314,11 @@ mod tests { fn ftp_brute_force_fields() -> FtpBruteForceFields { FtpBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 21, + resp_country_code: *b"XX", proto: 6, user_list: vec!["user1".to_string(), "user_2".to_string()], start_time: Utc @@ -2341,12 +2341,12 @@ mod tests { let now = chrono::Utc::now().timestamp_nanos_opt().unwrap(); RepeatedHttpSessionsFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 443, + resp_country_code: *b"XX", proto: 6, start_time: now, end_time: now, @@ -2358,12 +2358,12 @@ mod tests { fn dga_fields() -> DgaFields { DgaFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2403,12 +2403,12 @@ mod tests { fn http_event_fields() -> HttpEventFields { HttpEventFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2448,11 +2448,11 @@ mod tests { fn ldap_brute_force_fields() -> LdapBruteForceFields { LdapBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 389, + resp_country_code: *b"XX", proto: 6, user_pw_list: vec![ ("user1".to_string(), "pw1".to_string()), @@ -2476,8 +2476,8 @@ mod tests { fn rdp_brute_force_fields() -> RdpBruteForceFields { RdpBruteForceFields { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), + orig_country_code: *b"XX", resp_addrs: vec![ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)), @@ -2502,12 +2502,12 @@ mod tests { fn dns_event_fields() -> DnsEventFields { DnsEventFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) @@ -2540,12 +2540,12 @@ mod tests { NetworkThreat { time: Utc.with_ymd_and_hms(1970, 1, 1, 1, 1, 1).unwrap(), sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, service: "http".to_string(), start_time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap(), @@ -2610,12 +2610,12 @@ mod tests { HttpThreatFields { time: Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 80, + resp_country_code: *b"XX", proto: 6, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2659,12 +2659,12 @@ mod tests { fn blocklist_radius_fields() -> BlocklistRadiusFields { BlocklistRadiusFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 1812, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) @@ -2698,12 +2698,12 @@ mod tests { fn blocklist_malformed_dns_fields() -> BlocklistMalformedDnsFields { BlocklistMalformedDnsFields { sensor: "sensor".to_string(), - orig_country_code: *b"XX", orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), orig_port: 10000, + orig_country_code: *b"XX", resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), - resp_country_code: *b"XX", resp_port: 53, + resp_country_code: *b"XX", proto: 17, start_time: Utc .with_ymd_and_hms(1970, 1, 1, 0, 0, 0) diff --git a/src/event/conn.rs b/src/event/conn.rs index c21ca865..e5a1ae49 100644 --- a/src/event/conn.rs +++ b/src/event/conn.rs @@ -2,6 +2,7 @@ use std::{fmt, net::IpAddr, num::NonZeroU8}; use attrievent::attribute::{ConnAttr, RawEventAttrKind}; use chrono::{DateTime, Utc}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; @@ -43,8 +44,8 @@ pub struct PortScanFieldsV0_44 { pub orig_addr: IpAddr, pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_ports: Vec, + pub resp_country_code: [u8; 2], /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, /// Timestamp in nanoseconds since the Unix epoch (UTC). @@ -60,7 +61,7 @@ impl PortScanFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_country_code={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_ports={:?} resp_country_code={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -69,8 +70,8 @@ impl PortScanFields { self.orig_addr.to_string(), std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), - std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), vector_to_string(&self.resp_ports), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), self.proto.to_string(), @@ -84,11 +85,11 @@ impl PortScanFields { pub struct PortScan { pub sensor: String, pub time: DateTime, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_ports: Vec, + pub resp_country_code: [u8; 2], pub start_time: DateTime, pub end_time: DateTime, pub proto: u8, @@ -101,12 +102,12 @@ impl fmt::Display for PortScan { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_country_code={:?} resp_ports={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addr={:?} resp_ports={:?} resp_country_code={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", self.orig_addr.to_string(), std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), self.resp_addr.to_string(), - std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), vector_to_string(&self.resp_ports), + std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), self.proto.to_string(), @@ -120,11 +121,11 @@ impl PortScan { PortScan { sensor: fields.sensor.clone(), time, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_ports: fields.resp_ports.clone(), + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -204,8 +205,8 @@ pub struct MultiHostPortScanFieldsV0_44 { pub orig_addr: IpAddr, pub orig_country_code: [u8; 2], pub resp_addrs: Vec, - pub resp_country_codes: Vec<[u8; 2]>, pub resp_port: u16, + pub resp_country_codes: Vec<[u8; 2]>, pub proto: u8, /// Timestamp in nanoseconds since the Unix epoch (UTC). pub start_time: i64, @@ -221,7 +222,7 @@ impl MultiHostPortScanFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} resp_country_codes={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -231,6 +232,10 @@ impl MultiHostPortScanFields { std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), self.resp_port.to_string(), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.proto.to_string(), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), @@ -244,10 +249,10 @@ impl MultiHostPortScanFields { pub struct MultiHostPortScan { pub sensor: String, pub time: DateTime, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, - pub resp_port: u16, + pub orig_country_code: [u8; 2], pub resp_addrs: Vec, + pub resp_port: u16, pub resp_country_codes: Vec<[u8; 2]>, pub proto: u8, pub start_time: DateTime, @@ -261,11 +266,15 @@ impl fmt::Display for MultiHostPortScan { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_port={:?} resp_country_codes={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", self.orig_addr.to_string(), std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), self.resp_port.to_string(), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.proto.to_string(), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), @@ -279,10 +288,10 @@ impl MultiHostPortScan { MultiHostPortScan { sensor: fields.sensor.clone(), time, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, - resp_port: fields.resp_port, + orig_country_code: fields.orig_country_code, resp_addrs: fields.resp_addrs.clone(), + resp_port: fields.resp_port, resp_country_codes: fields.resp_country_codes.clone(), proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -380,13 +389,17 @@ impl ExternalDdosFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addrs={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addrs={:?} orig_country_codes={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string ), self.sensor, vector_to_string(&self.orig_addrs), + self.orig_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.resp_addr.to_string(), std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), @@ -418,8 +431,12 @@ impl fmt::Display for ExternalDdos { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "orig_addrs={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", + "orig_addrs={:?} orig_country_codes={:?} resp_addr={:?} resp_country_code={:?} proto={:?} start_time={:?} end_time={:?} triage_scores={:?}", vector_to_string(&self.orig_addrs), + self.orig_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.resp_addr.to_string(), std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"), self.proto.to_string(), @@ -575,12 +592,12 @@ impl BlocklistConnFields { pub struct BlocklistConn { pub sensor: String, pub time: DateTime, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub conn_state: String, pub start_time: DateTime, @@ -630,12 +647,12 @@ impl BlocklistConn { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, conn_state: fields.conn_state, start_time: DateTime::from_timestamp_nanos(fields.start_time), diff --git a/src/event/dcerpc.rs b/src/event/dcerpc.rs index 3ac3f1d0..f6db45b4 100644 --- a/src/event/dcerpc.rs +++ b/src/event/dcerpc.rs @@ -70,12 +70,12 @@ impl BlocklistDceRpcFields { pub struct BlocklistDceRpc { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -125,12 +125,12 @@ impl BlocklistDceRpc { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/dhcp.rs b/src/event/dhcp.rs index 4673469d..edbd7431 100644 --- a/src/event/dhcp.rs +++ b/src/event/dhcp.rs @@ -157,12 +157,12 @@ impl BlocklistDhcpFields { pub struct BlocklistDhcp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -241,12 +241,12 @@ impl BlocklistDhcp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/dns.rs b/src/event/dns.rs index 0750e99a..14c47860 100644 --- a/src/event/dns.rs +++ b/src/event/dns.rs @@ -127,12 +127,12 @@ impl DnsEventFields { pub struct DnsCovertChannel { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -199,19 +199,19 @@ impl DnsCovertChannel { Self { time, sensor: fields.sensor, + orig_addr: fields.orig_addr, + orig_port: fields.orig_port, orig_country_code: fields.orig_country_code, + resp_addr: fields.resp_addr, + resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, + proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - orig_addr: fields.orig_addr, - orig_port: fields.orig_port, - resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, - resp_port: fields.resp_port, - proto: fields.proto, query: fields.query, answer: fields.answer, trans_id: fields.trans_id, @@ -305,12 +305,12 @@ impl Match for DnsCovertChannel { pub struct LockyRansomware { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -377,19 +377,19 @@ impl LockyRansomware { Self { time, sensor: fields.sensor, + orig_addr: fields.orig_addr, + orig_port: fields.orig_port, orig_country_code: fields.orig_country_code, + resp_addr: fields.resp_addr, + resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, + proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - orig_addr: fields.orig_addr, - orig_port: fields.orig_port, - resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, - resp_port: fields.resp_port, - proto: fields.proto, query: fields.query, answer: fields.answer, trans_id: fields.trans_id, @@ -561,12 +561,12 @@ impl CryptocurrencyMiningPoolFields { pub struct CryptocurrencyMiningPool { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -634,19 +634,19 @@ impl CryptocurrencyMiningPool { Self { time, sensor: fields.sensor, + orig_addr: fields.orig_addr, + orig_port: fields.orig_port, orig_country_code: fields.orig_country_code, + resp_addr: fields.resp_addr, + resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, + proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - orig_addr: fields.orig_addr, - orig_port: fields.orig_port, - resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, - resp_port: fields.resp_port, - proto: fields.proto, query: fields.query, answer: fields.answer, trans_id: fields.trans_id, @@ -817,12 +817,12 @@ impl BlocklistDnsFields { pub struct BlocklistDns { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -888,14 +888,14 @@ impl BlocklistDns { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, diff --git a/src/event/ftp.rs b/src/event/ftp.rs index 534ffe60..11e24223 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -211,11 +211,11 @@ impl From for FtpBruteForceFieldsV0_44 { fn from(value: FtpBruteForceFieldsV0_41) -> Self { Self { sensor: String::new(), - orig_country_code: *b"XX", orig_addr: value.src_addr, + orig_country_code: *b"XX", resp_addr: value.dst_addr, - resp_country_code: *b"XX", resp_port: value.dst_port, + resp_country_code: *b"XX", proto: value.proto, user_list: value.user_list, start_time: value.start_time.timestamp_nanos_opt().unwrap_or_default(), @@ -244,12 +244,12 @@ pub(crate) struct FtpBruteForceFieldsV0_41 { #[derive(Serialize, Deserialize)] pub struct FtpBruteForce { pub sensor: String, - pub orig_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub user_list: Vec, pub start_time: DateTime, @@ -284,12 +284,12 @@ impl FtpBruteForce { pub(super) fn new(time: DateTime, fields: &FtpBruteForceFields) -> Self { FtpBruteForce { sensor: fields.sensor.clone(), - orig_country_code: fields.orig_country_code, time, orig_addr: fields.orig_addr, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, user_list: fields.user_list.clone(), start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -434,12 +434,12 @@ pub struct FtpEventFieldsV0_44 { pub struct FtpPlainText { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -494,14 +494,14 @@ impl FtpPlainText { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, @@ -571,12 +571,12 @@ impl Match for FtpPlainText { pub struct BlocklistFtp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -631,14 +631,14 @@ impl BlocklistFtp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, diff --git a/src/event/http.rs b/src/event/http.rs index bf284961..87e10fb2 100644 --- a/src/event/http.rs +++ b/src/event/http.rs @@ -201,12 +201,12 @@ impl RepeatedHttpSessionsFields { pub struct RepeatedHttpSessions { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub end_time: DateTime, @@ -240,12 +240,12 @@ impl RepeatedHttpSessions { RepeatedHttpSessions { time, sensor: fields.sensor.clone(), - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), end_time: DateTime::from_timestamp_nanos(fields.end_time), @@ -443,12 +443,12 @@ pub struct HttpThreat { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -541,14 +541,14 @@ impl HttpThreat { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, @@ -773,12 +773,12 @@ pub struct DomainGenerationAlgorithm { #[serde(with = "ts_nanoseconds")] pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -861,21 +861,21 @@ impl DomainGenerationAlgorithm { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - host: fields.host, method: fields.method, + host: fields.host, uri: fields.uri, referer: fields.referer, version: fields.version, @@ -970,12 +970,12 @@ impl Match for DomainGenerationAlgorithm { pub struct NonBrowser { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -1057,19 +1057,19 @@ impl NonBrowser { NonBrowser { time, sensor: fields.sensor.clone(), + orig_addr: fields.orig_addr, + orig_port: fields.orig_port, orig_country_code: fields.orig_country_code, + resp_addr: fields.resp_addr, + resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, + proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - orig_addr: fields.orig_addr, - orig_port: fields.orig_port, - resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, - resp_port: fields.resp_port, - proto: fields.proto, method: fields.method.clone(), host: fields.host.clone(), uri: fields.uri.clone(), @@ -1170,12 +1170,12 @@ pub type BlocklistHttpFields = DgaFields; pub struct BlocklistHttp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -1257,14 +1257,14 @@ impl BlocklistHttp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, diff --git a/src/event/kerberos.rs b/src/event/kerberos.rs index bc94fbcd..257ef9e5 100644 --- a/src/event/kerberos.rs +++ b/src/event/kerberos.rs @@ -116,12 +116,12 @@ impl BlocklistKerberosFields { pub struct BlocklistKerberos { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -181,12 +181,12 @@ impl BlocklistKerberos { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/ldap.rs b/src/event/ldap.rs index 1e3c6f5e..da4223d4 100644 --- a/src/event/ldap.rs +++ b/src/event/ldap.rs @@ -108,12 +108,12 @@ fn get_user_pw_list(user_pw_list: &[(String, String)]) -> String { #[derive(Serialize, Deserialize)] pub struct LdapBruteForce { pub sensor: String, - pub orig_country_code: [u8; 2], pub time: DateTime, pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub user_pw_list: Vec<(String, String)>, pub start_time: DateTime, @@ -146,12 +146,12 @@ impl LdapBruteForce { pub(super) fn new(time: DateTime, fields: &LdapBruteForceFields) -> Self { LdapBruteForce { sensor: fields.sensor.clone(), - orig_country_code: fields.orig_country_code, time, orig_addr: fields.orig_addr, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, user_pw_list: fields.user_pw_list.clone(), start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -293,12 +293,12 @@ impl LdapEventFields { pub struct LdapPlainText { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -354,14 +354,14 @@ impl LdapPlainText { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, @@ -435,12 +435,12 @@ impl Match for LdapPlainText { pub struct BlocklistLdap { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -494,14 +494,14 @@ impl BlocklistLdap { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, diff --git a/src/event/malformed_dns.rs b/src/event/malformed_dns.rs index ff7ecf42..5a3b61ae 100644 --- a/src/event/malformed_dns.rs +++ b/src/event/malformed_dns.rs @@ -118,12 +118,12 @@ fn format_vec_vec_u8(data: &[Vec]) -> String { pub struct BlocklistMalformedDns { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -191,12 +191,12 @@ impl BlocklistMalformedDns { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/mqtt.rs b/src/event/mqtt.rs index 97bc7342..66991040 100644 --- a/src/event/mqtt.rs +++ b/src/event/mqtt.rs @@ -112,12 +112,12 @@ impl BlocklistMqttFields { pub struct BlocklistMqtt { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -171,12 +171,12 @@ impl BlocklistMqtt { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/nfs.rs b/src/event/nfs.rs index f3ac8127..39e9aed1 100644 --- a/src/event/nfs.rs +++ b/src/event/nfs.rs @@ -95,12 +95,12 @@ impl BlocklistNfsFields { pub struct BlocklistNfs { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -145,12 +145,12 @@ impl BlocklistNfs { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/ntlm.rs b/src/event/ntlm.rs index 474ec9cf..b9b57a12 100644 --- a/src/event/ntlm.rs +++ b/src/event/ntlm.rs @@ -100,12 +100,12 @@ impl BlocklistNtlmFields { pub struct BlocklistNtlm { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -155,12 +155,12 @@ impl BlocklistNtlm { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/radius.rs b/src/event/radius.rs index 25d2048a..4ac944bb 100644 --- a/src/event/radius.rs +++ b/src/event/radius.rs @@ -126,12 +126,12 @@ impl BlocklistRadiusFields { pub struct BlocklistRadius { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -203,12 +203,12 @@ impl BlocklistRadius { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/rdp.rs b/src/event/rdp.rs index c7d03a45..cf2f5434 100644 --- a/src/event/rdp.rs +++ b/src/event/rdp.rs @@ -4,6 +4,7 @@ use std::{fmt, net::IpAddr, num::NonZeroU8}; use attrievent::attribute::{RawEventAttrKind, RdpAttr}; use chrono::{DateTime, Utc}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use super::{ @@ -59,7 +60,7 @@ impl RdpBruteForceFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", + "category={:?} sensor={:?} orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_country_codes={:?} start_time={:?} end_time={:?} proto={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -68,6 +69,10 @@ impl RdpBruteForceFields { self.orig_addr.to_string(), std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), self.proto.to_string(), @@ -80,8 +85,8 @@ impl RdpBruteForceFields { pub struct RdpBruteForce { pub sensor: String, pub time: DateTime, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, + pub orig_country_code: [u8; 2], pub resp_addrs: Vec, pub resp_country_codes: Vec<[u8; 2]>, pub start_time: DateTime, @@ -96,10 +101,14 @@ impl fmt::Display for RdpBruteForce { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", + "orig_addr={:?} orig_country_code={:?} resp_addrs={:?} resp_country_codes={:?} start_time={:?} end_time={:?} proto={:?} triage_scores={:?}", self.orig_addr.to_string(), std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"), vector_to_string(&self.resp_addrs), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), self.proto.to_string(), @@ -113,8 +122,8 @@ impl RdpBruteForce { RdpBruteForce { sensor: fields.sensor.clone(), time, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, + orig_country_code: fields.orig_country_code, resp_addrs: fields.resp_addrs.clone(), resp_country_codes: fields.resp_country_codes.clone(), start_time: DateTime::from_timestamp_nanos(fields.start_time), @@ -245,12 +254,12 @@ impl BlocklistRdpFields { pub struct BlocklistRdp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -293,12 +302,12 @@ impl BlocklistRdp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/smb.rs b/src/event/smb.rs index 0315fe84..4e166683 100644 --- a/src/event/smb.rs +++ b/src/event/smb.rs @@ -118,12 +118,12 @@ impl BlocklistSmbFields { pub struct BlocklistSmb { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -185,12 +185,12 @@ impl BlocklistSmb { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/smtp.rs b/src/event/smtp.rs index ae49485a..9242484d 100644 --- a/src/event/smtp.rs +++ b/src/event/smtp.rs @@ -106,12 +106,12 @@ impl BlocklistSmtpFields { pub struct BlocklistSmtp { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -166,12 +166,12 @@ impl BlocklistSmtp { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/ssh.rs b/src/event/ssh.rs index f68ca3e6..0b909b02 100644 --- a/src/event/ssh.rs +++ b/src/event/ssh.rs @@ -126,12 +126,12 @@ impl BlocklistSshFields { pub struct BlocklistSsh { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -198,12 +198,12 @@ impl BlocklistSsh { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, diff --git a/src/event/tls.rs b/src/event/tls.rs index dc2ff583..e9b1794e 100644 --- a/src/event/tls.rs +++ b/src/event/tls.rs @@ -166,12 +166,12 @@ impl BlocklistTlsFields { pub struct BlocklistTls { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -256,12 +256,12 @@ impl BlocklistTls { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, @@ -350,12 +350,12 @@ impl Match for BlocklistTls { pub struct SuspiciousTlsTraffic { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -440,14 +440,14 @@ impl SuspiciousTlsTraffic { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, diff --git a/src/event/tor.rs b/src/event/tor.rs index 2a8e9ed5..2a73641d 100644 --- a/src/event/tor.rs +++ b/src/event/tor.rs @@ -17,12 +17,12 @@ use crate::event::{ pub struct TorConnection { pub time: DateTime, pub sensor: String, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -102,19 +102,19 @@ impl TorConnection { TorConnection { time, sensor: fields.sensor.clone(), + orig_addr: fields.orig_addr, + orig_port: fields.orig_port, orig_country_code: fields.orig_country_code, + resp_addr: fields.resp_addr, + resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, + proto: fields.proto, start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, orig_pkts: fields.orig_pkts, resp_pkts: fields.resp_pkts, orig_l2_bytes: fields.orig_l2_bytes, resp_l2_bytes: fields.resp_l2_bytes, - orig_addr: fields.orig_addr, - orig_port: fields.orig_port, - resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, - resp_port: fields.resp_port, - proto: fields.proto, method: fields.method.clone(), host: fields.host.clone(), uri: fields.uri.clone(), @@ -210,12 +210,12 @@ impl Match for TorConnection { pub struct TorConnectionConn { pub sensor: String, pub time: DateTime, - pub orig_country_code: [u8; 2], pub orig_addr: IpAddr, pub orig_port: u16, + pub orig_country_code: [u8; 2], pub resp_addr: IpAddr, - pub resp_country_code: [u8; 2], pub resp_port: u16, + pub resp_country_code: [u8; 2], pub proto: u8, pub start_time: DateTime, pub duration: i64, @@ -263,16 +263,16 @@ impl TorConnectionConn { Self { time, sensor: fields.sensor, - orig_country_code: fields.orig_country_code, - start_time: DateTime::from_timestamp_nanos(fields.start_time), orig_addr: fields.orig_addr, orig_port: fields.orig_port, + orig_country_code: fields.orig_country_code, resp_addr: fields.resp_addr, - resp_country_code: fields.resp_country_code, resp_port: fields.resp_port, + resp_country_code: fields.resp_country_code, proto: fields.proto, - conn_state: fields.conn_state, + start_time: DateTime::from_timestamp_nanos(fields.start_time), duration: fields.duration, + conn_state: fields.conn_state, service: fields.service, orig_bytes: fields.orig_bytes, resp_bytes: fields.resp_bytes, diff --git a/src/event/unusual_destination_pattern.rs b/src/event/unusual_destination_pattern.rs index 31d28149..be539ad0 100644 --- a/src/event/unusual_destination_pattern.rs +++ b/src/event/unusual_destination_pattern.rs @@ -2,6 +2,7 @@ use std::{fmt, net::IpAddr, num::NonZeroU8}; use attrievent::attribute::{ConnAttr, RawEventAttrKind}; use chrono::{DateTime, Utc}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; @@ -32,7 +33,7 @@ impl UnusualDestinationPatternFields { let start_time_dt = DateTime::from_timestamp_nanos(self.start_time); let end_time_dt = DateTime::from_timestamp_nanos(self.end_time); format!( - "category={:?} sensor={:?} start_time={:?} end_time={:?} destination_ips={:?} count={:?} expected_mean={:?} std_deviation={:?} z_score={:?} confidence={:?}", + "category={:?} sensor={:?} start_time={:?} end_time={:?} destination_ips={:?} resp_country_codes={:?} count={:?} expected_mean={:?} std_deviation={:?} z_score={:?} confidence={:?}", self.category.as_ref().map_or_else( || "Unspecified".to_string(), std::string::ToString::to_string @@ -41,6 +42,10 @@ impl UnusualDestinationPatternFields { start_time_dt.to_rfc3339(), end_time_dt.to_rfc3339(), format_ip_vec(&self.destination_ips), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.count.to_string(), self.expected_mean.to_string(), self.std_deviation.to_string(), @@ -78,11 +83,15 @@ impl fmt::Display for UnusualDestinationPattern { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "sensor={:?} start_time={:?} end_time={:?} destination_ips={:?} count={:?} expected_mean={:?} std_deviation={:?} z_score={:?} triage_scores={:?}", + "sensor={:?} start_time={:?} end_time={:?} destination_ips={:?} resp_country_codes={:?} count={:?} expected_mean={:?} std_deviation={:?} z_score={:?} triage_scores={:?}", self.sensor, self.start_time.to_rfc3339(), self.end_time.to_rfc3339(), format_ip_vec(&self.destination_ips), + self.resp_country_codes + .iter() + .map(|code| std::str::from_utf8(code).unwrap_or("XX")) + .join(","), self.count.to_string(), self.expected_mean.to_string(), self.std_deviation.to_string(), diff --git a/src/migration.rs b/src/migration.rs index e8c7d787..93642d02 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -273,7 +273,7 @@ fn migrate_0_43_to_0_44( migrate_network_cf(data_dir)?; // Step 3: Migrate event fields to add country codes using Store abstraction - let store = crate::Store::new(data_dir, backup_dir) + let store = super::Store::new(data_dir, backup_dir) .context("Failed to open Store for event migration")?; migrate_event_country_codes(&store, locator)?; @@ -857,9 +857,9 @@ fn migrate_network_cf_inner( /// Migrates event fields from `V0_43` format (without country codes) to `V0_44` format /// (with country codes). If a locator is provided, country codes are resolved from -/// IP addresses. Otherwise, country codes are set to None. +/// IP addresses. Otherwise, country codes are set to "ZZ" (unknown). fn migrate_event_country_codes( - store: &crate::Store, + store: &super::Store, locator: Option<&ip2location::DB>, ) -> Result<()> { use num_traits::FromPrimitive; @@ -884,7 +884,7 @@ fn migrate_event_country_codes( // Collect all events that need migration using raw iterator let entries_to_migrate: Vec<(Vec, Vec)> = events - .raw_iter() + .raw_iter_forward() .map(|(key, value)| (key.to_vec(), value.to_vec())) .collect(); @@ -900,13 +900,17 @@ fn migrate_event_country_codes( for (key, value) in &entries_to_migrate { // Extract the event kind from the key (bits 32-63 of the 128-bit key) - let kind_value = if key.len() >= 16 { - let key_i128 = i128::from_be_bytes(key[..16].try_into().unwrap_or([0; 16])); - ((key_i128 >> 32) & 0xFFFF_FFFF) as i32 + let key_i128 = if key.len() >= 16 { + let Ok(key_bytes) = key[..16].try_into() else { + skipped_count += 1; + continue; + }; + i128::from_be_bytes(key_bytes) } else { skipped_count += 1; continue; }; + let kind_value = ((key_i128 >> 32) & 0xFFFF_FFFF) as i32; let Some(kind) = EventKind::from_i32(kind_value) else { skipped_count += 1; @@ -917,107 +921,137 @@ fn migrate_event_country_codes( // Events store raw field bytes directly (not EventMessage wrapper) let new_fields: Vec = match kind { EventKind::DnsCovertChannel | EventKind::LockyRansomware => { - migrate_fields::(value, locator)? - } - EventKind::HttpThreat => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::( + value, locator, + )? } - EventKind::RdpBruteForce => { - migrate_fields::(value, locator)? - } - EventKind::RepeatedHttpSessions => migrate_fields::< + EventKind::HttpThreat => migrate_event_with_country_code::< + HttpThreatFieldsV0_43, + HttpThreatFields, + >(value, locator)?, + EventKind::RdpBruteForce => migrate_event_with_country_code::< + RdpBruteForceFieldsV0_43, + RdpBruteForceFields, + >(value, locator)?, + EventKind::RepeatedHttpSessions => migrate_event_with_country_code::< RepeatedHttpSessionsFieldsV0_43, RepeatedHttpSessionsFields, >(value, locator)?, EventKind::TorConnection | EventKind::NonBrowser | EventKind::BlocklistHttp => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::( + value, locator, + )? } EventKind::TorConnectionConn | EventKind::BlocklistConn => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::( + value, locator, + )? } EventKind::DomainGenerationAlgorithm => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::(value, locator)? } - EventKind::FtpBruteForce => { - migrate_fields::(value, locator)? - } - EventKind::FtpPlainText | EventKind::BlocklistFtp => { - migrate_fields::(value, locator)? - } - EventKind::PortScan => { - migrate_fields::(value, locator)? - } - EventKind::MultiHostPortScan => migrate_fields::< + EventKind::FtpBruteForce => migrate_event_with_country_code::< + FtpBruteForceFieldsV0_43, + FtpBruteForceFields, + >(value, locator)?, + EventKind::FtpPlainText | EventKind::BlocklistFtp => migrate_event_with_country_code::< + FtpEventFieldsV0_43, + FtpEventFields, + >(value, locator)?, + EventKind::PortScan => migrate_event_with_country_code::< + PortScanFieldsV0_43, + PortScanFields, + >(value, locator)?, + EventKind::MultiHostPortScan => migrate_event_with_country_code::< MultiHostPortScanFieldsV0_43, MultiHostPortScanFields, >(value, locator)?, - EventKind::ExternalDdos => { - migrate_fields::(value, locator)? - } - EventKind::LdapBruteForce => { - migrate_fields::(value, locator)? - } + EventKind::ExternalDdos => migrate_event_with_country_code::< + ExternalDdosFieldsV0_43, + ExternalDdosFields, + >(value, locator)?, + EventKind::LdapBruteForce => migrate_event_with_country_code::< + LdapBruteForceFieldsV0_43, + LdapBruteForceFields, + >(value, locator)?, EventKind::LdapPlainText | EventKind::BlocklistLdap => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::( + value, locator, + )? } - EventKind::CryptocurrencyMiningPool => migrate_fields::< + EventKind::CryptocurrencyMiningPool => migrate_event_with_country_code::< CryptocurrencyMiningPoolFieldsV0_43, CryptocurrencyMiningPoolFields, >(value, locator)?, - EventKind::BlocklistBootp => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistDceRpc => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistDhcp => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistDns => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistKerberos => migrate_fields::< + EventKind::BlocklistBootp => migrate_event_with_country_code::< + BlocklistBootpFieldsV0_43, + BlocklistBootpFields, + >(value, locator)?, + EventKind::BlocklistDceRpc => migrate_event_with_country_code::< + BlocklistDceRpcFieldsV0_43, + BlocklistDceRpcFields, + >(value, locator)?, + EventKind::BlocklistDhcp => migrate_event_with_country_code::< + BlocklistDhcpFieldsV0_43, + BlocklistDhcpFields, + >(value, locator)?, + EventKind::BlocklistDns => migrate_event_with_country_code::< + BlocklistDnsFieldsV0_43, + BlocklistDnsFields, + >(value, locator)?, + EventKind::BlocklistKerberos => migrate_event_with_country_code::< BlocklistKerberosFieldsV0_43, BlocklistKerberosFields, >(value, locator)?, - EventKind::BlocklistMalformedDns => migrate_fields::< + EventKind::BlocklistMalformedDns => migrate_event_with_country_code::< BlocklistMalformedDnsFieldsV0_43, BlocklistMalformedDnsFields, >(value, locator)?, - EventKind::BlocklistMqtt => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistNfs => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistNtlm => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistRadius => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistRdp => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistSmb => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistSmtp => { - migrate_fields::(value, locator)? - } - EventKind::BlocklistSsh => { - migrate_fields::(value, locator)? - } + EventKind::BlocklistMqtt => migrate_event_with_country_code::< + BlocklistMqttFieldsV0_43, + BlocklistMqttFields, + >(value, locator)?, + EventKind::BlocklistNfs => migrate_event_with_country_code::< + BlocklistNfsFieldsV0_43, + BlocklistNfsFields, + >(value, locator)?, + EventKind::BlocklistNtlm => migrate_event_with_country_code::< + BlocklistNtlmFieldsV0_43, + BlocklistNtlmFields, + >(value, locator)?, + EventKind::BlocklistRadius => migrate_event_with_country_code::< + BlocklistRadiusFieldsV0_43, + BlocklistRadiusFields, + >(value, locator)?, + EventKind::BlocklistRdp => migrate_event_with_country_code::< + BlocklistRdpFieldsV0_43, + BlocklistRdpFields, + >(value, locator)?, + EventKind::BlocklistSmb => migrate_event_with_country_code::< + BlocklistSmbFieldsV0_43, + BlocklistSmbFields, + >(value, locator)?, + EventKind::BlocklistSmtp => migrate_event_with_country_code::< + BlocklistSmtpFieldsV0_43, + BlocklistSmtpFields, + >(value, locator)?, + EventKind::BlocklistSsh => migrate_event_with_country_code::< + BlocklistSshFieldsV0_43, + BlocklistSshFields, + >(value, locator)?, EventKind::BlocklistTls | EventKind::SuspiciousTlsTraffic => { - migrate_fields::(value, locator)? + migrate_event_with_country_code::( + value, locator, + )? } - EventKind::UnusualDestinationPattern => migrate_fields::< + EventKind::UnusualDestinationPattern => migrate_event_with_country_code::< UnusualDestinationPatternFieldsV0_43, UnusualDestinationPatternFields, >(value, locator)?, - EventKind::NetworkThreat => { - migrate_fields::(value, locator)? - } + EventKind::NetworkThreat => migrate_event_with_country_code::< + NetworkThreatV0_43, + NetworkThreat, + >(value, locator)?, // These event types don't have country code fields or use different structures EventKind::WindowsThreat | EventKind::ExtraThreat => { // Skip migration for these types - they don't have the standard @@ -1027,9 +1061,12 @@ fn migrate_event_country_codes( } }; - // Update the event with migrated fields using raw_update + // Update the event with migrated fields events - .raw_update(key, value, &new_fields) + .update( + (key.as_slice(), value.as_slice()), + (key.as_slice(), new_fields.as_slice()), + ) .context("failed to update migrated event")?; migrated_count += 1; } @@ -1057,6 +1094,71 @@ fn lookup_country_code(locator: &ip2location::DB, addr: IpAddr) -> [u8; 2] { crate::util::country_code_to_bytes(&crate::util::find_ip_country(locator, addr)) } +fn lookup_country_codes(locator: &ip2location::DB, addrs: I) -> Vec<[u8; 2]> +where + I: IntoIterator, +{ + addrs + .into_iter() + .map(|addr| lookup_country_code(locator, addr)) + .collect() +} + +macro_rules! impl_resolve_country_codes { + ( + $ty:ty, + orig: single ($orig_addr:ident => $orig_cc:ident), + resp: single ($resp_addr:ident => $resp_cc:ident) + $(,)? + ) => { + impl ResolveCountryCodes for $ty { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.$orig_cc = lookup_country_code(locator, self.$orig_addr); + self.$resp_cc = lookup_country_code(locator, self.$resp_addr); + } + } + }; + ( + $ty:ty, + orig: single ($orig_addr:ident => $orig_cc:ident), + resp: multi ($resp_addrs:ident => $resp_ccs:ident) + $(,)? + ) => { + impl ResolveCountryCodes for $ty { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.$orig_cc = lookup_country_code(locator, self.$orig_addr); + self.$resp_ccs = lookup_country_codes(locator, self.$resp_addrs.iter().copied()); + } + } + }; + ( + $ty:ty, + orig: multi ($orig_addrs:ident => $orig_ccs:ident), + resp: single ($resp_addr:ident => $resp_cc:ident) + $(,)? + ) => { + impl ResolveCountryCodes for $ty { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.$orig_ccs = lookup_country_codes(locator, self.$orig_addrs.iter().copied()); + self.$resp_cc = lookup_country_code(locator, self.$resp_addr); + } + } + }; + ( + $ty:ty, + orig: multi ($orig_addrs:ident => $orig_ccs:ident), + resp: multi ($resp_addrs:ident => $resp_ccs:ident) + $(,)? + ) => { + impl ResolveCountryCodes for $ty { + fn resolve_country_codes(&mut self, locator: &ip2location::DB) { + self.$orig_ccs = lookup_country_codes(locator, self.$orig_addrs.iter().copied()); + self.$resp_ccs = lookup_country_codes(locator, self.$resp_addrs.iter().copied()); + } + } + }; +} + // ============================================================================= // ResolveCountryCodes implementations for event field types // ============================================================================= @@ -1072,227 +1174,161 @@ use crate::event::{ RepeatedHttpSessionsFields, UnusualDestinationPatternFields, }; -impl ResolveCountryCodes for PortScanFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for MultiHostPortScanFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_codes = self - .resp_addrs - .iter() - .map(|addr| lookup_country_code(locator, *addr)) - .collect(); - } -} - -impl ResolveCountryCodes for ExternalDdosFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_codes = self - .orig_addrs - .iter() - .map(|addr| lookup_country_code(locator, *addr)) - .collect(); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistConnFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for DnsEventFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for CryptocurrencyMiningPoolFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistDnsFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for HttpEventFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for RepeatedHttpSessionsFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for HttpThreatFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for DgaFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for RdpBruteForceFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_codes = self - .resp_addrs - .iter() - .map(|addr| lookup_country_code(locator, *addr)) - .collect(); - } -} - -impl ResolveCountryCodes for BlocklistRdpFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for FtpBruteForceFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for FtpEventFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for LdapBruteForceFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for LdapEventFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistSshFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistTlsFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistKerberosFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistSmtpFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistNfsFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistDhcpFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistDceRpcFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistNtlmFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistSmbFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistMqttFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistBootpFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistRadiusFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - -impl ResolveCountryCodes for BlocklistMalformedDnsFields { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} +impl_resolve_country_codes!( + PortScanFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + MultiHostPortScanFields, + orig: single (orig_addr => orig_country_code), + resp: multi (resp_addrs => resp_country_codes), +); +impl_resolve_country_codes!( + ExternalDdosFields, + orig: multi (orig_addrs => orig_country_codes), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistConnFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + DnsEventFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + CryptocurrencyMiningPoolFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistDnsFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + HttpEventFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + RepeatedHttpSessionsFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + HttpThreatFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + DgaFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + RdpBruteForceFields, + orig: single (orig_addr => orig_country_code), + resp: multi (resp_addrs => resp_country_codes), +); +impl_resolve_country_codes!( + BlocklistRdpFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + FtpBruteForceFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + FtpEventFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + LdapBruteForceFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + LdapEventFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistSshFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistTlsFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistKerberosFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistSmtpFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistNfsFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistDhcpFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistDceRpcFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistNtlmFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistSmbFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistMqttFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistBootpFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistRadiusFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + BlocklistMalformedDnsFields, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); +impl_resolve_country_codes!( + NetworkThreat, + orig: single (orig_addr => orig_country_code), + resp: single (resp_addr => resp_country_code), +); impl ResolveCountryCodes for UnusualDestinationPatternFields { fn resolve_country_codes(&mut self, locator: &ip2location::DB) { @@ -1304,32 +1340,24 @@ impl ResolveCountryCodes for UnusualDestinationPatternFields { } } -impl ResolveCountryCodes for NetworkThreat { - fn resolve_country_codes(&mut self, locator: &ip2location::DB) { - self.orig_country_code = lookup_country_code(locator, self.orig_addr); - self.resp_country_code = lookup_country_code(locator, self.resp_addr); - } -} - /// Helper function to migrate event fields from old format to new format -fn migrate_fields(old_data: &[u8], locator: Option<&ip2location::DB>) -> Result> +fn migrate_event_with_country_code( + old_data: &[u8], + locator: Option<&ip2location::DB>, +) -> Result> where O: serde::de::DeserializeOwned, N: serde::Serialize + serde::de::DeserializeOwned + From + ResolveCountryCodes, { // First try to deserialize as the new format (already migrated) - if bincode::DefaultOptions::new() - .deserialize::(old_data) - .is_ok() - { + if bincode::deserialize::(old_data).is_ok() { // Already in new format, no migration needed return Ok(old_data.to_vec()); } // Deserialize as old format and convert - let old_fields: O = bincode::DefaultOptions::new() - .deserialize(old_data) - .context("failed to deserialize old event fields")?; + let old_fields: O = + bincode::deserialize(old_data).context("failed to deserialize old event fields")?; let mut new_fields: N = old_fields.into(); @@ -1338,9 +1366,7 @@ where new_fields.resolve_country_codes(loc); } - bincode::DefaultOptions::new() - .serialize(&new_fields) - .context("failed to serialize new event fields") + bincode::serialize(&new_fields).context("failed to serialize new event fields") } /// Recursively creates `path` if not existed, creates the VERSION file @@ -1401,9 +1427,13 @@ mod tests { use std::io::Write; use std::path::Path; + use chrono::{TimeZone, Utc}; use semver::{Version, VersionReq}; use super::{COMPATIBLE_VERSION_REQ, create_version_file, migrate_data_dir, read_version_file}; + use super::migrate_event_country_codes; + use super::migration_structures::DnsEventFieldsV0_43; + use crate::event::{DnsEventFields, EventKind, EventMessage}; use crate::tables::NETWORK_TAGS; use crate::test::{DbGuard, acquire_db_permit}; use crate::{Indexable, Store}; @@ -2712,4 +2742,65 @@ mod tests { .unwrap(); assert_eq!(id2, 2, "Second available id should fill the gap at 2"); } + + #[test] + fn migrate_event_country_codes_sets_default_country_codes() { + let schema = TestSchema::new(); + let old_fields = DnsEventFieldsV0_43 { + sensor: "collector1".to_string(), + orig_addr: std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST), + orig_port: 10000, + resp_addr: std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 2)), + resp_port: 53, + proto: 17, + start_time: Utc + .with_ymd_and_hms(1970, 1, 1, 0, 1, 1) + .unwrap() + .timestamp_nanos_opt() + .unwrap(), + duration: 0, + orig_pkts: 0, + resp_pkts: 0, + orig_l2_bytes: 0, + resp_l2_bytes: 0, + query: "foo.com".to_string(), + answer: vec!["10.10.10.10".to_string()], + trans_id: 123, + rtt: 1, + qclass: 0, + qtype: 0, + rcode: 0, + aa_flag: false, + tc_flag: false, + rd_flag: false, + ra_flag: true, + ttl: vec![120], + confidence: 0.9, + category: Some(crate::EventCategory::CommandAndControl), + }; + + let event_time = Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(); + let serialized = bincode::serialize(&old_fields).unwrap(); + let message = EventMessage { + time: event_time, + kind: EventKind::DnsCovertChannel, + fields: serialized, + }; + let event_db = schema.store.events(); + event_db.put(&message).unwrap(); + + migrate_event_country_codes(&schema.store, None).unwrap(); + + let event_db = schema.store.events(); + let mut iter = event_db.raw_iter_forward(); + let (_, value) = iter.next().expect("migrated event"); + let migrated: DnsEventFields = bincode::deserialize(&value).unwrap(); + + assert_eq!(migrated.orig_country_code, *b"ZZ"); + assert_eq!(migrated.resp_country_code, *b"ZZ"); + assert!(iter.next().is_none()); + drop(iter); + + let _ = schema.close(); + } } From 97ab83f99baf655247877bac5fd27307a7e857d5 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 11:34:23 -0800 Subject: [PATCH 11/12] Remove unused FtpBruteForceFieldsV0_41 and its From impl Address PR feedback from sophie-cluml: remove the unused From for FtpBruteForceFieldsV0_44 implementation and the FtpBruteForceFieldsV0_41 struct, as migrations from versions earlier than 0.42.0 are no longer supported by the 0.43.0 release and direct migrations from V41 to V44 are not supported. Also fix test compilation errors by adding the missing third argument (None) to migrate_data_dir calls in tests. --- src/event/ftp.rs | 39 +-------------------------------------- src/migration.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 46 deletions(-) diff --git a/src/event/ftp.rs b/src/event/ftp.rs index 11e24223..61a79faf 100644 --- a/src/event/ftp.rs +++ b/src/event/ftp.rs @@ -6,10 +6,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use super::{EventCategory, LearningMethod, MEDIUM, TriageScore, common::Match}; -use crate::{ - event::common::{AttrValue, triage_scores_to_string}, - types::EventCategoryV0_41, -}; +use crate::event::common::{AttrValue, triage_scores_to_string}; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct FtpCommand { @@ -207,40 +204,6 @@ pub struct FtpBruteForceFieldsV0_44 { pub category: Option, } -impl From for FtpBruteForceFieldsV0_44 { - fn from(value: FtpBruteForceFieldsV0_41) -> Self { - Self { - sensor: String::new(), - orig_addr: value.src_addr, - orig_country_code: *b"XX", - resp_addr: value.dst_addr, - resp_port: value.dst_port, - resp_country_code: *b"XX", - proto: value.proto, - user_list: value.user_list, - start_time: value.start_time.timestamp_nanos_opt().unwrap_or_default(), - end_time: value.end_time.timestamp_nanos_opt().unwrap_or_default(), - is_internal: value.is_internal, - confidence: value.confidence, - category: value.category.into(), - } - } -} - -#[derive(Serialize, Deserialize)] -pub(crate) struct FtpBruteForceFieldsV0_41 { - pub sensor: String, - pub src_addr: IpAddr, - pub dst_addr: IpAddr, - pub dst_port: u16, - pub proto: u8, - pub user_list: Vec, - pub start_time: DateTime, - pub end_time: DateTime, - pub is_internal: bool, - pub confidence: f32, - pub category: EventCategoryV0_41, -} #[derive(Serialize, Deserialize)] pub struct FtpBruteForce { pub sensor: String, diff --git a/src/migration.rs b/src/migration.rs index 93642d02..080c3465 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -1461,7 +1461,7 @@ mod tests { write_version(backup_dir.path(), current_version); // This should succeed without calling any migration - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_ok()); // VERSION should remain unchanged @@ -1486,7 +1486,7 @@ mod tests { write_version(data_dir.path(), &data_version.to_string()); write_version(backup_dir.path(), &backup_version.to_string()); - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -1503,7 +1503,7 @@ mod tests { // Don't write any VERSION files - directories are empty - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); // Should succeed (empty dir gets current version) assert!(result.is_ok()); @@ -1530,7 +1530,7 @@ mod tests { // Also need a file in backup to prevent it from being treated as empty write_version(backup_dir.path(), env!("CARGO_PKG_VERSION")); - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -1548,7 +1548,7 @@ mod tests { assert!(!data_dir.exists()); assert!(!backup_dir.exists()); - let result = migrate_data_dir(&data_dir, &backup_dir); + let result = migrate_data_dir(&data_dir, &backup_dir, None); // Should succeed assert!(result.is_ok()); @@ -1572,7 +1572,7 @@ mod tests { write_version(data_dir.path(), "0.30.0"); write_version(backup_dir.path(), "0.30.0"); - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -1662,7 +1662,7 @@ mod tests { write_version(data_dir.path(), &version.to_string()); write_version(backup_dir.path(), &version.to_string()); - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_ok(), "Migration should succeed from {version}"); let data_version = read_version_file(&data_dir.path().join("VERSION")).unwrap(); @@ -1693,7 +1693,7 @@ mod tests { write_version(backup_dir.path(), "0.42.0"); // Run the migration - let result = migrate_data_dir(data_dir.path(), backup_dir.path()); + let result = migrate_data_dir(data_dir.path(), backup_dir.path(), None); assert!(result.is_ok(), "Migration should succeed"); // Verify database opens with the current column families From 83bd5c1e8cdbc64fc831f1be72c8aacbdcb885e2 Mon Sep 17 00:00:00 2001 From: "octoaide[bot]" <204759324+octoaide[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 19:38:49 +0000 Subject: [PATCH 12/12] Merge network and event-country-code migrations --- src/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/migration.rs b/src/migration.rs index 080c3465..1a2ed52c 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -1430,9 +1430,9 @@ mod tests { use chrono::{TimeZone, Utc}; use semver::{Version, VersionReq}; - use super::{COMPATIBLE_VERSION_REQ, create_version_file, migrate_data_dir, read_version_file}; use super::migrate_event_country_codes; use super::migration_structures::DnsEventFieldsV0_43; + use super::{COMPATIBLE_VERSION_REQ, create_version_file, migrate_data_dir, read_version_file}; use crate::event::{DnsEventFields, EventKind, EventMessage}; use crate::tables::NETWORK_TAGS; use crate::test::{DbGuard, acquire_db_permit};