admin / Syanpse-Vanguard
public
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." |