Compare commits
No commits in common. "3adba7a09dc9bf62eb1c94cf5a5300ae55148b97" and "c032cdba58e86f9a2268235e0b5732ae8216efd9" have entirely different histories.
3adba7a09d
...
c032cdba58
|
|
@ -21,9 +21,9 @@ func NewSafeCmd() *cobra.Command {
|
||||||
Short: "交互式安全确认,将可疑对象加入白名单",
|
Short: "交互式安全确认,将可疑对象加入白名单",
|
||||||
Long: "查看当前的可疑文件和进程列表,并选择将其移入白名单。",
|
Long: "查看当前的可疑文件和进程列表,并选择将其移入白名单。",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cfg, ok := cmd.Context().Value("config").(*config.Config)
|
cfg, err := config.LoadConfig("./config.yaml")
|
||||||
if !ok {
|
if err != nil {
|
||||||
fmt.Println("无法获取配置")
|
fmt.Printf("加载配置失败: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,10 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"sysmonitord/internal/config"
|
"sysmonitord/internal/config"
|
||||||
"sysmonitord/pkg/logger"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewStatusCmd() *cobra.Command {
|
func NewStatusCmd() *cobra.Command {
|
||||||
|
|
@ -21,9 +16,10 @@ func NewStatusCmd() *cobra.Command {
|
||||||
Short: "显示系统状态",
|
Short: "显示系统状态",
|
||||||
Long: "显示Sysmonitod的当前状态",
|
Long: "显示Sysmonitod的当前状态",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cfg, ok := cmd.Context().Value("config").(*config.Config)
|
cfg, err := config.LoadConfig("./config.yaml")
|
||||||
if !ok {
|
|
||||||
fmt.Println("无法获取配置")
|
if err != nil {
|
||||||
|
fmt.Printf("加载配置失败: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +36,7 @@ func printStatus(cfg *config.Config) {
|
||||||
fmt.Println("================")
|
fmt.Println("================")
|
||||||
|
|
||||||
// Todo: 显示运行时长
|
// Todo: 显示运行时长
|
||||||
runtimeInfo := getRuntime()
|
runtimeInfo := "N/A"
|
||||||
|
|
||||||
fmt.Printf("Runtime: %s\n", runtimeInfo)
|
fmt.Printf("Runtime: %s\n", runtimeInfo)
|
||||||
fmt.Printf("Data Directory: %s\n", dataDir)
|
fmt.Printf("Data Directory: %s\n", dataDir)
|
||||||
|
|
@ -92,69 +88,3 @@ func countLines(filePath string) (int, error) {
|
||||||
|
|
||||||
return lineCount, scanner.Err()
|
return lineCount, scanner.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRuntime() string {
|
|
||||||
cmd := exec.Command("systemctl", "is-active", "sysmonitord")
|
|
||||||
output, err := cmd.Output()
|
|
||||||
if err != nil || strings.TrimSpace(string(output)) != "active" {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = exec.Command("systemctl", "show", "sysmonitord", "--property=ActiveEnterTimestamp")
|
|
||||||
output, err = cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := strings.SplitN(string(output), "=", 2)
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
timestampStr := strings.TrimSpace(parts[1])
|
|
||||||
if timestampStr == "" {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
layouts := []string{
|
|
||||||
"Mon 2006-01-02 15:04:05 MST",
|
|
||||||
"Mon 2006-01-02 15:04:05",
|
|
||||||
"2006-01-02 15:04:05 MST",
|
|
||||||
"2006-01-02 15:04:05",
|
|
||||||
"Mon 2006-01-02 15:04:05 MST 2006",
|
|
||||||
}
|
|
||||||
|
|
||||||
var startTime time.Time
|
|
||||||
var parseErr error
|
|
||||||
for _, layout := range layouts {
|
|
||||||
startTime, parseErr = time.Parse(layout, timestampStr)
|
|
||||||
if parseErr == nil {
|
|
||||||
logger.Log.Debug("时间解析成功", zap.String("layout", layout))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if parseErr != nil {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
if time.Since(startTime) < 0 {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime := time.Since(startTime)
|
|
||||||
|
|
||||||
days := int(runtime.Hours()) / 24
|
|
||||||
hours := int(runtime.Hours()) % 24
|
|
||||||
minutes := int(runtime.Minutes()) % 60
|
|
||||||
seconds := int(runtime.Seconds()) % 60
|
|
||||||
|
|
||||||
if days > 0 {
|
|
||||||
return fmt.Sprintf("%d天 %d小时 %d分钟 %d秒", days, hours, minutes, seconds)
|
|
||||||
} else if hours > 0 {
|
|
||||||
return fmt.Sprintf("%d小时 %d分钟 %d秒", hours, minutes, seconds)
|
|
||||||
} else if minutes > 0 {
|
|
||||||
return fmt.Sprintf("%d分钟 %d秒", minutes, seconds)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("%d秒", seconds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -21,65 +21,8 @@ scanner:
|
||||||
include_paths:
|
include_paths:
|
||||||
- /
|
- /
|
||||||
exclude_paths:
|
exclude_paths:
|
||||||
# ========== 虚拟/临时文件系统==========
|
|
||||||
- /proc
|
- /proc
|
||||||
- /sys
|
- /sys
|
||||||
- /dev
|
|
||||||
- /tmp
|
|
||||||
- /var/tmp
|
|
||||||
- /run
|
|
||||||
- /mnt
|
|
||||||
- /media
|
|
||||||
|
|
||||||
# ========== 系统高频写入目录==========
|
|
||||||
- /var/log
|
|
||||||
- /var/cache
|
|
||||||
- /var/mail
|
|
||||||
- /var/spool
|
|
||||||
- /var/lib/docker
|
|
||||||
- /var/lib/containerd
|
|
||||||
- /var/lib/systemd
|
|
||||||
|
|
||||||
# ========== 内核模块==========
|
|
||||||
- /usr/lib/modules
|
|
||||||
- /lib/modules
|
|
||||||
- /usr/src
|
|
||||||
|
|
||||||
# ========== 应用缓存和构建目录==========
|
|
||||||
# 通用
|
|
||||||
- "**/node_modules"
|
|
||||||
- "**/.git"
|
|
||||||
- "**/.cache"
|
|
||||||
- "**/build"
|
|
||||||
- "**/dist"
|
|
||||||
- "**/unpackage"
|
|
||||||
- "**/vendor"
|
|
||||||
- "**/__pycache__"
|
|
||||||
- "**/.idea"
|
|
||||||
- "**/.vscode"
|
|
||||||
|
|
||||||
# ========== Web 应用特定==========
|
|
||||||
- "**/cache"
|
|
||||||
- "**/logs"
|
|
||||||
- "**/tmp"
|
|
||||||
- "**/temp"
|
|
||||||
- "**/uploads/tmp"
|
|
||||||
|
|
||||||
# ========== 用户缓存目录 ==========
|
|
||||||
- /root/.cache
|
|
||||||
- /root/.npm
|
|
||||||
- /root/.local
|
|
||||||
- /home/*/.cache
|
|
||||||
- /home/*/.npm
|
|
||||||
- /home/*/.local
|
|
||||||
- /home/*/.gradle
|
|
||||||
- /home/*/.m2
|
|
||||||
|
|
||||||
# ========== 其他高频变化目录 ==========
|
|
||||||
- /var/run
|
|
||||||
- /var/lock
|
|
||||||
- /opt/*/cache
|
|
||||||
- /opt/*/logs
|
|
||||||
fast_hash: true
|
fast_hash: true
|
||||||
fast_hash_size: 100MB
|
fast_hash_size: 100MB
|
||||||
fast_hash_chunk: 2MB
|
fast_hash_chunk: 2MB
|
||||||
|
|
|
||||||
|
|
@ -56,26 +56,19 @@ func (s *Scanner) Scan() ([]FileInfo, error) {
|
||||||
var allFiles []FileInfo
|
var allFiles []FileInfo
|
||||||
hashCfg, _ := s.cfg.GetHashConfig()
|
hashCfg, _ := s.cfg.GetHashConfig()
|
||||||
|
|
||||||
var bar *progressbar.ProgressBar
|
bar := progressbar.NewOptions(len(allPaths),
|
||||||
if isInteractiveTerminal() {
|
progressbar.OptionSetDescription("[scan]计算文件哈希"),
|
||||||
bar = progressbar.NewOptions(len(allPaths),
|
progressbar.OptionSetWriter(os.Stderr),
|
||||||
progressbar.OptionSetDescription("[scan]计算文件哈希"),
|
progressbar.OptionShowCount(),
|
||||||
progressbar.OptionSetWriter(os.Stderr),
|
progressbar.OptionShowIts(),
|
||||||
progressbar.OptionShowCount(),
|
progressbar.OptionSetItsString("files"),
|
||||||
progressbar.OptionShowIts(),
|
progressbar.OptionOnCompletion(func() {
|
||||||
progressbar.OptionSetItsString("files"),
|
logger.Log.Info("[scan]文件哈希计算完成")
|
||||||
progressbar.OptionOnCompletion(func() {
|
}),
|
||||||
logger.Log.Info("[scan]文件哈希计算完成")
|
)
|
||||||
}),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
logger.Log.Info("[scan]开始计算文件哈希", zap.Int("total_files", len(allPaths)))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, path := range allPaths {
|
for _, path := range allPaths {
|
||||||
if bar != nil {
|
bar.Add(1)
|
||||||
bar.Add(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := os.Stat(path)
|
info, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -162,17 +155,6 @@ func (s *Scanner) collectPathsFunc(result *[]string) fs.WalkDirFunc {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := d.Info()
|
|
||||||
if err == nil {
|
|
||||||
if info.Mode()&os.ModeSymlink != 0 {
|
|
||||||
realInfo, err := os.Stat(path)
|
|
||||||
if err == nil && realInfo.IsDir() {
|
|
||||||
logger.Log.Debug("[scan]跳过指向目录的符号链接", zap.String("path", path))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, exclude := range s.cfg.Scanner.File.ExcludePaths {
|
for _, exclude := range s.cfg.Scanner.File.ExcludePaths {
|
||||||
if strings.HasPrefix(path, exclude) {
|
if strings.HasPrefix(path, exclude) {
|
||||||
logger.Log.Debug("[scan]跳过路径", zap.String("path", path), zap.String("reason", "匹配排除路径"))
|
logger.Log.Debug("[scan]跳过路径", zap.String("path", path), zap.String("reason", "匹配排除路径"))
|
||||||
|
|
@ -185,15 +167,6 @@ func (s *Scanner) collectPathsFunc(result *[]string) fs.WalkDirFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isInteractiveTerminal() bool {
|
|
||||||
fileInfo, err := os.Stderr.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return (fileInfo.Mode() & os.ModeCharDevice) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FileInfo) String() string {
|
func (f FileInfo) String() string {
|
||||||
return fmt.Sprintf("%s:%s", f.Path, f.Hash)
|
return fmt.Sprintf("%s:%s", f.Path, f.Hash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
63
uninstall.sh
63
uninstall.sh
|
|
@ -1,63 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# sysmonitord 卸载脚本
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "正在卸载 sysmonitord..."
|
|
||||||
|
|
||||||
# 检测是否为 root 用户
|
|
||||||
if [ "$EUID" -ne 0 ]; then
|
|
||||||
echo "请使用 root 用户运行此卸载脚本。"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 路径设置
|
|
||||||
BIN_NAME="sysmonitord"
|
|
||||||
INSTALL_DIR="/usr/local/bin"
|
|
||||||
CONFIG_DIR="/etc/sysmonitord"
|
|
||||||
DATA_DIR="/var/lib/sysmonitord"
|
|
||||||
LOG_DIR="/var/log/sysmonitord"
|
|
||||||
SERVICE_FILE="/etc/systemd/system/sysmonitord.service"
|
|
||||||
|
|
||||||
# 停止并禁用服务
|
|
||||||
if systemctl is-active --quiet sysmonitord; then
|
|
||||||
echo "正在停止 sysmonitord 服务..."
|
|
||||||
systemctl stop sysmonitord
|
|
||||||
fi
|
|
||||||
|
|
||||||
if systemctl is-enabled --quiet sysmonitord 2>/dev/null; then
|
|
||||||
echo "正在禁用 sysmonitord 服务..."
|
|
||||||
systemctl disable sysmonitord
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 删除 systemd 服务文件
|
|
||||||
if [ -f "$SERVICE_FILE" ]; then
|
|
||||||
echo "正在删除 systemd 服务文件..."
|
|
||||||
rm -f "$SERVICE_FILE"
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 删除可执行文件
|
|
||||||
if [ -f "$INSTALL_DIR/$BIN_NAME" ]; then
|
|
||||||
echo "正在删除可执行文件..."
|
|
||||||
rm -f "$INSTALL_DIR/$BIN_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 询问是否删除数据文件
|
|
||||||
echo ""
|
|
||||||
read -p "是否删除所有数据文件(包括配置、数据和日志)?[y/N] " -n 1 -r
|
|
||||||
echo
|
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
echo "正在删除数据文件..."
|
|
||||||
rm -rf "$CONFIG_DIR"
|
|
||||||
rm -rf "$DATA_DIR"
|
|
||||||
rm -rf "$LOG_DIR"
|
|
||||||
echo "数据文件已删除。"
|
|
||||||
else
|
|
||||||
echo "保留数据文件。"
|
|
||||||
echo "配置文件目录: $CONFIG_DIR"
|
|
||||||
echo "数据目录: $DATA_DIR"
|
|
||||||
echo "日志目录: $LOG_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "sysmonitord 卸载完成!"
|
|
||||||
Loading…
Reference in New Issue
Block a user