Skip to content

Improve system checks and add configuration support #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,56 @@
- **System Logging and Monitoring:** Ensures logging and monitoring systems are in place to detect unauthorized access or security breaches.
- **File Integrity Monitoring:** Verifies that the server is monitoring critical files for changes.

### Running the Application

To run the Kumo application, follow these steps:

1. **Clone the repository:**
```sh
git clone https://github.com/kintsdev/kumo.git
cd kumo
```

2. **Build the application:**
```sh
make build
```

3. **Run the application:**
```sh
sudo ./kumo
```

Note: The application must be run as root to perform certain system checks.

### Customizing Checks

You can customize the system checks by modifying the `config.json` file. This file contains an array of checks, each with the following fields:

- `Name`: The name of the check.
- `Cmd`: The command to be executed for the check.
- `ErrHint`: A hint message to be displayed if the check fails.

Example `config.json` entry:
```json
{
"Name": "Check Disk Space",
"Cmd": "df -h",
"ErrHint": "Ensure there is enough disk space available."
}
```

### Interpreting Results

The results of the system checks are displayed in the terminal with the following format:

- **Passed Checks:** Displayed with a green checkmark (✔) and the message "Passed".
- **Failed Checks:** Displayed with a red cross (✘) and the message "Failed" along with the error hint and the command output.

Example output:
```
✔ Check Disk Space Passed (df -h)
✘ Check Memory Usage Failed (Ensure there is enough free memory available. (free -m))
```

Press 'q' to quit the application.
77 changes: 77 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
[
{
"Name": "Check Disk Space",
"Cmd": "df -h",
"ErrHint": "Ensure there is enough disk space available."
},
{
"Name": "Check Memory Usage",
"Cmd": "free -m",
"ErrHint": "Ensure there is enough free memory available."
},
{
"Name": "Check CPU Load",
"Cmd": "uptime",
"ErrHint": "Ensure the CPU load is within acceptable limits."
},
{
"Name": "Check Running Processes",
"Cmd": "ps aux",
"ErrHint": "Ensure there are no unauthorized processes running."
},
{
"Name": "Check Firewall Status",
"Cmd": "ufw status",
"ErrHint": "Ensure the firewall is active and configured correctly."
},
{
"Name": "Check Open Ports",
"Cmd": "netstat -tuln",
"ErrHint": "Ensure only necessary ports are open."
},
{
"Name": "Check User Accounts",
"Cmd": "cat /etc/passwd",
"ErrHint": "Ensure there are no unauthorized user accounts."
},
{
"Name": "Check SSH Configuration",
"Cmd": "cat /etc/ssh/sshd_config",
"ErrHint": "Ensure SSH is configured securely."
},
{
"Name": "Check Installed Packages",
"Cmd": "dpkg -l",
"ErrHint": "Ensure only necessary packages are installed."
},
{
"Name": "Check System Logs",
"Cmd": "tail /var/log/syslog",
"ErrHint": "Review system logs for any unusual activity."
},
{
"Name": "Check Network Configuration",
"Cmd": "ifconfig",
"ErrHint": "Ensure network interfaces are configured correctly."
},
{
"Name": "Check System Uptime",
"Cmd": "uptime",
"ErrHint": "Ensure the system has been running without unexpected reboots."
},
{
"Name": "Check Disk Usage",
"Cmd": "du -sh /",
"ErrHint": "Ensure disk usage is within acceptable limits."
},
{
"Name": "Check Kernel Version",
"Cmd": "uname -r",
"ErrHint": "Ensure the system is running a supported kernel version."
},
{
"Name": "Check System Updates",
"Cmd": "apt-get update",
"ErrHint": "Ensure the system has the latest updates installed."
}
]
51 changes: 29 additions & 22 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
Expand All @@ -28,6 +29,12 @@ type CheckResult struct {
Message string `json:"message"`
}

type Check struct {
Name string `json:"name"`
Cmd string `json:"cmd"`
ErrHint string `json:"errHint"`
}

type model struct {
results []CheckResult
quitting bool
Expand All @@ -49,29 +56,14 @@ var (
// Spinner animation frames
var spinnerFrames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}

func runChecks() []CheckResult {
func runChecks(configFile string) []CheckResult {
var wg sync.WaitGroup
results := make([]CheckResult, 0)
mutex := &sync.Mutex{}

checks := []struct {
Name string
Cmd string
ErrHint string
}{
{"System Update", "sudo apt update -y 2>/dev/null ", "Failed to fetch updates. Ensure apt is installed and configured."},
{"System Updateable", "sudo apt list --upgradable 2>/dev/null", "Failed to check for upgradable packages."},
{"Kernel Check", "uname -r", "Kernel information not available."},
{"UFW Firewall Status", "sudo ufw status | grep -q active", "UFW firewall is inactive or not installed."},
{"SSH Security", "grep -q 'PermitRootLogin no' /etc/ssh/sshd_config", "Root login over SSH is permitted. Update sshd_config."},
{"Disk Usage", "df -h > /dev/null", "Disk usage information could not be retrieved."},
{"Memory Usage", "free -m", "Memory usage data is unavailable."},
{"Service Status (rsyslog)", "systemctl is-active --quiet rsyslog", "rsyslog service is not active."},
{"Cron Jobs", "crontab -l", "No cron jobs found for the current user."},
{"TLS Support", "openssl ciphers -v | grep -q 'TLSv1.2\\|TLSv1.3'", "TLSv1.2 or TLSv1.3 support is missing."},
{"Password Policy", "grep -q 'minlen' /etc/security/pwquality.conf", "Password policy not enforced. Check pwquality.conf."},
{"Disk Encryption", "lsblk -o NAME,TYPE,SIZE,MOUNTPOINT,UUID,ENCRYPTION | grep -i crypt", "Disk encryption not enabled."},
{"Unnecessary Services", "systemctl list-units --type=service --state=running | grep -i 'unwanted-service'", "Unnecessary services are running."},
checks, err := loadChecks(configFile)
if err != nil {
log.Fatalf("Error loading checks: %v", err)
}

for _, check := range checks {
Expand All @@ -81,7 +73,7 @@ func runChecks() []CheckResult {
start := time.Now()
status, msg := runCommand(cmd)
if status == "Failed" {
msg = errHint + " (" + msg + ")"
msg = fmt.Sprintf("%s (Command: %s, Error: %s)", errHint, cmd, msg)
}
elapsed := time.Since(start)

Expand All @@ -102,18 +94,33 @@ func runChecks() []CheckResult {
func runCommand(cmd string) (string, string) {
out, err := exec.Command("bash", "-c", cmd).CombinedOutput()
if err != nil {
return "Failed", strings.TrimSpace(string(out))
return "Failed", fmt.Sprintf("Command: %s, Output: %s, Error: %v", cmd, strings.TrimSpace(string(out)), err)
}
return "Passed", strings.TrimSpace(string(out))
}

func loadChecks(configFile string) ([]Check, error) {
file, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, err
}

var checks []Check
err = json.Unmarshal(file, &checks)
if err != nil {
return nil, err
}

return checks, nil
}

type checkResultsMsg []CheckResult

type quitMsg struct{}

func (m model) Init() tea.Cmd {
return func() tea.Msg {
return checkResultsMsg(runChecks())
return checkResultsMsg(runChecks("config.json"))
}
}

Expand Down