Skip to content

Commit 6fbd9ec

Browse files
Merge pull request #32 from stackroost/dev
feat(cli): add disable-firewall, sync-time, and run-security-check co…
2 parents 4c9af92 + 518d1ff commit 6fbd9ec

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

cmd/disable_firewall.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"github.com/spf13/cobra"
8+
"stackroost/internal"
9+
"stackroost/internal/logger"
10+
"strings"
11+
)
12+
13+
var disableFirewallCmd = &cobra.Command{
14+
Use: "disable-firewall",
15+
Short: "Disable the system firewall (UFW) safely",
16+
Run: func(cmd *cobra.Command, args []string) {
17+
flush, _ := cmd.Flags().GetBool("flush")
18+
19+
logger.Info("Checking firewall status...")
20+
statusOutput := CMDRUN("sudo", "ufw", "status")
21+
22+
if statusOutput == "" || statusOutput == "Status: inactive\n" {
23+
logger.Warn("Firewall is already inactive")
24+
return
25+
}
26+
27+
logger.Info("Disabling firewall (UFW)...")
28+
if err := internal.RunCommand("sudo", "ufw", "disable"); err != nil {
29+
logger.Error(fmt.Sprintf("Failed to disable firewall: %v", err))
30+
os.Exit(1)
31+
}
32+
33+
if flush {
34+
logger.Warn("Flushing all UFW rules...")
35+
if err := internal.RunCommand("sudo", "ufw", "reset"); err != nil {
36+
logger.Error(fmt.Sprintf("Failed to flush firewall rules: %v", err))
37+
os.Exit(1)
38+
}
39+
logger.Success("All firewall rules flushed.")
40+
}
41+
42+
logger.Success("Firewall disabled successfully.")
43+
},
44+
}
45+
46+
func init() {
47+
rootCmd.AddCommand(disableFirewallCmd)
48+
disableFirewallCmd.Flags().Bool("flush", false, "Flush all UFW rules after disabling")
49+
}
50+
51+
func CMDRUN(name string, args ...string) string {
52+
var out strings.Builder
53+
cmd := exec.Command(name, args...)
54+
cmd.Stdout = &out
55+
cmd.Stderr = &out
56+
_ = cmd.Run()
57+
return out.String()
58+
}

cmd/security_check.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package cmd
2+
3+
import (
4+
"os/exec"
5+
"strings"
6+
7+
"github.com/spf13/cobra"
8+
"stackroost/internal/logger"
9+
)
10+
11+
var securityCheckCmd = &cobra.Command{
12+
Use: "run-security-check",
13+
Short: "Run basic security checks on the server",
14+
Run: func(cmd *cobra.Command, args []string) {
15+
logger.Info("Running security checks...")
16+
17+
// SSH service check
18+
out := securityCaptureCommand("systemctl", "is-active", "ssh")
19+
if strings.Contains(out, "active") {
20+
logger.Success("SSH service: Active")
21+
} else {
22+
logger.Warn("SSH service: Inactive or not installed")
23+
}
24+
25+
// Check root login via SSH
26+
sshdConfig := securityCaptureCommand("sudo", "grep", "^PermitRootLogin", "/etc/ssh/sshd_config")
27+
if strings.Contains(sshdConfig, "no") {
28+
logger.Success("SSH root login: Disabled")
29+
} else {
30+
logger.Warn("SSH root login: Possibly enabled (check PermitRootLogin)")
31+
}
32+
33+
// Password authentication
34+
passAuth := securityCaptureCommand("sudo", "grep", "^PasswordAuthentication", "/etc/ssh/sshd_config")
35+
if strings.Contains(passAuth, "no") {
36+
logger.Success("Password authentication: Disabled (good)")
37+
} else {
38+
logger.Warn("Password authentication: Enabled (not recommended)")
39+
}
40+
41+
// Firewall check (UFW)
42+
ufwStatus := securityCaptureCommand("sudo", "ufw", "status")
43+
if strings.Contains(ufwStatus, "Status: active") {
44+
logger.Success("Firewall (UFW): Active")
45+
} else {
46+
logger.Warn("Firewall (UFW): Inactive or not installed")
47+
}
48+
49+
// fail2ban check
50+
fail2banStatus := securityCaptureCommand("systemctl", "is-active", "fail2ban")
51+
if strings.Contains(fail2banStatus, "active") {
52+
logger.Success("Fail2ban: Running")
53+
} else {
54+
logger.Warn("Fail2ban: Not active or not installed")
55+
}
56+
},
57+
}
58+
59+
func init() {
60+
rootCmd.AddCommand(securityCheckCmd)
61+
}
62+
63+
func securityCaptureCommand(name string, args ...string) string {
64+
var out strings.Builder
65+
cmd := exec.Command(name, args...)
66+
cmd.Stdout = &out
67+
cmd.Stderr = &out
68+
_ = cmd.Run()
69+
return out.String()
70+
}

cmd/sync_time.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"github.com/spf13/cobra"
8+
"stackroost/internal"
9+
"stackroost/internal/logger"
10+
"strings"
11+
)
12+
13+
var syncTimeCmd = &cobra.Command{
14+
Use: "sync-time",
15+
Short: "Sync server time with NTP using systemd-timesyncd",
16+
Run: func(cmd *cobra.Command, args []string) {
17+
logger.Info("Enabling NTP time sync...")
18+
if err := internal.RunCommand("sudo", "timedatectl", "set-ntp", "true"); err != nil {
19+
logger.Error(fmt.Sprintf("Failed to enable NTP sync: %v", err))
20+
os.Exit(1)
21+
}
22+
23+
logger.Info("Restarting time sync service...")
24+
if err := internal.RunCommand("sudo", "systemctl", "restart", "systemd-timesyncd"); err != nil {
25+
logger.Error(fmt.Sprintf("Failed to restart timesync service: %v", err))
26+
os.Exit(1)
27+
}
28+
29+
logger.Success("Time synchronization triggered successfully.")
30+
31+
logger.Info("Current time sync status:")
32+
status := TimeCaptureCommand("timedatectl", "status")
33+
fmt.Println(status)
34+
},
35+
}
36+
37+
func init() {
38+
rootCmd.AddCommand(syncTimeCmd)
39+
}
40+
41+
func TimeCaptureCommand(name string, args ...string) string {
42+
var out strings.Builder
43+
cmd := exec.Command(name, args...)
44+
cmd.Stdout = &out
45+
cmd.Stderr = &out
46+
_ = cmd.Run()
47+
return out.String()
48+
}

0 commit comments

Comments
 (0)