a1a17e81a1
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
257 lines
7.2 KiB
Bash
Executable File
257 lines
7.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Graylog API Backup
|
|
#
|
|
# Backs up Graylog configuration objects via the REST API.
|
|
# Exports inputs, streams, pipelines, dashboards, alerts,
|
|
# index sets, users, roles, sidecar configs, content packs,
|
|
# and lookup tables to individual JSON files in a dated directory.
|
|
#
|
|
# Usage:
|
|
# GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" ./graylog-api-backup.sh
|
|
# GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" ./graylog-api-backup.sh --dry-run
|
|
# GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" ./graylog-api-backup.sh --install
|
|
#
|
|
# Parameters:
|
|
# --dry-run Show what would be backed up without writing files
|
|
# --install Create cron job for daily backup at 3am
|
|
# --help Show usage
|
|
#
|
|
# Environment:
|
|
# GRAYLOG_URL Graylog API base URL (required, e.g. http://localhost:9000/api)
|
|
# GRAYLOG_TOKEN API token (required)
|
|
# BACKUP_DIR Base backup directory (default: /backup/graylog-api)
|
|
# RETENTION_DAYS Delete backups older than this many days (default: 30)
|
|
# CURL_TIMEOUT API request timeout in seconds (default: 10)
|
|
#
|
|
# Author: Phil Connor
|
|
# Contact: contact@mylinux.work
|
|
# Website: https://mylinux.work
|
|
# License: MIT
|
|
# Version: 1.01
|
|
|
|
set -euo pipefail
|
|
|
|
# --- Configuration ---
|
|
readonly VERSION="1.0"
|
|
readonly SCRIPT_NAME="$(basename "$0")"
|
|
GRAYLOG_URL="${GRAYLOG_URL:-}"
|
|
GRAYLOG_TOKEN="${GRAYLOG_TOKEN:-}"
|
|
BACKUP_DIR="${BACKUP_DIR:-/backup/graylog-api}"
|
|
RETENTION_DAYS="${RETENTION_DAYS:-30}"
|
|
CURL_TIMEOUT="${CURL_TIMEOUT:-10}"
|
|
DRY_RUN=false
|
|
|
|
# Backup endpoints: "api_path output_filename"
|
|
readonly ENDPOINTS=(
|
|
"system/inputs inputs.json"
|
|
"streams streams.json"
|
|
"system/pipelines/pipeline pipelines.json"
|
|
"system/pipelines/rule pipeline-rules.json"
|
|
"system/pipelines/connections pipeline-connections.json"
|
|
"views dashboards.json"
|
|
"alerts/definitions alert-definitions.json"
|
|
"alerts/notifications alert-notifications.json"
|
|
"system/indices/index_sets index-sets.json"
|
|
"users users.json"
|
|
"roles roles.json"
|
|
"sidecar/configurations sidecar-configs.json"
|
|
"system/content_packs content-packs.json"
|
|
"system/lookup/tables lookup-tables.json"
|
|
"system/lookup/adapters lookup-adapters.json"
|
|
"system/lookup/caches lookup-caches.json"
|
|
)
|
|
|
|
# --- Functions ---
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $SCRIPT_NAME [OPTIONS]
|
|
|
|
Graylog API Backup
|
|
|
|
Options:
|
|
--dry-run Show what would be backed up without writing files
|
|
--install Create cron job for daily backup at 3am
|
|
--help Show this help message
|
|
|
|
Environment Variables:
|
|
GRAYLOG_URL Graylog API base URL (required, e.g. http://localhost:9000/api)
|
|
GRAYLOG_TOKEN API token (required)
|
|
BACKUP_DIR Base backup directory (default: /backup/graylog-api)
|
|
RETENTION_DAYS Delete backups older than N days (default: 30)
|
|
CURL_TIMEOUT Request timeout in seconds (default: 10)
|
|
|
|
Examples:
|
|
GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" $SCRIPT_NAME
|
|
GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" $SCRIPT_NAME --dry-run
|
|
GRAYLOG_URL="http://graylog.example.com:9000/api" GRAYLOG_TOKEN="abc123" $SCRIPT_NAME --install
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
check_dependencies() {
|
|
local missing=()
|
|
for cmd in curl jq; do
|
|
if ! command -v "$cmd" &>/dev/null; then
|
|
missing+=("$cmd")
|
|
fi
|
|
done
|
|
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
echo "ERROR: Missing required commands: ${missing[*]}" >&2
|
|
echo "Install with: apt install ${missing[*]} OR dnf install ${missing[*]}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
validate_config() {
|
|
if [[ -z "$GRAYLOG_URL" ]]; then
|
|
echo "ERROR: GRAYLOG_URL environment variable is required" >&2
|
|
exit 1
|
|
fi
|
|
if [[ -z "$GRAYLOG_TOKEN" ]]; then
|
|
echo "ERROR: GRAYLOG_TOKEN environment variable is required" >&2
|
|
exit 1
|
|
fi
|
|
# Strip trailing slash
|
|
GRAYLOG_URL="${GRAYLOG_URL%/}"
|
|
}
|
|
|
|
api_get() {
|
|
local endpoint="$1"
|
|
curl -sf --max-time "$CURL_TIMEOUT" \
|
|
-u "${GRAYLOG_TOKEN}:token" \
|
|
-H "Accept: application/json" \
|
|
"${GRAYLOG_URL}/${endpoint}" 2>/dev/null || echo ""
|
|
}
|
|
|
|
backup_endpoint() {
|
|
local endpoint="$1"
|
|
local filename="$2"
|
|
local output_dir="$3"
|
|
local response
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
printf " %-35s → %s (dry-run)\n" "$endpoint" "$filename"
|
|
return 0
|
|
fi
|
|
|
|
response=$(api_get "$endpoint")
|
|
|
|
if [[ -z "$response" ]]; then
|
|
printf " %-35s → %-30s FAIL\n" "$endpoint" "$filename"
|
|
return 1
|
|
fi
|
|
|
|
echo "$response" | jq '.' > "${output_dir}/${filename}"
|
|
local size
|
|
size=$(du -h "${output_dir}/${filename}" | cut -f1)
|
|
printf " %-35s → %-30s OK %s\n" "$endpoint" "$filename" "$size"
|
|
return 0
|
|
}
|
|
|
|
cleanup_old_backups() {
|
|
if [[ ! -d "$BACKUP_DIR" ]]; then
|
|
return
|
|
fi
|
|
|
|
local removed=0
|
|
while IFS= read -r dir; do
|
|
rm -rf "$dir"
|
|
((removed++)) || true
|
|
done < <(find "$BACKUP_DIR" -maxdepth 1 -mindepth 1 -type d -mtime +"$RETENTION_DAYS" 2>/dev/null)
|
|
|
|
if [[ $removed -gt 0 ]]; then
|
|
echo "Retention: removed $removed backup(s) older than ${RETENTION_DAYS} days"
|
|
fi
|
|
}
|
|
|
|
install_cron() {
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "ERROR: --install requires root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local script_path
|
|
script_path=$(readlink -f "$0")
|
|
|
|
cat > /etc/cron.d/graylog-api-backup <<EOF
|
|
# Graylog API Backup — runs daily at 3am
|
|
GRAYLOG_URL=${GRAYLOG_URL}
|
|
GRAYLOG_TOKEN=${GRAYLOG_TOKEN}
|
|
BACKUP_DIR=${BACKUP_DIR}
|
|
RETENTION_DAYS=${RETENTION_DAYS}
|
|
0 3 * * * root ${script_path} 2>/dev/null
|
|
EOF
|
|
|
|
chmod 644 /etc/cron.d/graylog-api-backup
|
|
echo "Installed cron job: /etc/cron.d/graylog-api-backup"
|
|
echo "Backups will be written to: ${BACKUP_DIR}/<date>"
|
|
}
|
|
|
|
# --- Main ---
|
|
|
|
main() {
|
|
# Parse arguments
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--dry-run) DRY_RUN=true ;;
|
|
--install)
|
|
check_dependencies
|
|
validate_config
|
|
install_cron
|
|
exit 0
|
|
;;
|
|
--help|-h) usage ;;
|
|
*) echo "Unknown option: $arg" >&2; usage ;;
|
|
esac
|
|
done
|
|
|
|
check_dependencies
|
|
validate_config
|
|
|
|
local today
|
|
today=$(date +%Y%m%d)
|
|
local output_dir="${BACKUP_DIR}/${today}"
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
echo "Graylog API Backup v${VERSION} (dry-run)"
|
|
echo "Target: ${output_dir}"
|
|
echo ""
|
|
else
|
|
mkdir -p "$output_dir"
|
|
echo "Graylog API Backup v${VERSION}"
|
|
echo "Target: ${output_dir}"
|
|
echo ""
|
|
fi
|
|
|
|
local ok=0
|
|
local fail=0
|
|
|
|
for entry in "${ENDPOINTS[@]}"; do
|
|
local endpoint filename
|
|
endpoint="${entry%% *}"
|
|
filename="${entry##* }"
|
|
|
|
if backup_endpoint "$endpoint" "$filename" "$output_dir"; then
|
|
((ok++)) || true
|
|
else
|
|
((fail++)) || true
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
echo "Dry-run complete: ${#ENDPOINTS[@]} endpoints"
|
|
else
|
|
local total_size
|
|
total_size=$(du -sh "$output_dir" | cut -f1)
|
|
echo "Complete: ${ok} OK, ${fail} failed, ${total_size} total"
|
|
|
|
cleanup_old_backups
|
|
fi
|
|
}
|
|
|
|
main "$@"
|