Catalyst / admin/Syanpse-Vanguard 14.8 GB / 57.8 GB 40.0 GB free
Help Sign in

admin / Syanpse-Vanguard

public
Code Issues Pull requests Pipelines Packages Security Insights Wiki Settings
Syanpse-Vanguard / synapse-vanguard-v3 / agents / linux / install-linux-agent.sh 8555 B · main
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/usr/bin/env bash
#
# Synapse-Vanguard — one-shot Linux agent installer.
#
# Copies the agent, creates an isolated venv, writes the config, installs and
# starts a systemd service. Idempotent: re-running updates the install in place.
#
# Usage:
#   sudo ./install-linux-agent.sh --server 192.168.1.50 --token <ENROLLMENT_TOKEN>
#
# Options:
#   --server HOST[:PORT]   Server host/IP (default port 5500). Required unless --url.
#   --token  TOKEN         Enrollment token (server's SV_ENROLLMENT_TOKEN). Required.
#   --port   PORT          Server port (default 5500).
#   --url    URL           Full ingest URL, overrides --server/--port
#                          (e.g. https://vanguard.local:9443 for mTLS deployments).
#   --prefix DIR           Install dir (default /opt/sv-agent).
#   --tls-verify           Verify server TLS cert (default: off — dev/plaintext).
#   --no-service           Install only; don't create/start the systemd service.
#   --no-audit             Skip installing the auditd high-signal ruleset.
#   --uninstall            Stop, disable and remove the agent, then exit.
#   -h | --help            Show this help.
#
set -euo pipefail

# ---- defaults ---------------------------------------------------------------
SERVER=""; TOKEN=""; PORT="5500"; URL=""; PREFIX="/opt/sv-agent"
TLS_VERIFY="false"; INSTALL_SERVICE="1"; DO_UNINSTALL="0"; INSTALL_AUDIT="1"
CONF_DIR="/etc/sv-agent"; STATE_DIR="/var/lib/sv-agent"
SERVICE="sv-agent"

c_g="\033[92m"; c_y="\033[93m"; c_r="\033[91m"; c_0="\033[0m"
info(){ echo -e "${c_g}==>${c_0} $*"; }
warn(){ echo -e "${c_y}! ${c_0} $*"; }
die(){ echo -e "${c_r}ERROR:${c_0} $*" >&2; exit 1; }

usage(){ awk 'NR>1{ if ($0 !~ /^#/) exit; sub(/^# ?/,""); print }' "$0"; exit 0; }

# ---- args -------------------------------------------------------------------
while [ $# -gt 0 ]; do
  case "$1" in
    --server) SERVER="$2"; shift 2;;
    --token)  TOKEN="$2";  shift 2;;
    --port)   PORT="$2";   shift 2;;
    --url)    URL="$2";    shift 2;;
    --prefix) PREFIX="$2"; shift 2;;
    --tls-verify)  TLS_VERIFY="true"; shift;;
    --no-service)  INSTALL_SERVICE="0"; shift;;
    --no-audit)    INSTALL_AUDIT="0"; shift;;
    --uninstall)   DO_UNINSTALL="1"; shift;;
    -h|--help) usage;;
    *) die "unknown option: $1 (try --help)";;
  esac
done

[ "$(id -u)" = "0" ] || die "must run as root (use sudo)."

# ---- uninstall path ---------------------------------------------------------
if [ "$DO_UNINSTALL" = "1" ]; then
  info "Uninstalling ${SERVICE}…"
  if command -v systemctl >/dev/null 2>&1; then
    systemctl disable --now "${SERVICE}" 2>/dev/null || true
    rm -f "/etc/systemd/system/${SERVICE}.service"
    systemctl daemon-reload || true
  fi
  rm -rf "$PREFIX" "$CONF_DIR"
  rm -f /etc/audit/rules.d/synapse-vanguard.rules 2>/dev/null || true
  warn "Left ${STATE_DIR} (buffer/identity) in place. Remove it manually to fully reset."
  info "Done."
  exit 0
fi

# ---- locate the agents/ source tree ----------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if   [ -f "$SCRIPT_DIR/agents/linux/sv_agent_linux.py" ]; then SRC="$SCRIPT_DIR/agents"
elif [ -f "$SCRIPT_DIR/linux/sv_agent_linux.py" ];        then SRC="$SCRIPT_DIR"
elif [ -f "$SCRIPT_DIR/../linux/sv_agent_linux.py" ];     then SRC="$(cd "$SCRIPT_DIR/.." && pwd)"
else die "could not find the agents/ package near this script. Copy the whole agents/ dir alongside it."
fi
info "Agent source: $SRC"

# ---- validate connection args ----------------------------------------------
if [ -z "$URL" ]; then
  [ -n "$SERVER" ] || die "--server or --url is required."
  case "$SERVER" in *:*) URL="http://${SERVER}";; *) URL="http://${SERVER}:${PORT}";; esac
fi
[ -n "$TOKEN" ] || die "--token is required (server's SV_ENROLLMENT_TOKEN)."

# ---- prerequisites ----------------------------------------------------------
command -v python3 >/dev/null 2>&1 || die "python3 not found. Install Python 3.10+."
PYV="$(python3 -c 'import sys;print("%d.%d"%sys.version_info[:2])')"
info "python3 = $PYV"
python3 -c 'import venv' 2>/dev/null || die "python3 venv module missing (apt install python3-venv)."

# ---- reachability check (best-effort) --------------------------------------
if command -v curl >/dev/null 2>&1; then
  if curl -fsS --max-time 5 ${TLS_VERIFY:+} "${URL}/healthz" >/dev/null 2>&1; then
    info "Server reachable at ${URL}"
  else
    warn "Could not reach ${URL}/healthz — continuing anyway (agent buffers until it can connect)."
  fi
fi

# ---- install files ----------------------------------------------------------
info "Installing to ${PREFIX}"
mkdir -p "$PREFIX" "$CONF_DIR" "$STATE_DIR"
rm -rf "$PREFIX/agents"
cp -r "$SRC" "$PREFIX/agents"

info "Creating venv + installing deps (httpx, zstandard)"
python3 -m venv "$PREFIX/venv"
"$PREFIX/venv/bin/pip" install -q --upgrade pip
if [ -f "$PREFIX/agents/requirements.txt" ]; then
  "$PREFIX/venv/bin/pip" install -q -r "$PREFIX/agents/requirements.txt"
else
  "$PREFIX/venv/bin/pip" install -q "httpx>=0.28" "zstandard>=0.23"
fi

# ---- distro-aware default log paths ----------------------------------------
if [ -f /var/log/messages ] && [ ! -f /var/log/syslog ]; then
  SYSLOG_PATHS='["/var/log/messages", "/var/log/secure"]'   # RHEL/CentOS/Fedora
else
  SYSLOG_PATHS='["/var/log/syslog", "/var/log/auth.log"]'   # Debian/Ubuntu
fi

# ---- write config (0600; back up any existing) ------------------------------
CONF="$CONF_DIR/agent.config.toml"
[ -f "$CONF" ] && cp "$CONF" "$CONF.bak.$(date +%s)" && warn "existing config backed up"
cat > "$CONF" <<EOF
# Generated by install-linux-agent.sh on $(date -u +%FT%TZ)
ingest_url       = "${URL}"
enrollment_token = "${TOKEN}"
agent_version    = "0.2.0"
mtls_enabled     = false
verify_tls       = ${TLS_VERIFY}

buffer_path = "${STATE_DIR}/buffer.sqlite"
state_path  = "${STATE_DIR}/state.json"
batch_size  = 500
flush_interval_s = 5.0

syslog_paths = ${SYSLOG_PATHS}
auditd_path  = "/var/log/audit/audit.log"
EOF
chmod 600 "$CONF"
info "Wrote ${CONF}"

# ---- auditd high-signal ruleset --------------------------------------------
# auditd is inert without rules — this is what makes /var/log/audit/audit.log a
# rich syscall-level source. We install our ruleset and reload if auditd exists.
if [ "$INSTALL_AUDIT" = "1" ]; then
  RULES_SRC=""
  for cand in "$SRC/linux/audit.rules" "$PREFIX/agents/linux/audit.rules"; do
    [ -f "$cand" ] && RULES_SRC="$cand" && break
  done
  if [ -z "$RULES_SRC" ]; then
    warn "audit.rules not found next to the agent; skipping auditd rules."
  elif command -v auditctl >/dev/null 2>&1 || [ -d /etc/audit/rules.d ]; then
    mkdir -p /etc/audit/rules.d
    install -m 0640 "$RULES_SRC" /etc/audit/rules.d/synapse-vanguard.rules
    info "Installed auditd ruleset -> /etc/audit/rules.d/synapse-vanguard.rules"
    if command -v augenrules >/dev/null 2>&1; then
      augenrules --load 2>/dev/null || warn "augenrules --load failed (rules apply on next auditd restart)."
    elif command -v auditctl >/dev/null 2>&1; then
      auditctl -R /etc/audit/rules.d/synapse-vanguard.rules 2>/dev/null || true
    fi
    systemctl restart auditd 2>/dev/null || service auditd restart 2>/dev/null || \
      warn "Could not restart auditd automatically; restart it to activate rules."
  else
    warn "auditd not installed — install it (e.g. 'apt install auditd') then re-run to enable syscall auditing."
  fi
fi

# ---- systemd service --------------------------------------------------------
if [ "$INSTALL_SERVICE" = "1" ] && command -v systemctl >/dev/null 2>&1; then
  info "Installing systemd service '${SERVICE}'"
  cat > "/etc/systemd/system/${SERVICE}.service" <<EOF
[Unit]
Description=Synapse-Vanguard Linux Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=SV_AGENT_CONFIG=${CONF}
WorkingDirectory=${PREFIX}
ExecStart=${PREFIX}/venv/bin/python -m agents.linux.sv_agent_linux
Restart=always
RestartSec=5
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
EOF
  systemctl daemon-reload
  systemctl enable --now "${SERVICE}"
  sleep 1
  systemctl --no-pager --lines=8 status "${SERVICE}" || true
  echo
  info "Installed. Follow logs with:  journalctl -u ${SERVICE} -f"
else
  info "Skipped service install. Run the agent manually with:"
  echo "  sudo SV_AGENT_CONFIG=${CONF} ${PREFIX}/venv/bin/python -m agents.linux.sv_agent_linux"
fi

echo
info "Done. Check the Agents panel in the Synapse-Vanguard dashboard to confirm enrollment."