mirror of
https://github.com/DaLaw2/NetGuardia.git
synced 2026-08-24 14:10:28 +09:00
chore: Merge from ParrotXray master (#1)
* refactor: Use unsafe blocks for flow statistics updates in ingress and egress EBPF fix: Ensure proper error handling in parsing and access control functions * Add detection and statistics pages with navigation updates - Created detection.html and statistics.html with a consistent layout. - Implemented a sidebar navigation menu with links to Home, Dashboard, Statistics, Access Control, and Detection. - Added loading spinner to enhance user experience during data fetching. - Included favicon.ico for branding purposes. * refactor: Remove commented-out code for load average and CPU temperature in SystemHealth * refactor: Enhance system health metrics collection with configured network stats * refactor: Enhance SystemHealth structure with CPU details and uptime metrics * refactor: Remove commented-out code for ingress interface in SystemHealth * refactor: Update SystemHealthMetrics to include system information and adjust CPU usage calculation * add: Add new webpack and CSS files for improved styling and functionality * refactor: Update health API endpoint paths for consistency * update: dashbrad * update: Update dashbroad --------- Co-authored-by: ParrotXray <41143154@nfu.edu.tw>
This commit is contained in:
parent
3751a9c491
commit
f021c8ebe2
162
Cargo.lock
generated
162
Cargo.lock
generated
@ -610,12 +610,6 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
@ -643,25 +637,6 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
@ -1084,9 +1059,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
@ -1293,6 +1268,25 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
@ -1456,26 +1450,6 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.8"
|
||||
@ -1787,15 +1761,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.33.1"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01"
|
||||
checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"windows",
|
||||
]
|
||||
|
||||
@ -2154,31 +2128,55 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core",
|
||||
"windows-future",
|
||||
"windows-link",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-targets",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2187,9 +2185,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
version = "0.59.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2197,12 +2195,37 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2239,6 +2262,15 @@ dependencies = [
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[Config]
|
||||
ingress_ifindex = "enp1s0f0" # nic name
|
||||
egress_ifindex = "enp1s0f1" # nic name
|
||||
management_ifindex = "wlan0" # nic name
|
||||
ingress_ifindex = "enp6s18" # nic name
|
||||
egress_ifindex = "enp6s19" # nic name
|
||||
management_ifindex = "enp6s19" # nic name
|
||||
alert_path = "/tmp/alert"
|
||||
http_server_bind_port = 8080 # port
|
||||
refresh_interval = 1 # seconds
|
||||
|
||||
@ -78,13 +78,15 @@ unsafe fn ipv4_update_flow_stats(
|
||||
event: &IPv4Event,
|
||||
now: u64,
|
||||
) {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
unsafe {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,12 +97,14 @@ unsafe fn ipv6_update_flow_status(
|
||||
event: &IPv6Event,
|
||||
now: u64,
|
||||
) {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
unsafe {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,16 +26,18 @@ pub fn net_guardia(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn parsing(ctx: XdpContext) -> Result<u32, ()> {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let event = parsing::parse_packet(start, end)?;
|
||||
let ptr = PARSED_PACKET.get_ptr_mut(0).ok_or(())?;
|
||||
let parsed_packet = ptr.as_mut().ok_or(())?;
|
||||
*parsed_packet = event;
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 0).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
unsafe {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let event = parsing::parse_packet(start, end)?;
|
||||
let ptr = PARSED_PACKET.get_ptr_mut(0).ok_or(())?;
|
||||
let parsed_packet = ptr.as_mut().ok_or(())?;
|
||||
*parsed_packet = event;
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 0).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[xdp]
|
||||
@ -47,22 +49,25 @@ pub fn statistics(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn try_statistics(_: XdpContext) -> Result<u32, ()> {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
statistics::ipv4_update_stats(&event);
|
||||
unsafe {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
statistics::ipv4_update_stats(&event);
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
statistics::ipv6_update_stats(&event);
|
||||
}
|
||||
_ => Err(())?,
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
statistics::ipv6_update_stats(&event);
|
||||
}
|
||||
_ => Err(())?,
|
||||
Ok(xdp_action::XDP_PASS)
|
||||
}
|
||||
Ok(xdp_action::XDP_PASS)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
|
||||
@ -78,13 +78,15 @@ unsafe fn ipv4_update_flow_stats(
|
||||
event: &IPv4Event,
|
||||
now: u64,
|
||||
) {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
unsafe {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,12 +97,14 @@ unsafe fn ipv6_update_flow_status(
|
||||
event: &IPv6Event,
|
||||
now: u64,
|
||||
) {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
unsafe {
|
||||
if let Some(status) = map.get_ptr_mut(key) {
|
||||
(*status)[0] += event.len as u64;
|
||||
(*status)[1] += 1;
|
||||
(*status)[2] = now;
|
||||
} else {
|
||||
let new_stats = [event.len as u64, 1, now];
|
||||
let _ = map.insert(key, &new_stats, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,16 +26,18 @@ pub fn net_guardia(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn parsing(ctx: XdpContext) -> Result<u32, ()> {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let event = parsing::parse_packet(start, end)?;
|
||||
let ptr = PARSED_PACKET.get_ptr_mut(0).ok_or(())?;
|
||||
let parsed_packet = ptr.as_mut().ok_or(())?;
|
||||
*parsed_packet = event;
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 0).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
unsafe {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let event = parsing::parse_packet(start, end)?;
|
||||
let ptr = PARSED_PACKET.get_ptr_mut(0).ok_or(())?;
|
||||
let parsed_packet = ptr.as_mut().ok_or(())?;
|
||||
*parsed_packet = event;
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 0).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[xdp]
|
||||
@ -47,33 +49,35 @@ pub fn access_control(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn try_access_control(ctx: XdpContext) -> Result<u32, ()> {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
if access_control::ipv4_is_whitelisted(&event) {
|
||||
return Ok(xdp_action::XDP_PASS);
|
||||
unsafe {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
if access_control::ipv4_is_whitelisted(&event) {
|
||||
return Ok(xdp_action::XDP_PASS);
|
||||
}
|
||||
if access_control::ipv4_is_blacklisted(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
}
|
||||
if access_control::ipv4_is_blacklisted(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
if access_control::ipv6_is_whitelisted(&event) {
|
||||
return Ok(xdp_action::XDP_PASS);
|
||||
}
|
||||
if access_control::ipv6_is_blacklisted(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
}
|
||||
_ => Err(())?,
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
if access_control::ipv6_is_whitelisted(&event) {
|
||||
return Ok(xdp_action::XDP_PASS);
|
||||
}
|
||||
if access_control::ipv6_is_blacklisted(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 1).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
_ => Err(())?,
|
||||
Err(())
|
||||
}
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 1).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[xdp]
|
||||
@ -85,29 +89,31 @@ pub fn service(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn try_service(ctx: XdpContext) -> Result<u32, ()> {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
if service::ipv4_service_rule_violation(start, end, &event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
unsafe {
|
||||
let start = ctx.data();
|
||||
let end = ctx.data_end();
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
if service::ipv4_service_rule_violation(start, end, &event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
}
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
if service::ipv6_service_rule_violation(start, end, &event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
if service::ipv6_service_rule_violation(start, end, &event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
}
|
||||
_ => Err(())?,
|
||||
}
|
||||
_ => Err(())?,
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 3).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 3).is_err() {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
// #[xdp]
|
||||
@ -151,7 +157,7 @@ pub fn sampling(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn try_sampling(ctx: XdpContext) -> Result<u32, ()> {
|
||||
if PROGRAM_ARRAY.tail_call(&ctx, 4).is_err() {
|
||||
if unsafe { PROGRAM_ARRAY.tail_call(&ctx, 4).is_err() } {
|
||||
error!(&ctx, "Tail call failed");
|
||||
}
|
||||
Err(())
|
||||
@ -166,22 +172,25 @@ pub fn statistics(ctx: XdpContext) -> u32 {
|
||||
}
|
||||
|
||||
unsafe fn try_statistics(_: XdpContext) -> Result<u32, ()> {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
statistics::ipv4_update_stats(&event);
|
||||
unsafe {
|
||||
let ptr = PARSED_PACKET.get_ptr(0).ok_or(())?;
|
||||
let parsed_packet = ptr.read();
|
||||
match parsed_packet.eth_type {
|
||||
EtherType::Ipv4 => {
|
||||
let event = parsed_packet.into_ipv4_event();
|
||||
statistics::ipv4_update_stats(&event);
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
statistics::ipv6_update_stats(&event);
|
||||
}
|
||||
_ => Err(())?,
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
let event = parsed_packet.into_ipv6_event();
|
||||
statistics::ipv6_update_stats(&event);
|
||||
}
|
||||
_ => Err(())?,
|
||||
Ok(xdp_action::XDP_PASS)
|
||||
}
|
||||
Ok(xdp_action::XDP_PASS)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
|
||||
@ -24,7 +24,7 @@ actix = "0.13.5"
|
||||
mime_guess = "2.0.5"
|
||||
actix-web-actors = "4.3.0"
|
||||
serde_json = "1.0.133"
|
||||
sysinfo = "0.33.0"
|
||||
sysinfo = "0.36.1"
|
||||
|
||||
[build-dependencies]
|
||||
cargo_metadata = { workspace = true }
|
||||
|
||||
423
net-guardia/src/core/health.rs
Normal file
423
net-guardia/src/core/health.rs
Normal file
@ -0,0 +1,423 @@
|
||||
use crate::core::config_manager::ConfigManager;
|
||||
use serde::Serialize;
|
||||
// use std::collections::HashMap;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use sysinfo::{Components, Networks, System};
|
||||
use tokio::sync::{broadcast, mpsc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use tokio::time::interval;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
static SYSTEM_HEALTH_INSTANCE: OnceLock<RwLock<SystemHealth>> = OnceLock::new();
|
||||
|
||||
pub struct SystemHealth {
|
||||
system: System,
|
||||
networks: Networks,
|
||||
components: Components,
|
||||
broadcast_tx: broadcast::Sender<SystemHealthMetrics>,
|
||||
shutdown_tx: mpsc::UnboundedSender<()>,
|
||||
ingress_interface: String,
|
||||
egress_interface: String,
|
||||
management_interface: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SystemHealthMetrics {
|
||||
pub timestamp: u64,
|
||||
pub boot_time: u64,
|
||||
pub uptime_seconds: u64,
|
||||
pub system_info: SystemInfo,
|
||||
pub cpu_details: CpuDetails,
|
||||
pub memory_usage: MemoryUsage,
|
||||
pub network_stats: ConfiguredNetworkStats,
|
||||
pub load_average: Option<LoadAverage>,
|
||||
pub temperature: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SystemInfo {
|
||||
pub kernel_version: Option<String>,
|
||||
pub os_name: Option<String>,
|
||||
pub os_version: Option<String>,
|
||||
pub architecture: String,
|
||||
pub total_processes: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct CpuDetails {
|
||||
pub cpu_brand: String,
|
||||
pub core_count: usize,
|
||||
pub cpu_usage: f32,
|
||||
pub cpu_frequency: u64,
|
||||
pub cores: Vec<CpuCoreInfo>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct CpuCoreInfo {
|
||||
pub core_id: usize,
|
||||
pub usage_percent: f32,
|
||||
pub frequency: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct MemoryUsage {
|
||||
pub total: u64,
|
||||
pub used: u64,
|
||||
pub available: u64,
|
||||
pub usage_percent: f32,
|
||||
pub swap_total: u64,
|
||||
pub swap_used: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct ConfiguredNetworkStats {
|
||||
pub ingress: Option<NetworkStats>,
|
||||
pub egress: Option<NetworkStats>,
|
||||
pub management: Option<NetworkStats>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct NetworkStats {
|
||||
pub interface: String,
|
||||
pub bytes_received: u64,
|
||||
pub bytes_transmitted: u64,
|
||||
pub packets_received: u64,
|
||||
pub packets_transmitted: u64,
|
||||
pub errors_received: u64,
|
||||
pub errors_transmitted: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct LoadAverage {
|
||||
pub one_minute: f64,
|
||||
pub five_minute: f64,
|
||||
pub fifteen_minute: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SystemHealthStatus {
|
||||
pub overall_healthy: bool,
|
||||
pub issues: Vec<String>,
|
||||
pub warnings: Vec<String>,
|
||||
}
|
||||
|
||||
impl SystemHealth {
|
||||
pub async fn initialize(monitoring_interval: Duration) {
|
||||
let (broadcast_tx, _) = broadcast::channel(100);
|
||||
let (shutdown_tx, shutdown_rx) = mpsc::unbounded_channel();
|
||||
|
||||
let config = ConfigManager::now().await;
|
||||
|
||||
let system_health = SystemHealth {
|
||||
system: System::new_all(),
|
||||
networks: Networks::new_with_refreshed_list(),
|
||||
components: Components::new_with_refreshed_list(),
|
||||
broadcast_tx: broadcast_tx.clone(),
|
||||
shutdown_tx,
|
||||
ingress_interface: config.ingress_ifindex.clone(),
|
||||
egress_interface: config.egress_ifindex.clone(),
|
||||
management_interface: config.management_ifindex.clone(),
|
||||
};
|
||||
|
||||
SYSTEM_HEALTH_INSTANCE.get_or_init(|| RwLock::new(system_health));
|
||||
|
||||
let ingress_interface = config.ingress_ifindex;
|
||||
let egress_interface = config.egress_ifindex;
|
||||
let management_interface = config.management_ifindex;
|
||||
|
||||
tokio::spawn(async move {
|
||||
Self::monitoring_loop(
|
||||
broadcast_tx,
|
||||
shutdown_rx,
|
||||
monitoring_interval,
|
||||
ingress_interface,
|
||||
egress_interface,
|
||||
management_interface,
|
||||
).await;
|
||||
});
|
||||
|
||||
info!("System health monitoring initialized with configured interfaces");
|
||||
}
|
||||
|
||||
async fn monitoring_loop(
|
||||
broadcast_tx: broadcast::Sender<SystemHealthMetrics>,
|
||||
mut shutdown_rx: mpsc::UnboundedReceiver<()>,
|
||||
monitoring_interval: Duration,
|
||||
ingress_interface: String,
|
||||
egress_interface: String,
|
||||
management_interface: String,
|
||||
) {
|
||||
let mut system = System::new_all();
|
||||
let mut networks = Networks::new_with_refreshed_list();
|
||||
let mut components = Components::new_with_refreshed_list();
|
||||
let mut interval_timer = interval(monitoring_interval);
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = shutdown_rx.recv() => {
|
||||
info!("System health monitoring shutdown requested");
|
||||
break;
|
||||
}
|
||||
_ = interval_timer.tick() => {
|
||||
system.refresh_all();
|
||||
networks.refresh(true);
|
||||
components.refresh(true);
|
||||
|
||||
let metrics = Self::collect_metrics(
|
||||
&system,
|
||||
&networks,
|
||||
&components,
|
||||
&ingress_interface,
|
||||
&egress_interface,
|
||||
&management_interface,
|
||||
);
|
||||
|
||||
if broadcast_tx.receiver_count() > 0 {
|
||||
if let Err(e) = broadcast_tx.send(metrics) {
|
||||
error!("Failed to broadcast system health metrics: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("System health monitoring stopped");
|
||||
}
|
||||
|
||||
pub async fn instance() -> RwLockReadGuard<'static, SystemHealth> {
|
||||
let instance = SYSTEM_HEALTH_INSTANCE.get().unwrap();
|
||||
instance.read().await
|
||||
}
|
||||
|
||||
pub async fn instance_mut() -> RwLockWriteGuard<'static, SystemHealth> {
|
||||
let instance = SYSTEM_HEALTH_INSTANCE.get().unwrap();
|
||||
instance.write().await
|
||||
}
|
||||
|
||||
fn collect_metrics(
|
||||
system: &System,
|
||||
networks: &Networks,
|
||||
components: &Components,
|
||||
ingress_interface: &str,
|
||||
egress_interface: &str,
|
||||
management_interface: &str,
|
||||
) -> SystemHealthMetrics {
|
||||
let timestamp = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
|
||||
let boot_time = System::boot_time();
|
||||
let uptime_seconds = timestamp - boot_time;
|
||||
|
||||
let system_info = Self::collect_system_info(system);
|
||||
|
||||
let cpu_details = Self::collect_cpu_details(system);
|
||||
|
||||
let memory_usage = MemoryUsage {
|
||||
total: system.total_memory(),
|
||||
used: system.used_memory(),
|
||||
available: system.available_memory(),
|
||||
usage_percent: (system.used_memory() as f32 / system.total_memory() as f32) * 100.0,
|
||||
swap_total: system.total_swap(),
|
||||
swap_used: system.used_swap(),
|
||||
};
|
||||
|
||||
let network_stats = Self::collect_configured_network_stats(
|
||||
networks,
|
||||
ingress_interface,
|
||||
egress_interface,
|
||||
management_interface,
|
||||
);
|
||||
|
||||
let load_average = System::load_average();
|
||||
let load_average = if load_average.one != 0.0 || load_average.five != 0.0 || load_average.fifteen != 0.0 {
|
||||
Some(LoadAverage {
|
||||
one_minute: load_average.one,
|
||||
five_minute: load_average.five,
|
||||
fifteen_minute: load_average.fifteen,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let temperature = components
|
||||
.iter()
|
||||
.find(|component| {
|
||||
let label = component.label().to_lowercase();
|
||||
label.contains("cpu") || label.contains("core") || label.contains("processor")
|
||||
})
|
||||
.and_then(|component| component.temperature());
|
||||
|
||||
SystemHealthMetrics {
|
||||
timestamp,
|
||||
boot_time,
|
||||
uptime_seconds,
|
||||
system_info,
|
||||
cpu_details,
|
||||
memory_usage,
|
||||
network_stats,
|
||||
load_average,
|
||||
temperature,
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_system_info(system: &System) -> SystemInfo {
|
||||
SystemInfo {
|
||||
kernel_version: System::kernel_version(),
|
||||
os_name: System::name(),
|
||||
os_version: System::os_version(),
|
||||
architecture: std::env::consts::ARCH.to_string(),
|
||||
total_processes: system.processes().len(),
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_cpu_details(system: &System) -> CpuDetails {
|
||||
let cpus = system.cpus();
|
||||
|
||||
let cpu_usage = cpus.iter().map(|cpu| cpu.cpu_usage()).sum::<f32>()
|
||||
/ cpus.len() as f32;
|
||||
|
||||
let cores: Vec<CpuCoreInfo> = cpus
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, cpu)| CpuCoreInfo {
|
||||
core_id: index,
|
||||
usage_percent: cpu.cpu_usage(),
|
||||
frequency: cpu.frequency(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cpu_brand = cpus
|
||||
.first()
|
||||
.map(|cpu| cpu.brand().to_string())
|
||||
.unwrap_or_else(|| "Unknown".to_string());
|
||||
|
||||
let avg_frequency = if !cores.is_empty() {
|
||||
cores.iter().map(|core| core.frequency).sum::<u64>() / cores.len() as u64
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
CpuDetails {
|
||||
cpu_brand,
|
||||
core_count: cores.len(),
|
||||
cpu_usage,
|
||||
cpu_frequency: avg_frequency,
|
||||
cores,
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_configured_network_stats(
|
||||
networks: &Networks,
|
||||
ingress_interface: &str,
|
||||
egress_interface: &str,
|
||||
management_interface: &str,
|
||||
) -> ConfiguredNetworkStats {
|
||||
let create_network_stats = |interface_name: &str| -> Option<NetworkStats> {
|
||||
networks.get(interface_name).map(|network| NetworkStats {
|
||||
interface: interface_name.to_string(),
|
||||
bytes_received: network.total_received(),
|
||||
bytes_transmitted: network.total_transmitted(),
|
||||
packets_received: network.total_packets_received(),
|
||||
packets_transmitted: network.total_packets_transmitted(),
|
||||
errors_received: network.total_errors_on_received(),
|
||||
errors_transmitted: network.total_errors_on_transmitted(),
|
||||
})
|
||||
};
|
||||
|
||||
let ingress = create_network_stats(ingress_interface);
|
||||
let egress = create_network_stats(egress_interface);
|
||||
let management = create_network_stats(management_interface);
|
||||
|
||||
if ingress.is_none() {
|
||||
warn!("Ingress interface '{}' not found", ingress_interface);
|
||||
}
|
||||
if egress.is_none() {
|
||||
warn!("Egress interface '{}' not found", egress_interface);
|
||||
}
|
||||
if management.is_none() {
|
||||
warn!("Management interface '{}' not found", management_interface);
|
||||
}
|
||||
|
||||
ConfiguredNetworkStats {
|
||||
ingress,
|
||||
egress,
|
||||
management,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_current_metrics() -> SystemHealthMetrics {
|
||||
let mut instance = Self::instance_mut().await;
|
||||
instance.system.refresh_all();
|
||||
instance.networks.refresh(true);
|
||||
instance.components.refresh(true);
|
||||
|
||||
Self::collect_metrics(
|
||||
&instance.system,
|
||||
&instance.networks,
|
||||
&instance.components,
|
||||
&instance.ingress_interface,
|
||||
&instance.egress_interface,
|
||||
&instance.management_interface,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn subscribe_to_metrics() -> broadcast::Receiver<SystemHealthMetrics> {
|
||||
let instance = Self::instance().await;
|
||||
instance.broadcast_tx.subscribe()
|
||||
}
|
||||
|
||||
pub async fn shutdown() {
|
||||
if let Ok(instance) = SYSTEM_HEALTH_INSTANCE.get().unwrap().try_read() {
|
||||
let _ = instance.shutdown_tx.send(());
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_system_healthy() -> SystemHealthStatus {
|
||||
let metrics = Self::get_current_metrics().await;
|
||||
|
||||
let mut status = SystemHealthStatus {
|
||||
overall_healthy: true,
|
||||
issues: Vec::new(),
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
|
||||
if metrics.cpu_details.cpu_usage > 90.0 {
|
||||
status.overall_healthy = false;
|
||||
status.issues.push(format!("High CPU usage: {:.1}%", metrics.cpu_details.cpu_usage));
|
||||
} else if metrics.cpu_details.cpu_usage > 75.0 {
|
||||
status.warnings.push(format!("Moderate CPU usage: {:.1}%", metrics.cpu_details.cpu_usage));
|
||||
}
|
||||
|
||||
if metrics.memory_usage.usage_percent > 95.0 {
|
||||
status.overall_healthy = false;
|
||||
status.issues.push(format!("Critical memory usage: {:.1}%", metrics.memory_usage.usage_percent));
|
||||
} else if metrics.memory_usage.usage_percent > 80.0 {
|
||||
status.warnings.push(format!("High memory usage: {:.1}%", metrics.memory_usage.usage_percent));
|
||||
}
|
||||
|
||||
if let Some(temp) = metrics.temperature {
|
||||
if temp > 80.0 {
|
||||
status.overall_healthy = false;
|
||||
status.issues.push(format!("High CPU temperature: {:.1}°C", temp));
|
||||
} else if temp > 70.0 {
|
||||
status.warnings.push(format!("Elevated CPU temperature: {:.1}°C", temp));
|
||||
}
|
||||
}
|
||||
|
||||
if metrics.network_stats.ingress.is_none() {
|
||||
status.overall_healthy = false;
|
||||
status.issues.push("Ingress interface not available".to_string());
|
||||
}
|
||||
if metrics.network_stats.egress.is_none() {
|
||||
status.overall_healthy = false;
|
||||
status.issues.push("Egress interface not available".to_string());
|
||||
}
|
||||
if metrics.network_stats.management.is_none() {
|
||||
status.warnings.push("Management interface not available".to_string());
|
||||
}
|
||||
|
||||
status
|
||||
}
|
||||
}
|
||||
@ -3,3 +3,4 @@ pub mod config_manager;
|
||||
pub mod control;
|
||||
pub mod statistics;
|
||||
pub mod system;
|
||||
pub mod health;
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::core::statistics::Statistics;
|
||||
use crate::utils::log_entry::ebpf::EbpfEntry;
|
||||
use crate::utils::log_entry::system::SystemEntry;
|
||||
use crate::utils::logging::Logging;
|
||||
use crate::web::api::{ai, control, default, misc, statistics};
|
||||
use crate::web::api::{ai, control, default, misc, statistics, health};
|
||||
use actix_web::web::route;
|
||||
use actix_web::{App, HttpServer};
|
||||
use anyhow::Context;
|
||||
@ -16,6 +16,8 @@ use std::sync::OnceLock;
|
||||
use sysinfo::System as SystemInfo;
|
||||
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use tracing::{error, info, warn};
|
||||
use crate::core::health::SystemHealth;
|
||||
use std::time::Duration;
|
||||
|
||||
static SYSTEM: OnceLock<RwLock<System>> = OnceLock::new();
|
||||
|
||||
@ -33,11 +35,16 @@ impl System {
|
||||
pub async fn initialize() -> anyhow::Result<()> {
|
||||
Logging::initialize().await?;
|
||||
info!("{}", SystemEntry::Initializing);
|
||||
|
||||
ConfigManager::initialization().await?;
|
||||
|
||||
SystemHealth::initialize(Duration::from_secs(5)).await;
|
||||
|
||||
System::ebpf_initialize().await?;
|
||||
AI::initialize().await;
|
||||
Statistics::initialize().await?;
|
||||
Control::initialize().await?;
|
||||
|
||||
info!("{}", SystemEntry::InitializeComplete);
|
||||
Ok(())
|
||||
}
|
||||
@ -147,7 +154,9 @@ impl System {
|
||||
|
||||
pub async fn run() -> anyhow::Result<()> {
|
||||
info!("{}", SystemEntry::Online);
|
||||
|
||||
Statistics::run().await;
|
||||
|
||||
let config = ConfigManager::now().await;
|
||||
HttpServer::new(|| {
|
||||
let cors = actix_cors::Cors::default()
|
||||
@ -161,6 +170,7 @@ impl System {
|
||||
.service(statistics::initialize())
|
||||
.service(control::initialize())
|
||||
.service(misc::initialize())
|
||||
.service(health::initialize())
|
||||
.default_service(route().to(default::default_route))
|
||||
})
|
||||
.bind(format!("0.0.0.0:{}", config.http_server_bind_port))?
|
||||
@ -171,8 +181,11 @@ impl System {
|
||||
|
||||
pub async fn terminate() -> anyhow::Result<()> {
|
||||
info!("{}", SystemEntry::Terminating);
|
||||
|
||||
AI::terminate().await;
|
||||
Statistics::terminate().await;
|
||||
SystemHealth::shutdown().await;
|
||||
|
||||
info!("{}", SystemEntry::TerminateComplete);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
34
net-guardia/src/web/api/health.rs
Normal file
34
net-guardia/src/web/api/health.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// src/web/api/system_health.rs
|
||||
use crate::core::health::SystemHealth;
|
||||
use crate::web::utils::health_websocket::SystemHealthWebSocket;
|
||||
use actix_web::{get, web, HttpRequest, HttpResponse, Responder, Scope};
|
||||
use actix_web_actors::ws::start;
|
||||
|
||||
pub fn initialize() -> Scope {
|
||||
web::scope("/health")
|
||||
.service(get_current_metrics)
|
||||
.service(get_health_status)
|
||||
.service(websocket_metrics)
|
||||
}
|
||||
|
||||
#[get("/metrics")]
|
||||
async fn get_current_metrics() -> impl Responder {
|
||||
let metrics = SystemHealth::get_current_metrics().await;
|
||||
HttpResponse::Ok().json(metrics)
|
||||
}
|
||||
|
||||
#[get("/status")]
|
||||
async fn get_health_status() -> impl Responder {
|
||||
let status = SystemHealth::is_system_healthy().await;
|
||||
HttpResponse::Ok().json(status)
|
||||
}
|
||||
|
||||
#[get("/websocket/system_health")]
|
||||
async fn websocket_metrics(req: HttpRequest, stream: web::Payload) -> impl Responder {
|
||||
let broadcast_rx = SystemHealth::subscribe_to_metrics().await;
|
||||
let websocket = SystemHealthWebSocket {
|
||||
handle: None,
|
||||
broadcast_rx,
|
||||
};
|
||||
start(websocket, &req, stream)
|
||||
}
|
||||
@ -3,3 +3,4 @@ pub mod control;
|
||||
pub mod default;
|
||||
pub mod misc;
|
||||
pub mod statistics;
|
||||
pub mod health;
|
||||
|
||||
61
net-guardia/src/web/utils/health_websocket.rs
Normal file
61
net-guardia/src/web/utils/health_websocket.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use crate::core::health::SystemHealthMetrics;
|
||||
use actix::prelude::*;
|
||||
use actix_web_actors::ws;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
pub struct SystemHealthWebSocket {
|
||||
pub handle: Option<SpawnHandle>,
|
||||
pub broadcast_rx: broadcast::Receiver<SystemHealthMetrics>,
|
||||
}
|
||||
|
||||
impl Actor for SystemHealthWebSocket {
|
||||
type Context = ws::WebsocketContext<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
self.handle_metrics(ctx);
|
||||
}
|
||||
|
||||
fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
|
||||
if let Some(handle) = self.handle.take() {
|
||||
ctx.cancel_future(handle);
|
||||
}
|
||||
Running::Stop
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemHealthWebSocket {
|
||||
fn handle_metrics(&mut self, ctx: &mut <Self as Actor>::Context) {
|
||||
let mut rx = self.broadcast_rx.resubscribe();
|
||||
|
||||
let fut = async move {
|
||||
match rx.recv().await {
|
||||
Ok(metrics) => Some(metrics),
|
||||
Err(_) => None,
|
||||
}
|
||||
};
|
||||
|
||||
let handle = ctx.spawn(fut.into_actor(self).map(|result, act, ctx| {
|
||||
if let Some(metrics) = result {
|
||||
if let Ok(json) = serde_json::to_string(&metrics) {
|
||||
ctx.text(json);
|
||||
}
|
||||
act.handle_metrics(ctx);
|
||||
}
|
||||
}));
|
||||
|
||||
self.handle = Some(handle);
|
||||
}
|
||||
}
|
||||
|
||||
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for SystemHealthWebSocket {
|
||||
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
|
||||
match msg {
|
||||
Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
|
||||
Ok(ws::Message::Pong(_)) => (),
|
||||
Ok(ws::Message::Text(text)) => ctx.text(text),
|
||||
Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
|
||||
Ok(ws::Message::Close(reason)) => ctx.close(reason),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod alert_websocket;
|
||||
pub mod flow_websocket;
|
||||
pub mod health_websocket;
|
||||
1
net-guardia/static/web/404.html
Normal file
1
net-guardia/static/web/404.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,9 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[597],{5096:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var i=n(7876),r=n(4232),s=n(7328),a=n.n(s),o=n(6463),l=n(8230),c=n.n(l),d=n(9099),h=n(6848),p=n(1772),u=n(1041);let x=[{href:"/",icon:u.v02,label:"Home"},{href:"/dashboard",icon:u.xiI,label:"Dashboard"},{href:"/statistics",icon:u.$Fj,label:"Statistics"},{href:"/access-control",icon:u.imB,label:"Access Control"},{href:"/detection",icon:u.UBk,label:"Detection"}],m=e=>{let{children:t}=e,n=(0,d.useRouter)(),[s,a]=(0,r.useState)(!1),o=e=>"/"===e?"/"===n.pathname:n.pathname.startsWith(e),l={expanded:{x:0,opacity:1},collapsed:{x:-10,opacity:0}};return(0,i.jsxs)("div",{className:"flex min-h-screen bg-gray-100",children:[(0,i.jsxs)(h.P.aside,{className:"fixed top-0 left-0 h-screen bg-gradient-to-br from-slate-800 to-slate-700 text-white flex flex-col shadow-lg z-50 overflow-hidden",initial:"expanded",animate:s?"collapsed":"expanded",variants:{expanded:{width:"240px"},collapsed:{width:"80px"}},transition:{duration:.3,ease:"easeInOut"},children:[(0,i.jsxs)("div",{className:"flex items-center justify-between p-4 border-b border-white/10 min-h-[70px]",children:[!s&&(0,i.jsx)(c(),{href:"/",className:"no-underline text-inherit",children:(0,i.jsx)(h.P.h1,{className:"text-2xl font-bold text-blue-400 m-0 whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:"NetGuardia"})}),(0,i.jsx)("button",{onClick:()=>{a(!s)},className:"bg-transparent border-none text-white cursor-pointer p-2 rounded-md flex items-center justify-center w-10 h-10 hover:bg-white/10 transition-colors duration-200",children:(0,i.jsx)(p.g,{icon:u.ckx})})]}),(0,i.jsx)("nav",{className:"flex-1 py-4 flex flex-col gap-2",children:x.map(e=>(0,i.jsxs)(c(),{href:e.href,className:"\n flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg\n ".concat(s?"px-2 py-2 justify-center h-12 w-12":"px-4 py-3","\n ").concat(o(e.href)?"bg-blue-600 text-white shadow-lg shadow-blue-600/30":"text-slate-300 hover:bg-white/10 hover:text-white","\n "),children:[(0,i.jsx)("div",{className:"flex items-center justify-center flex-shrink-0 w-6 h-6",children:(0,i.jsx)(p.g,{icon:e.icon,className:"text-lg"})}),!s&&(0,i.jsx)(h.P.span,{className:"font-medium whitespace-nowrap overflow-hidden ml-3",variants:l,initial:"expanded",animate:s?"collapsed":"expanded",transition:{duration:.2},children:e.label})]},e.href))})]}),(0,i.jsx)("div",{className:"flex-1 flex flex-col transition-all duration-300 ".concat(s?"ml-20":"ml-60"),children:(0,i.jsx)("section",{className:"flex-1 p-8",children:(0,i.jsx)("div",{className:"max-w-full mx-auto",children:t})})})]})},f=e=>{let{children:t,title:n="NetGuardia",description:r="NetGuardia"}=e,s="".concat(o.hX,"/logo.png");return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(a(),{children:[(0,i.jsx)("title",{children:n}),(0,i.jsx)("meta",{name:"description",content:r}),(0,i.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),(0,i.jsx)("link",{rel:"icon",href:"/favicon.ico"}),(0,i.jsx)("meta",{property:"og:type",content:"website"}),(0,i.jsx)("meta",{property:"og:title",content:n}),(0,i.jsx)("meta",{property:"og:description",content:r}),(0,i.jsx)("meta",{property:"og:url",content:o.hX}),(0,i.jsx)("meta",{property:"og:image",content:s}),(0,i.jsx)("meta",{property:"og:image:width",content:"200"}),(0,i.jsx)("meta",{property:"og:image:height",content:"200"}),(0,i.jsx)("meta",{property:"og:image:alt",content:"NetGuardia"}),(0,i.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,i.jsx)("meta",{name:"twitter:title",content:n}),(0,i.jsx)("meta",{name:"twitter:description",content:r}),(0,i.jsx)("meta",{name:"twitter:image",content:s})]}),(0,i.jsx)(m,{children:t})]})}},7212:(e,t,n)=>{"use strict";n.d(t,{N:()=>j});var i=n(7876),r=n(4232),s=n(5048),a=n(1200),o=n(181),l=n(3866),c=n(7990),d=n(9751);class h extends r.Component{getSnapshotBeforeUpdate(e){let t=this.props.childRef.current;if(t&&e.isPresent&&!this.props.isPresent){let e=t.offsetParent,n=(0,c.s)(e)&&e.offsetWidth||0,i=this.props.sizeRef.current;i.height=t.offsetHeight||0,i.width=t.offsetWidth||0,i.top=t.offsetTop,i.left=t.offsetLeft,i.right=n-i.width-i.left}return null}componentDidUpdate(){}render(){return this.props.children}}function p({children:e,isPresent:t,anchorX:n,root:s}){let a=(0,r.useId)(),o=(0,r.useRef)(null),l=(0,r.useRef)({width:0,height:0,top:0,left:0,right:0}),{nonce:c}=(0,r.useContext)(d.Q);return(0,r.useInsertionEffect)(()=>{let{width:e,height:i,top:r,left:d,right:h}=l.current;if(t||!o.current||!e||!i)return;let p="left"===n?`left: ${d}`:`right: ${h}`;o.current.dataset.motionPopId=a;let u=document.createElement("style");c&&(u.nonce=c);let x=s??document.head;return x.appendChild(u),u.sheet&&u.sheet.insertRule(`
|
||||
[data-motion-pop-id="${a}"] {
|
||||
position: absolute !important;
|
||||
width: ${e}px !important;
|
||||
height: ${i}px !important;
|
||||
${p}px !important;
|
||||
top: ${r}px !important;
|
||||
}
|
||||
`),()=>{x.contains(u)&&x.removeChild(u)}},[t]),(0,i.jsx)(h,{isPresent:t,childRef:o,sizeRef:l,children:r.cloneElement(e,{ref:o})})}let u=({children:e,initial:t,isPresent:n,onExitComplete:s,custom:o,presenceAffectsLayout:c,mode:d,anchorX:h,root:u})=>{let m=(0,a.M)(x),f=(0,r.useId)(),g=!0,j=(0,r.useMemo)(()=>(g=!1,{id:f,initial:t,isPresent:n,custom:o,onExitComplete:e=>{for(let t of(m.set(e,!0),m.values()))if(!t)return;s&&s()},register:e=>(m.set(e,!1),()=>m.delete(e))}),[n,m,s]);return c&&g&&(j={...j}),(0,r.useMemo)(()=>{m.forEach((e,t)=>m.set(t,!1))},[n]),r.useEffect(()=>{n||m.size||!s||s()},[n]),"popLayout"===d&&(e=(0,i.jsx)(p,{isPresent:n,anchorX:h,root:u,children:e})),(0,i.jsx)(l.t.Provider,{value:j,children:e})};function x(){return new Map}var m=n(3885);let f=e=>e.key||"";function g(e){let t=[];return r.Children.forEach(e,e=>{(0,r.isValidElement)(e)&&t.push(e)}),t}let j=({children:e,custom:t,initial:n=!0,onExitComplete:l,presenceAffectsLayout:c=!0,mode:d="sync",propagate:h=!1,anchorX:p="left",root:x})=>{let[j,w]=(0,m.xQ)(h),b=(0,r.useMemo)(()=>g(e),[e]),y=h&&!j?[]:b.map(f),v=(0,r.useRef)(!0),N=(0,r.useRef)(b),E=(0,a.M)(()=>new Map),[C,P]=(0,r.useState)(b),[k,R]=(0,r.useState)(b);(0,o.E)(()=>{v.current=!1,N.current=b;for(let e=0;e<k.length;e++){let t=f(k[e]);y.includes(t)?E.delete(t):!0!==E.get(t)&&E.set(t,!1)}},[k,y.length,y.join("-")]);let $=[];if(b!==C){let e=[...b];for(let t=0;t<k.length;t++){let n=k[t],i=f(n);y.includes(i)||(e.splice(t,0,n),$.push(n))}return"wait"===d&&$.length&&(e=$),R(g(e)),P(b),null}let{forceRender:M}=(0,r.useContext)(s.L);return(0,i.jsx)(i.Fragment,{children:k.map(e=>{let r=f(e),s=(!h||!!j)&&(b===k||y.includes(r));return(0,i.jsx)(u,{isPresent:s,initial:(!v.current||!!n)&&void 0,custom:t,presenceAffectsLayout:c,mode:d,root:x,onExitComplete:s?void 0:()=>{if(!E.has(r))return;E.set(r,!0);let e=!0;E.forEach(t=>{t||(e=!1)}),e&&(M?.(),R(N.current),h&&w?.(),l&&l())},anchorX:p,children:e},r)})})}},9099:(e,t,n)=>{e.exports=n(8253)}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[731],{2164:(_,n,e)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return e(4100)}])}},_=>{var n=n=>_(_.s=n);_.O(0,[636,593,792],()=>n(2164)),_N_E=_.O()}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(()=>{"use strict";var e={},r={};function t(o){var n=r[o];if(void 0!==n)return n.exports;var i=r[o]={exports:{}},l=!0;try{e[o](i,i.exports,t),l=!1}finally{l&&delete r[o]}return i.exports}t.m=e,(()=>{var e=[];t.O=(r,o,n,i)=>{if(o){i=i||0;for(var l=e.length;l>0&&e[l-1][2]>i;l--)e[l]=e[l-1];e[l]=[o,n,i];return}for(var a=1/0,l=0;l<e.length;l++){for(var[o,n,i]=e[l],u=!0,f=0;f<o.length;f++)(!1&i||a>=i)&&Object.keys(t.O).every(e=>t.O[e](o[f]))?o.splice(f--,1):(u=!1,i<a&&(a=i));if(u){e.splice(l--,1);var s=n();void 0!==s&&(r=s)}}return r}})(),t.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return t.d(r,{a:r}),r},t.d=(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.p="/_next/",(()=>{var e={68:0};t.O.j=r=>0===e[r];var r=(r,o)=>{var n,i,[l,a,u]=o,f=0;if(l.some(r=>0!==e[r])){for(n in a)t.o(a,n)&&(t.m[n]=a[n]);if(u)var s=u(t)}for(r&&r(o);f<l.length;f++)i=l[f],t.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return t.O(s)},o=self.webpackChunk_N_E=self.webpackChunk_N_E||[];o.forEach(r.bind(null,0)),o.push=r.bind(null,o.push.bind(o))})()})();
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
self.__BUILD_MANIFEST=function(s,t,a,e,c,r){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:0,errorRate:1e-4,numBits:0,numHashes:null,bitArray:[]},__routerFilterDynamic:{numItems:t,errorRate:1e-4,numBits:t,numHashes:null,bitArray:[]},"/":[s,"static/chunks/pages/index-20fac084227e433f.js"],"/404":[s,"static/chunks/pages/404-88ca1a114c255c82.js"],"/_error":["static/chunks/pages/_error-41608b100cc61246.js"],"/access-control":[s,c,"static/chunks/pages/access-control-02dfbb4c16554211.js"],"/dashboard":[s,r,"static/chunks/335-efb20d23e9c8fbdc.js","static/chunks/pages/dashboard-79264065de788f0d.js"],"/detection":[s,c,"static/chunks/pages/detection-58f841797f6fb8cf.js"],"/statistics":[s,r,"static/chunks/pages/statistics-2ac73b87bd720929.js"],sortedPages:["/","/404","/_app","/_error","/access-control","/dashboard","/detection","/statistics"]}}("static/chunks/182-f7d7e0bcbc4935b2.js",0,1e-4,null,"static/chunks/597-536a1ec6d7dc1ed9.js","static/chunks/620-cfbe65d7a4660b89.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||
@ -0,0 +1 @@
|
||||
self.__SSG_MANIFEST=new Set,self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB();
|
||||
21
net-guardia/static/web/access-control.html
Normal file
21
net-guardia/static/web/access-control.html
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
21
net-guardia/static/web/dashboard.html
Normal file
21
net-guardia/static/web/dashboard.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width, initial-scale=1" data-next-head=""/><title data-next-head="">NetGuardia</title><meta name="description" content="NetGuardia" data-next-head=""/><link rel="icon" href="/favicon.ico" data-next-head=""/><meta property="og:type" content="website" data-next-head=""/><meta property="og:title" content="NetGuardia" data-next-head=""/><meta property="og:description" content="NetGuardia" data-next-head=""/><meta property="og:url" content="http://140.130.34.65:59182" data-next-head=""/><meta property="og:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><meta property="og:image:width" content="200" data-next-head=""/><meta property="og:image:height" content="200" data-next-head=""/><meta property="og:image:alt" content="NetGuardia" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:title" content="NetGuardia" data-next-head=""/><meta name="twitter:description" content="NetGuardia" data-next-head=""/><meta name="twitter:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><link rel="preload" href="/_next/static/css/d0ec348c2f7ab2b9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d0ec348c2f7ab2b9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8cac0b4b405cede1.js" defer=""></script><script src="/_next/static/chunks/framework-8241368a3aa58199.js" defer=""></script><script src="/_next/static/chunks/main-8b597568282ddf7d.js" defer=""></script><script src="/_next/static/chunks/pages/_app-3847060648a79052.js" defer=""></script><script src="/_next/static/chunks/182-f7d7e0bcbc4935b2.js" defer=""></script><script src="/_next/static/chunks/620-cfbe65d7a4660b89.js" defer=""></script><script src="/_next/static/chunks/335-efb20d23e9c8fbdc.js" defer=""></script><script src="/_next/static/chunks/pages/dashboard-79264065de788f0d.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_buildManifest.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="flex min-h-screen bg-gray-100"><aside class="fixed top-0 left-0 h-screen bg-gradient-to-br from-slate-800 to-slate-700 text-white flex flex-col shadow-lg z-50 overflow-hidden" style="width:240px"><div class="flex items-center justify-between p-4 border-b border-white/10 min-h-[70px]"><a class="no-underline text-inherit" href="/"><h1 class="text-2xl font-bold text-blue-400 m-0 whitespace-nowrap" style="opacity:0">NetGuardia</h1></a><button class="bg-transparent border-none text-white cursor-pointer p-2 rounded-md flex items-center justify-center w-10 h-10 hover:bg-white/10 transition-colors duration-200"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bars" class="svg-inline--fa fa-bars " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"></path></svg></button></div><nav class="flex-1 py-4 flex flex-col gap-2"><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Home</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
bg-blue-600 text-white shadow-lg shadow-blue-600/30
|
||||
" href="/dashboard"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="gauge-high" class="svg-inline--fa fa-gauge-high text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM256 416c35.3 0 64-28.7 64-64c0-17.4-6.9-33.1-18.1-44.6L366 161.7c5.3-12.1-.2-26.3-12.3-31.6s-26.3 .2-31.6 12.3L257.9 288c-.6 0-1.3 0-1.9 0c-35.3 0-64 28.7-64 64s28.7 64 64 64zM176 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM96 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm352-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Dashboard</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/statistics"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-bar" class="svg-inline--fa fa-chart-bar text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 32c17.7 0 32 14.3 32 32l0 336c0 8.8 7.2 16 16 16l400 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L80 480c-44.2 0-80-35.8-80-80L0 64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64l128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96l256 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-256 0c-17.7 0-32-14.3-32-32s14.3-32 32-32z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Statistics</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/access-control"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shield-halved" class="svg-inline--fa fa-shield-halved text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Access Control</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/detection"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="robot" class="svg-inline--fa fa-robot text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M320 0c17.7 0 32 14.3 32 32l0 64 120 0c39.8 0 72 32.2 72 72l0 272c0 39.8-32.2 72-72 72l-304 0c-39.8 0-72-32.2-72-72l0-272c0-39.8 32.2-72 72-72l120 0 0-64c0-17.7 14.3-32 32-32zM208 384c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zM264 256a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm152 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM48 224l16 0 0 192-16 0c-26.5 0-48-21.5-48-48l0-96c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-16 0 0-192 16 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Detection</span></a></nav></aside><div class="flex-1 flex flex-col transition-all duration-300 ml-60"><section class="flex-1 p-8"><div class="max-w-full mx-auto"><div class="flex items-center justify-center w-full h-full min-h-[calc(100vh-4rem)]"><div class="flex flex-col items-center space-y-4"><div class="flex justify-center items-center"><div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div></div></div></div></div></section></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/dashboard","query":{},"buildId":"wASj1qj7ED75Mpwihahbt","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
21
net-guardia/static/web/detection.html
Normal file
21
net-guardia/static/web/detection.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width, initial-scale=1" data-next-head=""/><title data-next-head="">NetGuardia</title><meta name="description" content="NetGuardia" data-next-head=""/><link rel="icon" href="/favicon.ico" data-next-head=""/><meta property="og:type" content="website" data-next-head=""/><meta property="og:title" content="NetGuardia" data-next-head=""/><meta property="og:description" content="NetGuardia" data-next-head=""/><meta property="og:url" content="http://140.130.34.65:59182" data-next-head=""/><meta property="og:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><meta property="og:image:width" content="200" data-next-head=""/><meta property="og:image:height" content="200" data-next-head=""/><meta property="og:image:alt" content="NetGuardia" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:title" content="NetGuardia" data-next-head=""/><meta name="twitter:description" content="NetGuardia" data-next-head=""/><meta name="twitter:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><link rel="preload" href="/_next/static/css/d0ec348c2f7ab2b9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d0ec348c2f7ab2b9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8cac0b4b405cede1.js" defer=""></script><script src="/_next/static/chunks/framework-8241368a3aa58199.js" defer=""></script><script src="/_next/static/chunks/main-8b597568282ddf7d.js" defer=""></script><script src="/_next/static/chunks/pages/_app-3847060648a79052.js" defer=""></script><script src="/_next/static/chunks/182-f7d7e0bcbc4935b2.js" defer=""></script><script src="/_next/static/chunks/597-536a1ec6d7dc1ed9.js" defer=""></script><script src="/_next/static/chunks/pages/detection-58f841797f6fb8cf.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_buildManifest.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="flex min-h-screen bg-gray-100"><aside class="fixed top-0 left-0 h-screen bg-gradient-to-br from-slate-800 to-slate-700 text-white flex flex-col shadow-lg z-50 overflow-hidden" style="width:240px"><div class="flex items-center justify-between p-4 border-b border-white/10 min-h-[70px]"><a class="no-underline text-inherit" href="/"><h1 class="text-2xl font-bold text-blue-400 m-0 whitespace-nowrap" style="opacity:0">NetGuardia</h1></a><button class="bg-transparent border-none text-white cursor-pointer p-2 rounded-md flex items-center justify-center w-10 h-10 hover:bg-white/10 transition-colors duration-200"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bars" class="svg-inline--fa fa-bars " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"></path></svg></button></div><nav class="flex-1 py-4 flex flex-col gap-2"><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Home</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/dashboard"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="gauge-high" class="svg-inline--fa fa-gauge-high text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM256 416c35.3 0 64-28.7 64-64c0-17.4-6.9-33.1-18.1-44.6L366 161.7c5.3-12.1-.2-26.3-12.3-31.6s-26.3 .2-31.6 12.3L257.9 288c-.6 0-1.3 0-1.9 0c-35.3 0-64 28.7-64 64s28.7 64 64 64zM176 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM96 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm352-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Dashboard</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/statistics"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-bar" class="svg-inline--fa fa-chart-bar text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 32c17.7 0 32 14.3 32 32l0 336c0 8.8 7.2 16 16 16l400 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L80 480c-44.2 0-80-35.8-80-80L0 64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64l128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96l256 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-256 0c-17.7 0-32-14.3-32-32s14.3-32 32-32z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Statistics</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/access-control"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shield-halved" class="svg-inline--fa fa-shield-halved text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Access Control</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
bg-blue-600 text-white shadow-lg shadow-blue-600/30
|
||||
" href="/detection"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="robot" class="svg-inline--fa fa-robot text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M320 0c17.7 0 32 14.3 32 32l0 64 120 0c39.8 0 72 32.2 72 72l0 272c0 39.8-32.2 72-72 72l-304 0c-39.8 0-72-32.2-72-72l0-272c0-39.8 32.2-72 72-72l120 0 0-64c0-17.7 14.3-32 32-32zM208 384c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zM264 256a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm152 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM48 224l16 0 0 192-16 0c-26.5 0-48-21.5-48-48l0-96c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-16 0 0-192 16 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Detection</span></a></nav></aside><div class="flex-1 flex flex-col transition-all duration-300 ml-60"><section class="flex-1 p-8"><div class="max-w-full mx-auto"><div class="flex items-center justify-center w-full h-full min-h-[calc(100vh-4rem)]"><div class="flex flex-col items-center space-y-4"><div class="flex justify-center items-center"><div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div></div></div></div></div></section></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/detection","query":{},"buildId":"wASj1qj7ED75Mpwihahbt","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
BIN
net-guardia/static/web/favicon.ico
Normal file
BIN
net-guardia/static/web/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@ -1,14 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/icon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>NetGuardia</title>
|
||||
<script type="module" crossorigin src="/assets/index-BLvNN6v5.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-zHxCX2TQ.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width, initial-scale=1" data-next-head=""/><title data-next-head="">NetGuardia</title><meta name="description" content="NetGuardia" data-next-head=""/><link rel="icon" href="/favicon.ico" data-next-head=""/><meta property="og:type" content="website" data-next-head=""/><meta property="og:title" content="NetGuardia" data-next-head=""/><meta property="og:description" content="NetGuardia" data-next-head=""/><meta property="og:url" content="http://140.130.34.65:59182" data-next-head=""/><meta property="og:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><meta property="og:image:width" content="200" data-next-head=""/><meta property="og:image:height" content="200" data-next-head=""/><meta property="og:image:alt" content="NetGuardia" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:title" content="NetGuardia" data-next-head=""/><meta name="twitter:description" content="NetGuardia" data-next-head=""/><meta name="twitter:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><link rel="preload" href="/_next/static/css/d0ec348c2f7ab2b9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d0ec348c2f7ab2b9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8cac0b4b405cede1.js" defer=""></script><script src="/_next/static/chunks/framework-8241368a3aa58199.js" defer=""></script><script src="/_next/static/chunks/main-8b597568282ddf7d.js" defer=""></script><script src="/_next/static/chunks/pages/_app-3847060648a79052.js" defer=""></script><script src="/_next/static/chunks/182-f7d7e0bcbc4935b2.js" defer=""></script><script src="/_next/static/chunks/pages/index-20fac084227e433f.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_buildManifest.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="flex min-h-screen bg-gray-100"><aside class="fixed top-0 left-0 h-screen bg-gradient-to-br from-slate-800 to-slate-700 text-white flex flex-col shadow-lg z-50 overflow-hidden" style="width:240px"><div class="flex items-center justify-between p-4 border-b border-white/10 min-h-[70px]"><a class="no-underline text-inherit" href="/"><h1 class="text-2xl font-bold text-blue-400 m-0 whitespace-nowrap" style="opacity:0">NetGuardia</h1></a><button class="bg-transparent border-none text-white cursor-pointer p-2 rounded-md flex items-center justify-center w-10 h-10 hover:bg-white/10 transition-colors duration-200"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bars" class="svg-inline--fa fa-bars " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"></path></svg></button></div><nav class="flex-1 py-4 flex flex-col gap-2"><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
bg-blue-600 text-white shadow-lg shadow-blue-600/30
|
||||
" href="/"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Home</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/dashboard"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="gauge-high" class="svg-inline--fa fa-gauge-high text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM256 416c35.3 0 64-28.7 64-64c0-17.4-6.9-33.1-18.1-44.6L366 161.7c5.3-12.1-.2-26.3-12.3-31.6s-26.3 .2-31.6 12.3L257.9 288c-.6 0-1.3 0-1.9 0c-35.3 0-64 28.7-64 64s28.7 64 64 64zM176 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM96 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm352-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Dashboard</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/statistics"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-bar" class="svg-inline--fa fa-chart-bar text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 32c17.7 0 32 14.3 32 32l0 336c0 8.8 7.2 16 16 16l400 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L80 480c-44.2 0-80-35.8-80-80L0 64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64l128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96l256 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-256 0c-17.7 0-32-14.3-32-32s14.3-32 32-32z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Statistics</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/access-control"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shield-halved" class="svg-inline--fa fa-shield-halved text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Access Control</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/detection"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="robot" class="svg-inline--fa fa-robot text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M320 0c17.7 0 32 14.3 32 32l0 64 120 0c39.8 0 72 32.2 72 72l0 272c0 39.8-32.2 72-72 72l-304 0c-39.8 0-72-32.2-72-72l0-272c0-39.8 32.2-72 72-72l120 0 0-64c0-17.7 14.3-32 32-32zM208 384c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zM264 256a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm152 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM48 224l16 0 0 192-16 0c-26.5 0-48-21.5-48-48l0-96c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-16 0 0-192 16 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Detection</span></a></nav></aside><div class="flex-1 flex flex-col transition-all duration-300 ml-60"><section class="flex-1 p-8"><div class="max-w-full mx-auto"><div class="flex items-center justify-center w-full h-full min-h-[calc(100vh-4rem)]"><div class="flex flex-col items-center space-y-4"><div class="flex justify-center items-center"><div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div></div></div></div></div></section></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"wASj1qj7ED75Mpwihahbt","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
21
net-guardia/static/web/statistics.html
Normal file
21
net-guardia/static/web/statistics.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width, initial-scale=1" data-next-head=""/><title data-next-head="">NetGuardia</title><meta name="description" content="NetGuardia" data-next-head=""/><link rel="icon" href="/favicon.ico" data-next-head=""/><meta property="og:type" content="website" data-next-head=""/><meta property="og:title" content="NetGuardia" data-next-head=""/><meta property="og:description" content="NetGuardia" data-next-head=""/><meta property="og:url" content="http://140.130.34.65:59182" data-next-head=""/><meta property="og:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><meta property="og:image:width" content="200" data-next-head=""/><meta property="og:image:height" content="200" data-next-head=""/><meta property="og:image:alt" content="NetGuardia" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:title" content="NetGuardia" data-next-head=""/><meta name="twitter:description" content="NetGuardia" data-next-head=""/><meta name="twitter:image" content="http://140.130.34.65:59182/logo.png" data-next-head=""/><link rel="preload" href="/_next/static/css/d0ec348c2f7ab2b9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d0ec348c2f7ab2b9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8cac0b4b405cede1.js" defer=""></script><script src="/_next/static/chunks/framework-8241368a3aa58199.js" defer=""></script><script src="/_next/static/chunks/main-8b597568282ddf7d.js" defer=""></script><script src="/_next/static/chunks/pages/_app-3847060648a79052.js" defer=""></script><script src="/_next/static/chunks/182-f7d7e0bcbc4935b2.js" defer=""></script><script src="/_next/static/chunks/620-cfbe65d7a4660b89.js" defer=""></script><script src="/_next/static/chunks/pages/statistics-2ac73b87bd720929.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_buildManifest.js" defer=""></script><script src="/_next/static/wASj1qj7ED75Mpwihahbt/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="flex min-h-screen bg-gray-100"><aside class="fixed top-0 left-0 h-screen bg-gradient-to-br from-slate-800 to-slate-700 text-white flex flex-col shadow-lg z-50 overflow-hidden" style="width:240px"><div class="flex items-center justify-between p-4 border-b border-white/10 min-h-[70px]"><a class="no-underline text-inherit" href="/"><h1 class="text-2xl font-bold text-blue-400 m-0 whitespace-nowrap" style="opacity:0">NetGuardia</h1></a><button class="bg-transparent border-none text-white cursor-pointer p-2 rounded-md flex items-center justify-center w-10 h-10 hover:bg-white/10 transition-colors duration-200"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bars" class="svg-inline--fa fa-bars " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"></path></svg></button></div><nav class="flex-1 py-4 flex flex-col gap-2"><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Home</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/dashboard"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="gauge-high" class="svg-inline--fa fa-gauge-high text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM256 416c35.3 0 64-28.7 64-64c0-17.4-6.9-33.1-18.1-44.6L366 161.7c5.3-12.1-.2-26.3-12.3-31.6s-26.3 .2-31.6 12.3L257.9 288c-.6 0-1.3 0-1.9 0c-35.3 0-64 28.7-64 64s28.7 64 64 64zM176 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM96 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm352-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Dashboard</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
bg-blue-600 text-white shadow-lg shadow-blue-600/30
|
||||
" href="/statistics"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-bar" class="svg-inline--fa fa-chart-bar text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 32c17.7 0 32 14.3 32 32l0 336c0 8.8 7.2 16 16 16l400 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L80 480c-44.2 0-80-35.8-80-80L0 64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64l128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96l256 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-256 0c-17.7 0-32-14.3-32-32s14.3-32 32-32z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Statistics</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/access-control"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shield-halved" class="svg-inline--fa fa-shield-halved text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8l0 378.1C394 378 431.1 230.1 432 141.4L256 66.8s0 0 0 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Access Control</span></a><a class="
|
||||
flex items-center no-underline transition-all duration-200 relative mx-2 rounded-lg
|
||||
px-4 py-3
|
||||
text-slate-300 hover:bg-white/10 hover:text-white
|
||||
" href="/detection"><div class="flex items-center justify-center flex-shrink-0 w-6 h-6"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="robot" class="svg-inline--fa fa-robot text-lg" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M320 0c17.7 0 32 14.3 32 32l0 64 120 0c39.8 0 72 32.2 72 72l0 272c0 39.8-32.2 72-72 72l-304 0c-39.8 0-72-32.2-72-72l0-272c0-39.8 32.2-72 72-72l120 0 0-64c0-17.7 14.3-32 32-32zM208 384c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0zM264 256a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm152 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM48 224l16 0 0 192-16 0c-26.5 0-48-21.5-48-48l0-96c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-16 0 0-192 16 0z"></path></svg></div><span class="font-medium whitespace-nowrap overflow-hidden ml-3" style="opacity:1;transform:none">Detection</span></a></nav></aside><div class="flex-1 flex flex-col transition-all duration-300 ml-60"><section class="flex-1 p-8"><div class="max-w-full mx-auto"><div class="flex items-center justify-center w-full h-full min-h-[calc(100vh-4rem)]"><div class="flex flex-col items-center space-y-4"><div class="flex justify-center items-center"><div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div></div></div></div></div></section></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/statistics","query":{},"buildId":"wASj1qj7ED75Mpwihahbt","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
Loading…
x
Reference in New Issue
Block a user