From 707b5f3fd2199d6b44c124e07ccfde19d50002dd Mon Sep 17 00:00:00 2001 From: toby Date: Sat, 29 Mar 2025 17:32:10 +0100 Subject: [PATCH 1/3] feat: firewall - support iptables and nftables --- modules/security/firewall.go | 86 +++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/modules/security/firewall.go b/modules/security/firewall.go index 83547fa06..8e0994b7b 100644 --- a/modules/security/firewall.go +++ b/modules/security/firewall.go @@ -1,9 +1,7 @@ package security import ( - "bytes" "os/exec" - "os/user" "runtime" "strings" @@ -42,25 +40,83 @@ func FirewallStealthState() string { /* -------------------- Unexported Functions -------------------- */ -func firewallStateLinux() string { // might be very Ubuntu specific - user, _ := user.Current() - cmd := exec.Command("sudo", "/usr/sbin/ufw", "status") +func firewallStateLinux() string { + // Check UFW first + if hasUfw := checkUfw(); hasUfw != "" { + return hasUfw + } - if strings.Contains(user.Username, "root") { - cmd = exec.Command("ufw", "status") + // Check nftables + if hasNft := checkNftables(); hasNft != "" { + return hasNft } - var o bytes.Buffer - cmd.Stdout = &o - if err := cmd.Run(); err != nil { - return "[red]NA[white]" + // Check iptables as last resort + if hasIpt := checkIptables(); hasIpt != "" { + return hasIpt } - if strings.Contains(o.String(), "inactive") { - return "[red]Disabled[white]" - } else { - return "[green]Enabled[white]" + return "[red]No firewall[white]" +} + +func checkUfw() string { + // First check if UFW is installed + checkInstalled := exec.Command("which", "ufw") + if err := checkInstalled.Run(); err != nil { + return "" + } + + // Then check if service is running + cmd := exec.Command("systemctl", "is-active", "ufw") + out := utils.ExecuteCommand(cmd) + + if strings.Contains(out, "active") { + return "[green]Enabled (ufw)[white]" + } else if out != "" { + return "[red]Disabled (ufw)[white]" + } + return "" +} + +func checkNftables() string { + // First check if nftables is installed + checkInstalled := exec.Command("which", "nft") + if err := checkInstalled.Run(); err != nil { + return "" + } + + // Then check if service is running + cmd := exec.Command("systemctl", "is-active", "nftables") + out := utils.ExecuteCommand(cmd) + if strings.Contains(out, "active") { + return "[green]Enabled (nftables)[white]" + } else if out != "" { + return "[red]Disabled (nftables)[white]" + } + return "" +} + +func checkIptables() string { + // First check if iptables is installed + checkInstalled := exec.Command("which", "iptables") + if strings.Contains(utils.ExecuteCommand(checkInstalled), "not found") { + return "" + } + + // Check if iptables module is loaded + cmd := exec.Command("lsmod") + out := utils.ExecuteCommand(cmd) + + if strings.Contains(out, "ip_tables") { + // Check for any active rules + cmd := exec.Command("iptables", "-L") + out := utils.ExecuteCommand(cmd) + if strings.Contains(out, "Chain") && !strings.Contains(out, "0 references") { + return "[green]Enabled (iptables)[white]" + } + return "[yellow]Unable to check rules (iptables)[white]" } + return "" } func firewallStateMacOS() string { From ff0ab7ec683300240ea4a6486c8599b61e79ec50 Mon Sep 17 00:00:00 2001 From: toby Date: Sat, 29 Mar 2025 17:35:38 +0100 Subject: [PATCH 2/3] chore: clearer iptables message --- modules/security/firewall.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/security/firewall.go b/modules/security/firewall.go index 8e0994b7b..5d947ebc1 100644 --- a/modules/security/firewall.go +++ b/modules/security/firewall.go @@ -114,7 +114,7 @@ func checkIptables() string { if strings.Contains(out, "Chain") && !strings.Contains(out, "0 references") { return "[green]Enabled (iptables)[white]" } - return "[yellow]Unable to check rules (iptables)[white]" + return "[yellow]Loaded but unable to check rules (iptables)[white]" } return "" } From 7a552278456357691a2ed6c0f3561fe183f776c4 Mon Sep 17 00:00:00 2001 From: toby Date: Sun, 30 Mar 2025 17:16:59 +0200 Subject: [PATCH 3/3] fix: make firewall check not language dependant --- modules/security/firewall.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/modules/security/firewall.go b/modules/security/firewall.go index 5d947ebc1..55016fbef 100644 --- a/modules/security/firewall.go +++ b/modules/security/firewall.go @@ -68,14 +68,11 @@ func checkUfw() string { // Then check if service is running cmd := exec.Command("systemctl", "is-active", "ufw") - out := utils.ExecuteCommand(cmd) - - if strings.Contains(out, "active") { + err := cmd.Run() + if err == nil { return "[green]Enabled (ufw)[white]" - } else if out != "" { - return "[red]Disabled (ufw)[white]" } - return "" + return "[red]Disabled (ufw)[white]" } func checkNftables() string { @@ -87,13 +84,11 @@ func checkNftables() string { // Then check if service is running cmd := exec.Command("systemctl", "is-active", "nftables") - out := utils.ExecuteCommand(cmd) - if strings.Contains(out, "active") { + err := cmd.Run() + if err == nil { return "[green]Enabled (nftables)[white]" - } else if out != "" { - return "[red]Disabled (nftables)[white]" } - return "" + return "[red]Disabled (nftables)[white]" } func checkIptables() string {