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:
2026-05-25 03:31:08 +02:00
parent dbd6bf0324
commit a1a17e81a1
332 changed files with 174509 additions and 1106 deletions
+434
View File
@@ -0,0 +1,434 @@
#!/bin/bash
################################################################################
# Script Name: process-metrics-exporter.sh
# Version: 1.0
# Description: Prometheus exporter for system process metrics. Collects CPU,
# memory, virtual memory per process, process state distribution,
# system load averages, TCP connection states, top resource
# consumers, file handles by program, and network connections.
#
# Author: Phil Connor
# Contact: contact@mylinux.work
# Website: https://mylinux.work
# License: MIT
#
# Prerequisites:
# - ps, awk, bc, lsof, ss (or netstat)
# - netcat (nc) for HTTP mode
#
# Usage:
# ./process-metrics-exporter.sh # stdout
# ./process-metrics-exporter.sh --textfile # node_exporter textfile
# ./process-metrics-exporter.sh --http # HTTP server on port 9200
#
# Metrics Exported:
# Per-Process:
# - node_cpu_usage{process,pid,owner,state} - CPU % per process
# - node_memory_usage_bytes{process,pid,owner} - RSS memory per process
# - node_virtual_memory_bytes{process,pid,owner} - Virtual memory per process
#
# System:
# - node_process_state_total{state} - Process count by state
# - node_system_load{period} - Load averages (1m,5m,15m)
# - node_network_connection_state{state} - TCP connections by state
#
# Top Consumers:
# - node_top_cpu_consumer{rank,process,pid} - Top 10 CPU processes
# - node_top_memory_consumer{rank,process,pid} - Top 10 memory processes
#
# File Handles:
# - node_file_handles_by_program{program} - Open files per program
# - node_file_handle_connection{fd,command,...} - Network connections by process
# - node_file_handles_open - System open file handles
# - node_file_handles_allocated - Allocated file handles
# - node_file_handles_max - Maximum file handle limit
#
# Exporter:
# - node_process_metrics_up - Exporter status (1=up)
# - node_process_metrics_duration_seconds - Script execution time
# - node_process_metrics_last_run_timestamp - Last run timestamp
#
# Configuration:
# Default HTTP port: 9200
# Textfile directory: /var/lib/node_exporter
#
################################################################################
set -uo pipefail
# ============================================================================
# CONFIGURATION
# ============================================================================
TEXTFILE_DIR="/var/lib/node_exporter"
OUTPUT_FILE=""
HTTP_MODE=false
HTTP_PORT=9200
PROCESS_LIMIT=1000
FILE_HANDLER_LIMIT=1000
FHCONN_LIMIT=50
# ============================================================================
# USAGE
# ============================================================================
show_usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
Export system process metrics as Prometheus metrics.
MODES:
--textfile Write to node_exporter textfile collector
--http Run HTTP server on port ${HTTP_PORT}
(default) Print metrics to stdout
OPTIONS:
-p, --port N HTTP port (default: ${HTTP_PORT})
-o, --output F Output file path
-h, --help Show this help
EXAMPLES:
$(basename "$0") --textfile
$(basename "$0") --http --port 9200
$(basename "$0") -o /tmp/process_metrics.prom
EOF
exit 0
}
# ============================================================================
# ARGUMENT PARSING
# ============================================================================
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) show_usage ;;
--textfile) OUTPUT_FILE="${TEXTFILE_DIR}/process_metrics.prom"; shift ;;
--http) HTTP_MODE=true; shift ;;
-p|--port) HTTP_PORT="$2"; shift 2 ;;
-o|--output) OUTPUT_FILE="$2"; shift 2 ;;
*) echo "# ERROR: Unknown option: $1" >&2; show_usage ;;
esac
done
}
# ============================================================================
# PREFLIGHT
# ============================================================================
preflight() {
local missing=()
for cmd in ps awk bc lsof; do
command -v "$cmd" &>/dev/null || missing+=("$cmd")
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "# ERROR: Missing required commands: ${missing[*]}" >&2
exit 1
fi
if ! command -v ss &>/dev/null && ! command -v netstat &>/dev/null; then
echo "# WARN: Neither ss nor netstat found — network metrics unavailable" >&2
fi
}
# ============================================================================
# METRICS COLLECTION
# ============================================================================
collect_metrics() {
local start_time
start_time=$(date +%s%N)
local now
now=$(date +%s)
echo "# HELP node_process_metrics_up Exporter status (1=up)"
echo "# TYPE node_process_metrics_up gauge"
echo "node_process_metrics_up 1"
echo ""
# --- Per-process CPU, memory, virtual memory (single-pass awk) ---
local ps_output
ps_output=$(ps -eo pid,ppid,user,pcpu,rss,vsz,stat,comm --no-headers -ww 2>/dev/null) || true
if [[ -n "$ps_output" ]]; then
echo "$ps_output" | awk -v limit="$PROCESS_LIMIT" '
{
if (NF < 8 || NR > limit) next
if ($1 !~ /^[0-9]+$/ || $4 !~ /^[0-9]+\.?[0-9]*$/) next
if ($5 !~ /^[0-9]+$/ || $6 !~ /^[0-9]+$/) next
gsub(/[^a-zA-Z0-9_:-]/, "_", $8); gsub(/_+/, "_", $8)
gsub(/[^a-zA-Z0-9_:-]/, "_", $3); gsub(/_+/, "_", $3)
gsub(/[^a-zA-Z0-9_:-]/, "_", $7); gsub(/_+/, "_", $7)
cpu[NR] = sprintf("node_cpu_usage{process=\"%s\",pid=\"%s\",owner=\"%s\",state=\"%s\"} %s", $8, $1, $3, $7, $4)
mem[NR] = sprintf("node_memory_usage_bytes{process=\"%s\",pid=\"%s\",owner=\"%s\"} %d", $8, $1, $3, $5 * 1024)
vmem[NR] = sprintf("node_virtual_memory_bytes{process=\"%s\",pid=\"%s\",owner=\"%s\"} %d", $8, $1, $3, $6 * 1024)
}
END {
print "# HELP node_cpu_usage CPU usage by process"
print "# TYPE node_cpu_usage gauge"
for (i in cpu) print cpu[i]
print ""
print "# HELP node_memory_usage_bytes Physical memory (RSS) by process in bytes"
print "# TYPE node_memory_usage_bytes gauge"
for (i in mem) print mem[i]
print ""
print "# HELP node_virtual_memory_bytes Virtual memory by process in bytes"
print "# TYPE node_virtual_memory_bytes gauge"
for (i in vmem) print vmem[i]
print ""
}'
fi
# --- Process state distribution ---
local stat_output
stat_output=$(ps -eo stat --no-headers 2>/dev/null) || true
if [[ -n "$stat_output" ]]; then
echo "# HELP node_process_state_total Process count by state"
echo "# TYPE node_process_state_total gauge"
echo "$stat_output" | awk '
{
s = substr($1, 1, 1)
count[s]++
}
END {
for (s in count) {
if (s == "R") name = "running"
else if (s == "S") name = "sleeping"
else if (s == "D") name = "uninterruptible_sleep"
else if (s == "Z") name = "zombie"
else if (s == "T") name = "stopped"
else if (s == "I") name = "idle"
else name = "other"
printf "node_process_state_total{state=\"%s\"} %d\n", name, count[s]
}
}'
echo ""
fi
# --- System load averages ---
if [[ -r /proc/loadavg ]]; then
echo "# HELP node_system_load System load averages"
echo "# TYPE node_system_load gauge"
awk '{
printf "node_system_load{period=\"1m\"} %s\n", $1
printf "node_system_load{period=\"5m\"} %s\n", $2
printf "node_system_load{period=\"15m\"} %s\n", $3
}' /proc/loadavg
echo ""
fi
# --- TCP connection states ---
local net_output=""
if command -v ss &>/dev/null; then
net_output=$(ss -nt 2>/dev/null) || true
elif command -v netstat &>/dev/null; then
net_output=$(netstat -nt 2>/dev/null) || true
fi
if [[ -n "$net_output" ]]; then
echo "# HELP node_network_connection_state TCP connections by state"
echo "# TYPE node_network_connection_state gauge"
echo "$net_output" | awk '
/^tcp/ || /^ESTAB/ || /^CLOSE/ || /^TIME/ || /^LISTEN/ || /^SYN/ || /^FIN/ || /^LAST/ {
state = $1
if ($1 ~ /^tcp/) state = $NF
count[state]++
}
END {
for (s in count)
printf "node_network_connection_state{state=\"%s\"} %d\n", s, count[s]
}'
echo ""
fi
# --- Top 10 CPU and memory consumers ---
if [[ -n "$ps_output" ]]; then
local top_cpu top_mem
top_cpu=$(echo "$ps_output" | sort -k4 -nr | head -10)
top_mem=$(echo "$ps_output" | sort -k5 -nr | head -10)
echo "# HELP node_top_cpu_consumer Top 10 CPU consuming processes"
echo "# TYPE node_top_cpu_consumer gauge"
echo "$top_cpu" | awk '
{
gsub(/[^a-zA-Z0-9_:-]/, "_", $8); gsub(/_+/, "_", $8)
gsub(/[^a-zA-Z0-9_:-]/, "_", $3); gsub(/_+/, "_", $3)
printf "node_top_cpu_consumer{rank=\"%d\",process=\"%s\",pid=\"%s\",owner=\"%s\"} %s\n", NR, $8, $1, $3, $4
}'
echo ""
echo "# HELP node_top_memory_consumer Top 10 memory consuming processes (bytes)"
echo "# TYPE node_top_memory_consumer gauge"
echo "$top_mem" | awk '
{
gsub(/[^a-zA-Z0-9_:-]/, "_", $8); gsub(/_+/, "_", $8)
gsub(/[^a-zA-Z0-9_:-]/, "_", $3); gsub(/_+/, "_", $3)
printf "node_top_memory_consumer{rank=\"%d\",process=\"%s\",pid=\"%s\",owner=\"%s\"} %d\n", NR, $8, $1, $3, $5 * 1024
}'
echo ""
fi
# --- File handles by program ---
local lsof_output
lsof_output=$(timeout 60 lsof 2>/dev/null) || true
if [[ -n "$lsof_output" ]]; then
echo "# HELP node_file_handles_by_program Open file handles by program"
echo "# TYPE node_file_handles_by_program gauge"
echo "$lsof_output" | awk -v limit="$FILE_HANDLER_LIMIT" '
/COMMAND/ { next }
NR > limit { exit }
{
if (NF >= 5 && $1 != "" && $2 ~ /^[0-9]+$/) {
gsub(/[^a-zA-Z0-9_:-]/, "_", $1)
gsub(/_+/, "_", $1)
count[$1]++
}
}
END {
for (cmd in count)
if (count[cmd] > 0)
printf "node_file_handles_by_program{program=\"%s\"} %d\n", cmd, count[cmd]
}'
echo ""
fi
# --- File handle connections (network, deduplicated) ---
local conn_output
conn_output=$(timeout 60 lsof -i 2>/dev/null | head -"$FHCONN_LIMIT") || true
if [[ -n "$conn_output" ]]; then
echo "# HELP node_file_handle_connection Network connections by process"
echo "# TYPE node_file_handle_connection gauge"
echo "$conn_output" | awk -v limit="$FHCONN_LIMIT" '
NR == 1 { next }
NR > limit + 1 { exit }
{
if (NF < 9) next
gsub(/[\\]/, "_", $1); gsub(/[*:]/, "_", $2); gsub(/US\\/, "", $3); gsub(/[*:\\]/, "_", $9)
gsub(/["\n\r\t\\]/, "_", $1); gsub(/["\n\r\t\\]/, "_", $3)
gsub(/["\n\r\t\\]/, "_", $4); gsub(/["\n\r\t\\]/, "_", $5)
gsub(/["\n\r\t\\]/, "_", $8); gsub(/["\n\r\t\\]/, "_", $9)
key = $4 $1 $9 $3 $5 $8
if (!(key in seen)) {
seen[key] = 1
printf "node_file_handle_connection{fd=\"%s\",command=\"%s\",connection=\"%s\",user=\"%s\",protocol=\"%s\",type=\"%s\"} %s\n", $4, $1, $9, $3, $5, $8, $2
}
}' | sort -u
echo ""
fi
# --- System-wide file handle stats ---
if [[ -r /proc/sys/fs/file-nr ]]; then
local file_nr
file_nr=$(< /proc/sys/fs/file-nr)
if [[ "$file_nr" =~ ^[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+$ ]]; then
local fh_open fh_alloc fh_max
read -r fh_open fh_alloc fh_max <<< "$file_nr"
echo "# HELP node_file_handles_open Currently open file handles"
echo "# TYPE node_file_handles_open gauge"
echo "node_file_handles_open ${fh_open}"
echo ""
echo "# HELP node_file_handles_allocated Allocated file handles"
echo "# TYPE node_file_handles_allocated gauge"
echo "node_file_handles_allocated ${fh_alloc}"
echo ""
echo "# HELP node_file_handles_max Maximum file handle limit"
echo "# TYPE node_file_handles_max gauge"
echo "node_file_handles_max ${fh_max}"
echo ""
fi
fi
# --- Exporter metadata ---
local end_time duration
end_time=$(date +%s%N)
duration=$(echo "scale=3; ($end_time - $start_time) / 1000000000" | bc 2>/dev/null || echo "0")
echo "# HELP node_process_metrics_duration_seconds Script execution time"
echo "# TYPE node_process_metrics_duration_seconds gauge"
echo "node_process_metrics_duration_seconds ${duration}"
echo ""
echo "# HELP node_process_metrics_last_run_timestamp Last successful run (unix timestamp)"
echo "# TYPE node_process_metrics_last_run_timestamp gauge"
echo "node_process_metrics_last_run_timestamp ${now}"
}
# ============================================================================
# OUTPUT HANDLING
# ============================================================================
output_metrics() {
local metrics
metrics=$(collect_metrics)
if [[ -n "$OUTPUT_FILE" ]]; then
local output_dir
output_dir="$(dirname "$OUTPUT_FILE")"
mkdir -p "$output_dir"
local temp_file
temp_file=$(mktemp "${output_dir}/.process_metrics.XXXXXX")
echo "$metrics" > "$temp_file"
local file_lines
file_lines=$(wc -l < "$temp_file" 2>/dev/null || echo 0)
if [[ "$file_lines" -lt 10 ]]; then
rm -f "$temp_file"
echo "# ERROR: Metrics file too small (${file_lines} lines), keeping previous" >&2
exit 1
fi
chmod 644 "$temp_file"
mv -f "$temp_file" "$OUTPUT_FILE"
echo "# Metrics written to ${OUTPUT_FILE} (${file_lines} lines)" >&2
else
echo "$metrics"
fi
}
serve_http() {
echo "# Starting HTTP server on port ${HTTP_PORT}" >&2
echo "# Metrics endpoint: http://localhost:${HTTP_PORT}/metrics" >&2
if ! command -v nc &>/dev/null && ! command -v ncat &>/dev/null; then
echo "# ERROR: netcat (nc/ncat) required for HTTP mode" >&2
exit 1
fi
local nc_cmd="nc"
command -v ncat &>/dev/null && nc_cmd="ncat"
while true; do
local metrics
metrics=$(collect_metrics)
local content_length=${#metrics}
local response="HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: ${content_length}\r\nConnection: close\r\n\r\n${metrics}"
echo -e "$response" | $nc_cmd -l -p "$HTTP_PORT" -q 1 2>/dev/null || \
echo -e "$response" | $nc_cmd -l "$HTTP_PORT" 2>/dev/null || true
done
}
# ============================================================================
# MAIN
# ============================================================================
parse_args "$@"
preflight
if [[ "$HTTP_MODE" == "true" ]]; then
serve_http
else
output_metrics
fi