diff --git a/cmd/disable_firewall.go b/cmd/disable_firewall.go new file mode 100644 index 0000000..31e9da2 --- /dev/null +++ b/cmd/disable_firewall.go @@ -0,0 +1,58 @@ +package cmd + +import ( + "fmt" + "os" + "os/exec" + "github.com/spf13/cobra" + "stackroost/internal" + "stackroost/internal/logger" + "strings" +) + +var disableFirewallCmd = &cobra.Command{ + Use: "disable-firewall", + Short: "Disable the system firewall (UFW) safely", + Run: func(cmd *cobra.Command, args []string) { + flush, _ := cmd.Flags().GetBool("flush") + + logger.Info("Checking firewall status...") + statusOutput := CMDRUN("sudo", "ufw", "status") + + if statusOutput == "" || statusOutput == "Status: inactive\n" { + logger.Warn("Firewall is already inactive") + return + } + + logger.Info("Disabling firewall (UFW)...") + if err := internal.RunCommand("sudo", "ufw", "disable"); err != nil { + logger.Error(fmt.Sprintf("Failed to disable firewall: %v", err)) + os.Exit(1) + } + + if flush { + logger.Warn("Flushing all UFW rules...") + if err := internal.RunCommand("sudo", "ufw", "reset"); err != nil { + logger.Error(fmt.Sprintf("Failed to flush firewall rules: %v", err)) + os.Exit(1) + } + logger.Success("All firewall rules flushed.") + } + + logger.Success("Firewall disabled successfully.") + }, +} + +func init() { + rootCmd.AddCommand(disableFirewallCmd) + disableFirewallCmd.Flags().Bool("flush", false, "Flush all UFW rules after disabling") +} + +func CMDRUN(name string, args ...string) string { + var out strings.Builder + cmd := exec.Command(name, args...) + cmd.Stdout = &out + cmd.Stderr = &out + _ = cmd.Run() + return out.String() +} \ No newline at end of file diff --git a/cmd/security_check.go b/cmd/security_check.go new file mode 100644 index 0000000..5c5c1e0 --- /dev/null +++ b/cmd/security_check.go @@ -0,0 +1,70 @@ +package cmd + +import ( + "os/exec" + "strings" + + "github.com/spf13/cobra" + "stackroost/internal/logger" +) + +var securityCheckCmd = &cobra.Command{ + Use: "run-security-check", + Short: "Run basic security checks on the server", + Run: func(cmd *cobra.Command, args []string) { + logger.Info("Running security checks...") + + // SSH service check + out := securityCaptureCommand("systemctl", "is-active", "ssh") + if strings.Contains(out, "active") { + logger.Success("SSH service: Active") + } else { + logger.Warn("SSH service: Inactive or not installed") + } + + // Check root login via SSH + sshdConfig := securityCaptureCommand("sudo", "grep", "^PermitRootLogin", "/etc/ssh/sshd_config") + if strings.Contains(sshdConfig, "no") { + logger.Success("SSH root login: Disabled") + } else { + logger.Warn("SSH root login: Possibly enabled (check PermitRootLogin)") + } + + // Password authentication + passAuth := securityCaptureCommand("sudo", "grep", "^PasswordAuthentication", "/etc/ssh/sshd_config") + if strings.Contains(passAuth, "no") { + logger.Success("Password authentication: Disabled (good)") + } else { + logger.Warn("Password authentication: Enabled (not recommended)") + } + + // Firewall check (UFW) + ufwStatus := securityCaptureCommand("sudo", "ufw", "status") + if strings.Contains(ufwStatus, "Status: active") { + logger.Success("Firewall (UFW): Active") + } else { + logger.Warn("Firewall (UFW): Inactive or not installed") + } + + // fail2ban check + fail2banStatus := securityCaptureCommand("systemctl", "is-active", "fail2ban") + if strings.Contains(fail2banStatus, "active") { + logger.Success("Fail2ban: Running") + } else { + logger.Warn("Fail2ban: Not active or not installed") + } + }, +} + +func init() { + rootCmd.AddCommand(securityCheckCmd) +} + +func securityCaptureCommand(name string, args ...string) string { + var out strings.Builder + cmd := exec.Command(name, args...) + cmd.Stdout = &out + cmd.Stderr = &out + _ = cmd.Run() + return out.String() +} \ No newline at end of file diff --git a/cmd/sync_time.go b/cmd/sync_time.go new file mode 100644 index 0000000..c8eae85 --- /dev/null +++ b/cmd/sync_time.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "fmt" + "os" + "os/exec" + "github.com/spf13/cobra" + "stackroost/internal" + "stackroost/internal/logger" + "strings" +) + +var syncTimeCmd = &cobra.Command{ + Use: "sync-time", + Short: "Sync server time with NTP using systemd-timesyncd", + Run: func(cmd *cobra.Command, args []string) { + logger.Info("Enabling NTP time sync...") + if err := internal.RunCommand("sudo", "timedatectl", "set-ntp", "true"); err != nil { + logger.Error(fmt.Sprintf("Failed to enable NTP sync: %v", err)) + os.Exit(1) + } + + logger.Info("Restarting time sync service...") + if err := internal.RunCommand("sudo", "systemctl", "restart", "systemd-timesyncd"); err != nil { + logger.Error(fmt.Sprintf("Failed to restart timesync service: %v", err)) + os.Exit(1) + } + + logger.Success("Time synchronization triggered successfully.") + + logger.Info("Current time sync status:") + status := TimeCaptureCommand("timedatectl", "status") + fmt.Println(status) + }, +} + +func init() { + rootCmd.AddCommand(syncTimeCmd) +} + +func TimeCaptureCommand(name string, args ...string) string { + var out strings.Builder + cmd := exec.Command(name, args...) + cmd.Stdout = &out + cmd.Stderr = &out + _ = cmd.Run() + return out.String() +} \ No newline at end of file