Sync all scripts from website downloads — 352 scripts total
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.
This commit is contained in:
Executable
+576
@@ -0,0 +1,576 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Alloy Config Generator
|
||||
#
|
||||
# Interactive script that generates a Grafana Alloy configuration
|
||||
# file based on your environment. Asks what backends you use, what
|
||||
# signals to collect, and what services to monitor, then outputs
|
||||
# a working config.alloy ready to deploy.
|
||||
#
|
||||
# Usage:
|
||||
# ./alloy-config-generator.sh
|
||||
# ./alloy-config-generator.sh -o /etc/alloy/config.alloy
|
||||
# ./alloy-config-generator.sh --non-interactive --metrics --logs --prometheus-url http://mimir:9009
|
||||
#
|
||||
# Parameters:
|
||||
# -o, --output FILE Write config to file (default: stdout)
|
||||
# --non-interactive Skip prompts, use flags and defaults
|
||||
# --metrics Enable host metrics collection
|
||||
# --logs Enable log collection
|
||||
# --traces Enable OTLP trace collection
|
||||
# --journald Enable journald log collection
|
||||
# --docker Enable Docker container log collection
|
||||
# --nginx Enable nginx log collection
|
||||
# --prometheus-url URL Prometheus/Mimir remote_write URL
|
||||
# --loki-url URL Loki push URL
|
||||
# --tempo-url URL Tempo OTLP endpoint (host:port)
|
||||
# --hostname NAME Hostname label for metrics and logs
|
||||
# --scrape-targets LIST Comma-separated host:port targets to scrape
|
||||
# --help Show usage
|
||||
#
|
||||
# Author: Phil Connor
|
||||
# Contact: contact@mylinux.work
|
||||
# Website: https://mylinux.work
|
||||
# License: MIT
|
||||
# Version: 1.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- Configuration ---
|
||||
readonly VERSION="1.0"
|
||||
readonly SCRIPT_NAME="$(basename "$0")"
|
||||
|
||||
# Defaults
|
||||
OUTPUT=""
|
||||
NON_INTERACTIVE=false
|
||||
ENABLE_METRICS=false
|
||||
ENABLE_LOGS=false
|
||||
ENABLE_TRACES=false
|
||||
ENABLE_JOURNALD=false
|
||||
ENABLE_DOCKER=false
|
||||
ENABLE_NGINX=false
|
||||
PROMETHEUS_URL=""
|
||||
LOKI_URL=""
|
||||
TEMPO_URL=""
|
||||
HOSTNAME=""
|
||||
SCRAPE_TARGETS=""
|
||||
|
||||
# --- Functions ---
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $SCRIPT_NAME [OPTIONS]
|
||||
|
||||
Alloy Config Generator v${VERSION}
|
||||
|
||||
Generates a Grafana Alloy configuration file interactively or from flags.
|
||||
|
||||
Options:
|
||||
-o, --output FILE Write config to file (default: stdout)
|
||||
--non-interactive Skip prompts, use flags and defaults
|
||||
--metrics Enable host metrics collection
|
||||
--logs Enable log collection
|
||||
--traces Enable OTLP trace collection
|
||||
--journald Enable journald log collection
|
||||
--docker Enable Docker container log collection
|
||||
--nginx Enable nginx log collection
|
||||
--prometheus-url URL Prometheus/Mimir remote_write URL
|
||||
--loki-url URL Loki push URL
|
||||
--tempo-url URL Tempo OTLP endpoint (host:port)
|
||||
--hostname NAME Hostname label
|
||||
--scrape-targets LIST Comma-separated host:port targets to scrape
|
||||
--help Show this help
|
||||
|
||||
Examples:
|
||||
$SCRIPT_NAME
|
||||
$SCRIPT_NAME -o /etc/alloy/config.alloy
|
||||
$SCRIPT_NAME --non-interactive --metrics --logs --prometheus-url http://mimir:9009/api/v1/push --loki-url http://loki:3100/loki/api/v1/push
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
ask() {
|
||||
local prompt="$1"
|
||||
local default="$2"
|
||||
local var_name="$3"
|
||||
local response
|
||||
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
eval "$var_name=\"$default\""
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -n "$default" ]]; then
|
||||
read -r -p "$prompt [$default]: " response
|
||||
eval "$var_name=\"${response:-$default}\""
|
||||
else
|
||||
read -r -p "$prompt: " response
|
||||
eval "$var_name=\"$response\""
|
||||
fi
|
||||
}
|
||||
|
||||
ask_yn() {
|
||||
local prompt="$1"
|
||||
local default="$2"
|
||||
local var_name="$3"
|
||||
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local yn_hint="y/n"
|
||||
[[ "$default" == "y" ]] && yn_hint="Y/n"
|
||||
[[ "$default" == "n" ]] && yn_hint="y/N"
|
||||
|
||||
local response
|
||||
read -r -p "$prompt ($yn_hint): " response
|
||||
response="${response:-$default}"
|
||||
|
||||
case "$response" in
|
||||
[Yy]*) eval "$var_name=true" ;;
|
||||
*) eval "$var_name=false" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
interactive_setup() {
|
||||
echo ""
|
||||
echo "Alloy Config Generator v${VERSION}"
|
||||
echo "================================="
|
||||
echo ""
|
||||
echo "This generates a Grafana Alloy config.alloy file."
|
||||
echo ""
|
||||
|
||||
# Hostname
|
||||
local detected_hostname
|
||||
detected_hostname=$(hostname -s 2>/dev/null || echo "server")
|
||||
ask "Hostname label" "$detected_hostname" HOSTNAME
|
||||
echo ""
|
||||
|
||||
# --- Backends ---
|
||||
echo "== Backends =="
|
||||
echo ""
|
||||
|
||||
ask "Prometheus/Mimir remote_write URL (leave empty to skip metrics)" "http://prometheus:9090/api/v1/write" PROMETHEUS_URL
|
||||
if [[ -n "$PROMETHEUS_URL" ]]; then
|
||||
ENABLE_METRICS=true
|
||||
fi
|
||||
|
||||
ask "Loki push URL (leave empty to skip logs)" "http://loki:3100/loki/api/v1/push" LOKI_URL
|
||||
if [[ -n "$LOKI_URL" ]]; then
|
||||
ENABLE_LOGS=true
|
||||
fi
|
||||
|
||||
ask "Tempo OTLP endpoint host:port (leave empty to skip traces)" "" TEMPO_URL
|
||||
if [[ -n "$TEMPO_URL" ]]; then
|
||||
ENABLE_TRACES=true
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# --- Metrics options ---
|
||||
if [[ "$ENABLE_METRICS" == true ]]; then
|
||||
echo "== Metrics =="
|
||||
echo ""
|
||||
|
||||
local extra_targets=""
|
||||
ask "Additional Prometheus scrape targets (comma-separated host:port, or empty)" "" extra_targets
|
||||
if [[ -n "$extra_targets" ]]; then
|
||||
SCRAPE_TARGETS="$extra_targets"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# --- Log options ---
|
||||
if [[ "$ENABLE_LOGS" == true ]]; then
|
||||
echo "== Logs =="
|
||||
echo ""
|
||||
ask_yn "Collect journald logs?" "y" ENABLE_JOURNALD
|
||||
ask_yn "Collect Docker container logs?" "n" ENABLE_DOCKER
|
||||
ask_yn "Collect nginx logs?" "n" ENABLE_NGINX
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Config generation functions ---
|
||||
|
||||
generate_header() {
|
||||
cat <<EOF
|
||||
// Grafana Alloy Configuration
|
||||
// Generated by alloy-config-generator.sh v${VERSION}
|
||||
// $(date +"%Y-%m-%d %H:%M:%S")
|
||||
//
|
||||
// Hostname: ${HOSTNAME}
|
||||
// Docs: https://mylinux.work/guides/grafana-alloy-setup/
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_metrics() {
|
||||
if [[ "$ENABLE_METRICS" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// =========================================
|
||||
// Metrics: host metrics → ${PROMETHEUS_URL}
|
||||
// =========================================
|
||||
|
||||
prometheus.exporter.unix "default" {
|
||||
set_collectors = ["cpu", "diskstats", "filesystem", "loadavg", "meminfo", "netdev", "uname"]
|
||||
filesystem {
|
||||
mount_points_exclude = "^/(sys|proc|dev|run)(\$|/)"
|
||||
}
|
||||
}
|
||||
|
||||
prometheus.scrape "node" {
|
||||
targets = prometheus.exporter.unix.default.targets
|
||||
scrape_interval = "15s"
|
||||
forward_to = [prometheus.remote_write.default.receiver]
|
||||
}
|
||||
|
||||
// Scrape Alloy internal metrics
|
||||
prometheus.scrape "alloy_self" {
|
||||
targets = [
|
||||
{"__address__" = "localhost:12345"},
|
||||
]
|
||||
scrape_interval = "30s"
|
||||
forward_to = [prometheus.remote_write.default.receiver]
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
# Additional scrape targets
|
||||
if [[ -n "$SCRAPE_TARGETS" ]]; then
|
||||
cat <<EOF
|
||||
// Additional scrape targets
|
||||
prometheus.scrape "extra" {
|
||||
targets = [
|
||||
EOF
|
||||
IFS=',' read -ra targets <<< "$SCRAPE_TARGETS"
|
||||
for target in "${targets[@]}"; do
|
||||
target=$(echo "$target" | xargs) # trim whitespace
|
||||
echo " {\"__address__\" = \"${target}\"},"
|
||||
done
|
||||
cat <<EOF
|
||||
]
|
||||
scrape_interval = "15s"
|
||||
forward_to = [prometheus.remote_write.default.receiver]
|
||||
}
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
prometheus.remote_write "default" {
|
||||
endpoint {
|
||||
url = "${PROMETHEUS_URL}"
|
||||
}
|
||||
external_labels = {
|
||||
host = "${HOSTNAME}",
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_header() {
|
||||
if [[ "$ENABLE_LOGS" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// =========================================
|
||||
// Logs → ${LOKI_URL}
|
||||
// =========================================
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_system() {
|
||||
if [[ "$ENABLE_LOGS" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Detect OS family for log paths
|
||||
local syslog_path="/var/log/syslog"
|
||||
local auth_path="/var/log/auth.log"
|
||||
if [[ -f /etc/redhat-release ]] || [[ -f /etc/rocky-release ]] || [[ -f /etc/almalinux-release ]]; then
|
||||
syslog_path="/var/log/messages"
|
||||
auth_path="/var/log/secure"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// System log files
|
||||
local.file_match "system_logs" {
|
||||
path_targets = [
|
||||
{__path__ = "${syslog_path}", job = "syslog"},
|
||||
{__path__ = "${auth_path}", job = "auth"},
|
||||
]
|
||||
}
|
||||
|
||||
loki.source.file "system" {
|
||||
targets = local.file_match.system_logs.targets
|
||||
forward_to = [loki.process.add_host.receiver]
|
||||
}
|
||||
|
||||
loki.process "add_host" {
|
||||
forward_to = [loki.write.default.receiver]
|
||||
|
||||
stage.static_labels {
|
||||
values = {
|
||||
host = "${HOSTNAME}",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_journald() {
|
||||
if [[ "$ENABLE_JOURNALD" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// Journald
|
||||
loki.source.journal "default" {
|
||||
max_age = "12h"
|
||||
relabel_rules = loki.relabel.journal.rules
|
||||
forward_to = [loki.write.default.receiver]
|
||||
}
|
||||
|
||||
loki.relabel "journal" {
|
||||
forward_to = []
|
||||
rule {
|
||||
source_labels = ["__journal__systemd_unit"]
|
||||
target_label = "unit"
|
||||
}
|
||||
rule {
|
||||
source_labels = ["__journal__hostname"]
|
||||
target_label = "host"
|
||||
}
|
||||
rule {
|
||||
source_labels = ["__journal__priority_keyword"]
|
||||
target_label = "level"
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_docker() {
|
||||
if [[ "$ENABLE_DOCKER" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// Docker container logs
|
||||
discovery.docker "containers" {
|
||||
host = "unix:///var/run/docker.sock"
|
||||
}
|
||||
|
||||
discovery.relabel "docker" {
|
||||
targets = discovery.docker.containers.targets
|
||||
|
||||
rule {
|
||||
source_labels = ["__meta_docker_container_name"]
|
||||
target_label = "container"
|
||||
regex = "/(.*)"
|
||||
}
|
||||
rule {
|
||||
source_labels = ["__meta_docker_container_log_stream"]
|
||||
target_label = "stream"
|
||||
}
|
||||
}
|
||||
|
||||
loki.source.docker "default" {
|
||||
host = "unix:///var/run/docker.sock"
|
||||
targets = discovery.docker.containers.targets
|
||||
labels = {"host" = "${HOSTNAME}", "job" = "docker"}
|
||||
forward_to = [loki.write.default.receiver]
|
||||
relabel_rules = discovery.relabel.docker.rules
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_nginx() {
|
||||
if [[ "$ENABLE_NGINX" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// Nginx logs
|
||||
local.file_match "nginx" {
|
||||
path_targets = [
|
||||
{__path__ = "/var/log/nginx/access.log", job = "nginx_access"},
|
||||
{__path__ = "/var/log/nginx/error.log", job = "nginx_error"},
|
||||
]
|
||||
}
|
||||
|
||||
loki.source.file "nginx" {
|
||||
targets = local.file_match.nginx.targets
|
||||
forward_to = [loki.process.nginx.receiver]
|
||||
}
|
||||
|
||||
loki.process "nginx" {
|
||||
forward_to = [loki.write.default.receiver]
|
||||
|
||||
stage.static_labels {
|
||||
values = {
|
||||
host = "${HOSTNAME}",
|
||||
}
|
||||
}
|
||||
|
||||
stage.regex {
|
||||
expression = "^(?P<remote_addr>\\\\S+) - (?P<remote_user>\\\\S+) \\\\[(?P<timestamp>.+?)\\\\] \"(?P<method>\\\\S+) (?P<path>\\\\S+) (?P<protocol>\\\\S+)\" (?P<status>\\\\d+) (?P<bytes>\\\\d+)"
|
||||
}
|
||||
|
||||
stage.labels {
|
||||
values = {
|
||||
method = "",
|
||||
status = "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_logs_write() {
|
||||
if [[ "$ENABLE_LOGS" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
loki.write "default" {
|
||||
endpoint {
|
||||
url = "${LOKI_URL}"
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_traces() {
|
||||
if [[ "$ENABLE_TRACES" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
// =========================================
|
||||
// Traces: OTLP → ${TEMPO_URL}
|
||||
// =========================================
|
||||
|
||||
otelcol.receiver.otlp "default" {
|
||||
grpc {
|
||||
endpoint = "0.0.0.0:4317"
|
||||
}
|
||||
http {
|
||||
endpoint = "0.0.0.0:4318"
|
||||
}
|
||||
output {
|
||||
traces = [otelcol.processor.batch.default.input]
|
||||
}
|
||||
}
|
||||
|
||||
otelcol.processor.batch "default" {
|
||||
timeout = "5s"
|
||||
output {
|
||||
traces = [otelcol.exporter.otlp.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
otelcol.exporter.otlp "tempo" {
|
||||
client {
|
||||
endpoint = "${TEMPO_URL}"
|
||||
tls {
|
||||
insecure = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
generate_header
|
||||
generate_metrics
|
||||
generate_logs_header
|
||||
generate_logs_system
|
||||
generate_logs_journald
|
||||
generate_logs_docker
|
||||
generate_logs_nginx
|
||||
generate_logs_write
|
||||
generate_traces
|
||||
}
|
||||
|
||||
# --- Main ---
|
||||
|
||||
main() {
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-o|--output) OUTPUT="$2"; shift 2 ;;
|
||||
--non-interactive) NON_INTERACTIVE=true; shift ;;
|
||||
--metrics) ENABLE_METRICS=true; shift ;;
|
||||
--logs) ENABLE_LOGS=true; shift ;;
|
||||
--traces) ENABLE_TRACES=true; shift ;;
|
||||
--journald) ENABLE_JOURNALD=true; shift ;;
|
||||
--docker) ENABLE_DOCKER=true; shift ;;
|
||||
--nginx) ENABLE_NGINX=true; shift ;;
|
||||
--prometheus-url) PROMETHEUS_URL="$2"; ENABLE_METRICS=true; shift 2 ;;
|
||||
--loki-url) LOKI_URL="$2"; ENABLE_LOGS=true; shift 2 ;;
|
||||
--tempo-url) TEMPO_URL="$2"; ENABLE_TRACES=true; shift 2 ;;
|
||||
--hostname) HOSTNAME="$2"; shift 2 ;;
|
||||
--scrape-targets) SCRAPE_TARGETS="$2"; shift 2 ;;
|
||||
--help|-h) usage ;;
|
||||
*) echo "Unknown option: $1" >&2; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Set hostname default
|
||||
if [[ -z "$HOSTNAME" ]]; then
|
||||
HOSTNAME=$(hostname -s 2>/dev/null || echo "server")
|
||||
fi
|
||||
|
||||
# Set backend URL defaults for non-interactive mode
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
[[ "$ENABLE_METRICS" == true && -z "$PROMETHEUS_URL" ]] && PROMETHEUS_URL="http://prometheus:9090/api/v1/write"
|
||||
[[ "$ENABLE_LOGS" == true && -z "$LOKI_URL" ]] && LOKI_URL="http://loki:3100/loki/api/v1/push"
|
||||
[[ "$ENABLE_TRACES" == true && -z "$TEMPO_URL" ]] && TEMPO_URL="tempo:4317"
|
||||
fi
|
||||
|
||||
# Interactive mode
|
||||
if [[ "$NON_INTERACTIVE" != true ]]; then
|
||||
interactive_setup
|
||||
fi
|
||||
|
||||
# Check at least one signal is enabled
|
||||
if [[ "$ENABLE_METRICS" != true && "$ENABLE_LOGS" != true && "$ENABLE_TRACES" != true ]]; then
|
||||
echo "ERROR: No signals enabled. Enable at least one of: metrics, logs, traces" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate config
|
||||
if [[ -n "$OUTPUT" ]]; then
|
||||
generate_config > "$OUTPUT"
|
||||
echo ""
|
||||
echo "Config written to: $OUTPUT"
|
||||
echo ""
|
||||
echo "Signals enabled:"
|
||||
[[ "$ENABLE_METRICS" == true ]] && echo " ✓ Metrics → $PROMETHEUS_URL"
|
||||
[[ "$ENABLE_LOGS" == true ]] && echo " ✓ Logs → $LOKI_URL"
|
||||
[[ "$ENABLE_TRACES" == true ]] && echo " ✓ Traces → $TEMPO_URL"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Review the config: cat $OUTPUT"
|
||||
echo " 2. Validate syntax: alloy fmt $OUTPUT"
|
||||
echo " 3. Test it: alloy run $OUTPUT"
|
||||
echo " 4. Deploy: sudo cp $OUTPUT /etc/alloy/config.alloy && sudo systemctl restart alloy"
|
||||
else
|
||||
generate_config
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user