Skip to main content

judge_ufw

Function judge_ufw 

Source
pub fn judge_ufw(status: &str, plan: &FirewallPlan) -> FirewallObservation
Expand description

Judge ufw status output against the plan. Pure.

A rule is admitted when, for each of its sources (or once, for any source), a line allows its port/proto inbound from that network or from anywhere, to its group when it has one.

use std::net::Ipv4Addr;
use majordomus_cli::mesh::firewall::{judge_ufw, plan, FirewallObservationState};
use majordomus_cli::mesh::MeshConfig;

let config: MeshConfig = serde_json::from_value(serde_json::json!({
    "schema": "mesh/v1", "kind": "mesh-declaration", "id": "doc", "enabled": true,
    "rendezvous": { "endpoints": ["http://192.168.7.10:8791", "http://100.64.1.2:8791"] },
})).unwrap();
let p = plan(Some(&config), &[Ipv4Addr::new(192, 168, 7, 10)], None);

let before = "Status: active\n\nTo                         Action      From\n--                         ------      ----\n22/tcp                     ALLOW IN    Anywhere\n";
let o = judge_ufw(before, &p);
assert_eq!(o.state, FirewallObservationState::Missing);
assert_eq!(o.missing.len(), 2);

let after = "Status: active\n\nTo                         Action      From\n--                         ------      ----\n22/tcp                     ALLOW IN    Anywhere\n239.255.77.77 7741/udp     ALLOW IN    Anywhere                   # majordomus mesh: multicast discovery\n8791/tcp                   ALLOW IN    192.168.7.0/24             # majordomus mesh: rendezvous hub\n8791/tcp                   ALLOW IN    100.64.0.0/10              # majordomus mesh: rendezvous hub\n";
assert_eq!(judge_ufw(after, &p).state, FirewallObservationState::Present);

// `ufw status` without `verbose` prints the action as `ALLOW`; it is the same rule
let terse = "Status: active\n239.255.77.77 7741/udp     ALLOW       Anywhere\n8791/tcp                   ALLOW       192.168.7.0/24\n8791/tcp                   ALLOW       100.64.0.0/10\n";
assert_eq!(judge_ufw(terse, &p).state, FirewallObservationState::Present);

// a wider admission counts: anywhere covers every network
let wide = "Status: active\n239.255.77.77 7741/udp     ALLOW IN    Anywhere\n8791/tcp                   ALLOW IN    Anywhere\n";
assert_eq!(judge_ufw(wide, &p).state, FirewallObservationState::Present);

assert_eq!(judge_ufw("Status: inactive\n", &p).state, FirewallObservationState::Inactive);
assert_eq!(judge_ufw("ERROR: You need to be root to run this script\n", &p).state, FirewallObservationState::Unobservable);