Skip to main content

max / makenotwork

4.4 KB · 135 lines History Blame Raw
1 #!/bin/bash
2 # Set up Florian Roth's `signature-base` YARA ruleset on the Makenotwork
3 # production host. Idempotent: safe to re-run; pulls upstream changes if
4 # the repo's already cloned.
5 #
6 # After this script finishes, add the following to /opt/makenotwork/.env
7 # (and restart makenotwork):
8 #
9 # YARA_RULES_DIR=/opt/makenotwork/yara-rules
10 #
11 # The `yara` layer compiles every `.yar` file in that directory at server
12 # startup. The Pipeline Health card flips from "down — No YARA rules loaded"
13 # to "ok" after the first upload completes.
14 #
15 # Periodic refresh: install the cron entry at the bottom of this script so
16 # upstream rule updates land automatically. Re-running the cron does NOT
17 # restart makenotwork — new rules take effect on next startup. Run a manual
18 # `systemctl restart makenotwork` after a significant ruleset change.
19 #
20 # References:
21 # - https://github.com/Neo23x0/signature-base
22 # - https://github.com/Neo23x0/signature-base/blob/master/LICENSE (CC-BY-NC 4.0)
23 #
24 # License note: signature-base is CC-BY-NC 4.0 (non-commercial). We use it
25 # server-side to protect creators on the platform; this is the same usage
26 # profile the upstream contributors document for SIEM/IR deployments.
27
28 set -euo pipefail
29
30 RULES_REPO="https://github.com/Neo23x0/signature-base.git"
31 WORK_DIR="/opt/makenotwork/yara-rules-src"
32 LINK_DIR="/opt/makenotwork/yara-rules"
33 CRON_FILE="/etc/cron.d/mnw-yara-rules"
34
35 require_root() {
36 if [ "$(id -u)" -ne 0 ]; then
37 echo "[yara] error: must run as root" >&2
38 exit 1
39 fi
40 }
41
42 ensure_git() {
43 if ! command -v git >/dev/null 2>&1; then
44 DEBIAN_FRONTEND=noninteractive apt-get update -qq
45 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git
46 fi
47 }
48
49 pull_or_clone() {
50 if [ -d "$WORK_DIR/.git" ]; then
51 echo "[yara] updating $WORK_DIR..."
52 git -C "$WORK_DIR" fetch --depth=1 origin master
53 git -C "$WORK_DIR" reset --hard origin/master
54 else
55 echo "[yara] cloning $RULES_REPO -> $WORK_DIR..."
56 git clone --depth=1 "$RULES_REPO" "$WORK_DIR"
57 fi
58 }
59
60 assemble_link_dir() {
61 # The repo lays rules out under yara/, but also ships a few support
62 # files we want to skip (LICENSE, .md, etc.). Assemble a flat dir of
63 # .yar files so the yara-x compiler walks it cleanly.
64 echo "[yara] assembling $LINK_DIR..."
65 rm -rf "$LINK_DIR"
66 mkdir -p "$LINK_DIR"
67 # Copy every .yar / .yara, preserving filenames. find -print0 + cp is
68 # the safe pattern (handles spaces, though signature-base avoids them).
69 find "$WORK_DIR/yara" -type f \( -name '*.yar' -o -name '*.yara' \) -print0 \
70 | xargs -0 -I {} cp {} "$LINK_DIR/"
71 local count
72 count=$(ls -1 "$LINK_DIR" | wc -l)
73 echo "[yara] $count rule files staged"
74 }
75
76 write_ruleset_version() {
77 # Stamp the commit SHA so we can correlate scan_layers details back to
78 # a specific rule revision when a creator asks "why did this flag?"
79 local sha
80 sha=$(git -C "$WORK_DIR" rev-parse --short HEAD)
81 local date
82 date=$(git -C "$WORK_DIR" log -1 --format=%cI)
83 cat > "$LINK_DIR/RULESET_VERSION" <<EOF
84 repo=$RULES_REPO
85 commit=$sha
86 date=$date
87 synced_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
88 EOF
89 echo "[yara] ruleset commit $sha ($date)"
90 }
91
92 install_cron() {
93 cat > "$CRON_FILE" <<EOF
94 # Pull upstream YARA ruleset updates weekly. Does not restart makenotwork —
95 # the compiled rules in memory keep working until the next service restart.
96 SHELL=/bin/bash
97 PATH=/usr/sbin:/usr/bin:/sbin:/bin
98 30 4 * * 1 root /opt/makenotwork/deploy/setup-yara-rules.sh >> /var/log/mnw-yara-update.log 2>&1
99 EOF
100 chmod 644 "$CRON_FILE"
101 echo "[yara] cron installed at $CRON_FILE (weekly, Mondays 04:30 UTC)"
102 }
103
104 main() {
105 require_root
106 ensure_git
107 pull_or_clone
108 assemble_link_dir
109 write_ruleset_version
110
111 # Only install the cron on the first setup run (re-running idempotently
112 # rewrites it, which is also fine but noisy).
113 if [ ! -f "$CRON_FILE" ]; then
114 install_cron
115 fi
116
117 cat <<EOF
118
119 [yara] setup complete. Ruleset at $LINK_DIR.
120
121 Next step — set the env var so makenotwork uses these rules:
122
123 echo 'YARA_RULES_DIR=$LINK_DIR' >> /opt/makenotwork/.env
124 systemctl restart makenotwork
125
126 The Pipeline Health card for 'yara' will flip from down to ok after the
127 first upload passes through the scan worker. Subsequent ruleset bumps land
128 via the weekly cron; a manual 'systemctl restart makenotwork' picks up the
129 newly-compiled rules.
130
131 EOF
132 }
133
134 main "$@"
135