Skip to content
Merged
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
5 changes: 0 additions & 5 deletions .cargo/config.toml

This file was deleted.

46 changes: 0 additions & 46 deletions BUILD-EBPF.md

This file was deleted.

29 changes: 0 additions & 29 deletions Cargo.toml

This file was deleted.

51 changes: 10 additions & 41 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,48 +1,17 @@
.PHONY: build install clean test fmt clippy build-bpf help
.PHONY: all bpf go clean

help:
@echo "Available targets:"
@echo " build - Build all Rust components"
@echo " build-bpf - Build eBPF programs"
@echo " install - Install to system (requires root)"
@echo " clean - Clean build artifacts"
@echo " test - Run tests"
@echo " fmt - Format code"
@echo " clippy - Run clippy linter"
@echo " help - Show this help"
all: bpf go

build: build-bpf
@echo "Building secrds Security Monitor..."
@cargo build --release
@echo "Build complete."
bpf:
clang -O2 -g -target bpf -c bpf/ssh_accept.bpf.c -o secrds.bpf.o

build-bpf:
@echo "Building eBPF programs..."
@echo "Note: Aya eBPF build requires special setup."
@echo "See BUILD-EBPF.md for instructions."
@chmod +x build-ebpf.sh
@./build-ebpf.sh
@echo "eBPF build complete (may be placeholder)."

install:
@echo "Installing secrds Security Monitor..."
@sudo chmod +x install.sh
@sudo ./install.sh
go:
go mod download
go build -o secrds ./cmd/secrds

clean:
@echo "Cleaning build artifacts..."
@cargo clean
@rm -rf target/release/secrds-*
@rm -rf target/bpfel-unknown-none

test:
@echo "Running Rust tests..."
@cargo test --workspace || true
rm -f secrds secrds.bpf.o

fmt:
@echo "Formatting Rust code..."
@cargo fmt --all || true
run: all
sudo ./secrds

clippy:
@echo "Running clippy linter..."
@cargo clippy --workspace || true
71 changes: 71 additions & 0 deletions bpf/ssh_accept.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// bpf/ssh_accept.bpf.c
// Compile target: clang -O2 -g -target bpf -c ssh_accept.bpf.c -o ssh_accept.bpf.o

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <linux/ptrace.h>
#include <linux/sched.h>

// Tracepoint struct definition for sys_exit
struct trace_event_raw_sys_exit {
unsigned short common_type;
unsigned char common_flags;
unsigned char common_preempt_count;
int common_pid;
long id;
long ret;
};

// Event we send to userland
struct accept_event {
__u32 pid;
__u32 tgid;
int fd; // returned fd from accept4
__u64 ts_ns;
char comm[16];
};

struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(__u32));
__uint(max_entries, 0);
} events SEC(".maps");

// Helper function to handle accept/accept4 exit
static __always_inline int handle_accept_exit(struct trace_event_raw_sys_exit *ctx)
{
int retval = (int)ctx->ret;
if (retval < 0) {
// accept failed
return 0;
}

struct accept_event ev = {};
__u64 pid_tgid = bpf_get_current_pid_tgid();
ev.pid = (__u32)pid_tgid; // tid
ev.tgid = (__u32)(pid_tgid >> 32); // pid (tgid)
ev.fd = retval;
ev.ts_ns = bpf_ktime_get_ns();
bpf_get_current_comm(&ev.comm, sizeof(ev.comm));

// send to userland
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &ev, sizeof(ev));
return 0;
}

// tracepoint: sys_exit_accept4
SEC("tracepoint/syscalls/sys_exit_accept4")
int trace_exit_accept4(struct trace_event_raw_sys_exit *ctx)
{
return handle_accept_exit(ctx);
}

// tracepoint: sys_exit_accept (for systems using accept instead of accept4)
SEC("tracepoint/syscalls/sys_exit_accept")
int trace_exit_accept(struct trace_event_raw_sys_exit *ctx)
{
return handle_accept_exit(ctx);
}

char _license[] SEC("license") = "GPL";
46 changes: 0 additions & 46 deletions build-ebpf.sh

This file was deleted.

38 changes: 0 additions & 38 deletions build.sh

This file was deleted.

75 changes: 75 additions & 0 deletions cmd/secrds/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"fmt"
"os"
"os/signal"
"syscall"

"secrds/internal/logger"
"secrds/internal/monitor"
)

func main() {
// Default log directory - try /var/log/secrds first, fallback to /etc/secrds/logs
logDir := "/var/log/secrds"
if _, err := os.Stat("/var/log"); err != nil {
// Fallback to /etc/secrds/logs if /var/log doesn't exist or isn't writable
logDir = "/etc/secrds/logs"
}

// Initialize logger
lg, err := logger.NewLogger(logDir)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize logger: %v\n", err)
os.Exit(1)
}
defer lg.Close()

// Create monitor
mon := monitor.NewMonitor(lg)

// Load BPF object file
bpfObjFile := "secrds.bpf.o"
if len(os.Args) > 1 {
bpfObjFile = os.Args[1]
}

if err := mon.LoadBPF(bpfObjFile); err != nil {
lg.LogError("Failed to load BPF: %v", err)
os.Exit(1)
}

// Attach tracepoints
if err := mon.Attach(); err != nil {
lg.LogError("Failed to attach tracepoints: %v", err)
os.Exit(1)
}

// Start perf reader
if err := mon.StartPerfReader(); err != nil {
lg.LogError("Failed to start perf reader: %v", err)
os.Exit(1)
}
defer mon.Close()

// Start monitoring
lg.StartMonitoring()

// Handle signals
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

// Start event processing in goroutine
go mon.ProcessEvents()

// Wait for signal
<-sigChan
lg.LogInfo("Shutting down...")

// Close monitor (this will gracefully stop the goroutine)
mon.Close()

lg.LogInfo("Exited")
}

Loading
Loading