chore: git cache cleanup
This commit is contained in:
461
scripts/diagnose-crowdsec.sh
Executable file
461
scripts/diagnose-crowdsec.sh
Executable file
@@ -0,0 +1,461 @@
|
||||
#!/usr/bin/env bash
|
||||
# diagnose-crowdsec.sh - CrowdSec Connectivity and Enrollment Diagnostics
|
||||
# Usage: ./diagnose-crowdsec.sh [--json] [--data-dir /path/to/crowdsec]
|
||||
# shellcheck disable=SC2312
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Default configuration
|
||||
DATA_DIR="${CROWDSEC_DATA_DIR:-/var/lib/crowdsec}"
|
||||
JSON_OUTPUT=false
|
||||
LAPI_PORT="${CROWDSEC_LAPI_PORT:-8085}"
|
||||
|
||||
# Colors for terminal output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--json)
|
||||
JSON_OUTPUT=true
|
||||
shift
|
||||
;;
|
||||
--data-dir)
|
||||
DATA_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--lapi-port)
|
||||
LAPI_PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: $0 [--json] [--data-dir /path/to/crowdsec] [--lapi-port 8085]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --json Output results as JSON"
|
||||
echo " --data-dir CrowdSec data directory (default: /var/lib/crowdsec)"
|
||||
echo " --lapi-port LAPI port (default: 8085)"
|
||||
echo " -h, --help Show this help message"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Results storage
|
||||
declare -A RESULTS
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
if [[ "$JSON_OUTPUT" == "false" ]]; then
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
if [[ "$JSON_OUTPUT" == "false" ]]; then
|
||||
echo -e "${GREEN}[PASS]${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
if [[ "$JSON_OUTPUT" == "false" ]]; then
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_error() {
|
||||
if [[ "$JSON_OUTPUT" == "false" ]]; then
|
||||
echo -e "${RED}[FAIL]${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if command exists
|
||||
check_command() {
|
||||
command -v "$1" &>/dev/null
|
||||
}
|
||||
|
||||
# 1. Check LAPI process running
|
||||
check_lapi_running() {
|
||||
log_info "Checking if CrowdSec LAPI is running..."
|
||||
|
||||
if pgrep -x "crowdsec" &>/dev/null; then
|
||||
local pid
|
||||
pid=$(pgrep -x "crowdsec" | head -1)
|
||||
RESULTS["lapi_running"]="true"
|
||||
RESULTS["lapi_pid"]="$pid"
|
||||
log_success "CrowdSec LAPI is running (PID: $pid)"
|
||||
return 0
|
||||
else
|
||||
RESULTS["lapi_running"]="false"
|
||||
RESULTS["lapi_pid"]=""
|
||||
log_error "CrowdSec LAPI is NOT running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 2. Check LAPI responding
|
||||
check_lapi_health() {
|
||||
log_info "Checking LAPI health endpoint..."
|
||||
|
||||
local health_url="http://127.0.0.1:${LAPI_PORT}/health"
|
||||
local response
|
||||
|
||||
if response=$(curl -s --connect-timeout 5 --max-time 10 "$health_url" 2>/dev/null); then
|
||||
RESULTS["lapi_healthy"]="true"
|
||||
RESULTS["lapi_health_response"]="$response"
|
||||
log_success "LAPI health endpoint responding at $health_url"
|
||||
return 0
|
||||
else
|
||||
RESULTS["lapi_healthy"]="false"
|
||||
RESULTS["lapi_health_response"]=""
|
||||
log_error "LAPI health endpoint not responding at $health_url"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 3. Check cscli available
|
||||
check_cscli() {
|
||||
log_info "Checking cscli availability..."
|
||||
|
||||
if check_command cscli; then
|
||||
local version
|
||||
version=$(cscli version 2>/dev/null | head -1 || echo "unknown")
|
||||
RESULTS["cscli_available"]="true"
|
||||
RESULTS["cscli_version"]="$version"
|
||||
log_success "cscli is available: $version"
|
||||
return 0
|
||||
else
|
||||
RESULTS["cscli_available"]="false"
|
||||
RESULTS["cscli_version"]=""
|
||||
log_error "cscli command not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 4. Check CAPI registration
|
||||
check_capi_registered() {
|
||||
log_info "Checking CAPI registration..."
|
||||
|
||||
local creds_path="${DATA_DIR}/config/online_api_credentials.yaml"
|
||||
if [[ ! -f "$creds_path" ]]; then
|
||||
creds_path="${DATA_DIR}/online_api_credentials.yaml"
|
||||
fi
|
||||
|
||||
if [[ -f "$creds_path" ]]; then
|
||||
RESULTS["capi_registered"]="true"
|
||||
RESULTS["capi_creds_path"]="$creds_path"
|
||||
log_success "CAPI credentials found at $creds_path"
|
||||
return 0
|
||||
else
|
||||
RESULTS["capi_registered"]="false"
|
||||
RESULTS["capi_creds_path"]=""
|
||||
log_error "CAPI credentials not found (checked ${DATA_DIR}/config/online_api_credentials.yaml)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 5. Check CAPI connectivity
|
||||
check_capi_connectivity() {
|
||||
log_info "Checking CAPI connectivity..."
|
||||
|
||||
if ! check_command cscli; then
|
||||
RESULTS["capi_reachable"]="unknown"
|
||||
log_warning "Cannot check CAPI connectivity - cscli not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local config_path="${DATA_DIR}/config/config.yaml"
|
||||
if [[ ! -f "$config_path" ]]; then
|
||||
config_path="${DATA_DIR}/config.yaml"
|
||||
fi
|
||||
|
||||
local cscli_args=("capi" "status")
|
||||
if [[ -f "$config_path" ]]; then
|
||||
cscli_args=("-c" "$config_path" "capi" "status")
|
||||
fi
|
||||
|
||||
local output
|
||||
if output=$(timeout 10s cscli "${cscli_args[@]}" 2>&1); then
|
||||
RESULTS["capi_reachable"]="true"
|
||||
RESULTS["capi_status"]="$output"
|
||||
log_success "CAPI is reachable"
|
||||
return 0
|
||||
else
|
||||
RESULTS["capi_reachable"]="false"
|
||||
RESULTS["capi_status"]="$output"
|
||||
log_error "CAPI is not reachable: $output"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 6. Check Console API reachability
|
||||
check_console_api() {
|
||||
log_info "Checking CrowdSec Console API reachability..."
|
||||
|
||||
local console_url="https://api.crowdsec.net/health"
|
||||
local http_code
|
||||
|
||||
http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 "$console_url" 2>/dev/null || echo "000")
|
||||
|
||||
if [[ "$http_code" == "200" ]] || [[ "$http_code" == "204" ]]; then
|
||||
RESULTS["console_reachable"]="true"
|
||||
RESULTS["console_http_code"]="$http_code"
|
||||
log_success "Console API is reachable (HTTP $http_code)"
|
||||
return 0
|
||||
else
|
||||
RESULTS["console_reachable"]="false"
|
||||
RESULTS["console_http_code"]="$http_code"
|
||||
log_error "Console API is not reachable (HTTP $http_code)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 7. Check Console enrollment status
|
||||
check_console_enrolled() {
|
||||
log_info "Checking Console enrollment status..."
|
||||
|
||||
if ! check_command cscli; then
|
||||
RESULTS["console_enrolled"]="unknown"
|
||||
log_warning "Cannot check enrollment - cscli not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local config_path="${DATA_DIR}/config/config.yaml"
|
||||
if [[ ! -f "$config_path" ]]; then
|
||||
config_path="${DATA_DIR}/config.yaml"
|
||||
fi
|
||||
|
||||
local cscli_args=("console" "status")
|
||||
if [[ -f "$config_path" ]]; then
|
||||
cscli_args=("-c" "$config_path" "console" "status")
|
||||
fi
|
||||
|
||||
local output
|
||||
if output=$(timeout 10s cscli "${cscli_args[@]}" 2>&1); then
|
||||
if echo "$output" | grep -qi "enrolled"; then
|
||||
RESULTS["console_enrolled"]="true"
|
||||
RESULTS["console_enrollment_output"]="$output"
|
||||
log_success "Console is enrolled"
|
||||
return 0
|
||||
else
|
||||
RESULTS["console_enrolled"]="false"
|
||||
RESULTS["console_enrollment_output"]="$output"
|
||||
log_warning "Console enrollment status unclear: $output"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
RESULTS["console_enrolled"]="false"
|
||||
RESULTS["console_enrollment_output"]="$output"
|
||||
log_error "Failed to check console status: $output"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 8. Check config.yaml
|
||||
check_config_yaml() {
|
||||
log_info "Checking config.yaml..."
|
||||
|
||||
local config_path="${DATA_DIR}/config/config.yaml"
|
||||
if [[ ! -f "$config_path" ]]; then
|
||||
config_path="${DATA_DIR}/config.yaml"
|
||||
fi
|
||||
|
||||
if [[ -f "$config_path" ]]; then
|
||||
RESULTS["config_exists"]="true"
|
||||
RESULTS["config_path"]="$config_path"
|
||||
log_success "config.yaml found at $config_path"
|
||||
|
||||
# Try to validate
|
||||
if check_command cscli; then
|
||||
if timeout 10s cscli -c "$config_path" config check &>/dev/null; then
|
||||
RESULTS["config_valid"]="true"
|
||||
log_success "config.yaml is valid"
|
||||
else
|
||||
RESULTS["config_valid"]="false"
|
||||
log_error "config.yaml validation failed"
|
||||
fi
|
||||
else
|
||||
RESULTS["config_valid"]="unknown"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
RESULTS["config_exists"]="false"
|
||||
RESULTS["config_valid"]="false"
|
||||
log_error "config.yaml not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 9. Check acquis.yaml
|
||||
check_acquis_yaml() {
|
||||
log_info "Checking acquis.yaml..."
|
||||
|
||||
local acquis_path="${DATA_DIR}/config/acquis.yaml"
|
||||
if [[ ! -f "$acquis_path" ]]; then
|
||||
acquis_path="${DATA_DIR}/acquis.yaml"
|
||||
fi
|
||||
|
||||
if [[ -f "$acquis_path" ]]; then
|
||||
RESULTS["acquis_exists"]="true"
|
||||
RESULTS["acquis_path"]="$acquis_path"
|
||||
log_success "acquis.yaml found at $acquis_path"
|
||||
|
||||
# Check for datasources
|
||||
if grep -q "source:" "$acquis_path" && grep -qE "(filenames?:|journalctl)" "$acquis_path"; then
|
||||
RESULTS["acquis_valid"]="true"
|
||||
log_success "acquis.yaml has datasource configuration"
|
||||
else
|
||||
RESULTS["acquis_valid"]="false"
|
||||
log_warning "acquis.yaml may be missing datasource configuration"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
RESULTS["acquis_exists"]="false"
|
||||
RESULTS["acquis_valid"]="false"
|
||||
log_warning "acquis.yaml not found (optional for some setups)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 10. Check bouncers registered
|
||||
check_bouncers() {
|
||||
log_info "Checking registered bouncers..."
|
||||
|
||||
if ! check_command cscli; then
|
||||
RESULTS["bouncers_count"]="unknown"
|
||||
log_warning "Cannot check bouncers - cscli not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local config_path="${DATA_DIR}/config/config.yaml"
|
||||
if [[ ! -f "$config_path" ]]; then
|
||||
config_path="${DATA_DIR}/config.yaml"
|
||||
fi
|
||||
|
||||
local cscli_args=("bouncers" "list" "-o" "json")
|
||||
if [[ -f "$config_path" ]]; then
|
||||
cscli_args=("-c" "$config_path" "bouncers" "list" "-o" "json")
|
||||
fi
|
||||
|
||||
local output
|
||||
if output=$(timeout 10s cscli "${cscli_args[@]}" 2>/dev/null); then
|
||||
local count
|
||||
count=$(echo "$output" | jq 'length' 2>/dev/null || echo "0")
|
||||
RESULTS["bouncers_count"]="$count"
|
||||
RESULTS["bouncers_list"]="$output"
|
||||
if [[ "$count" -gt 0 ]]; then
|
||||
log_success "Found $count registered bouncer(s)"
|
||||
else
|
||||
log_warning "No bouncers registered"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
RESULTS["bouncers_count"]="0"
|
||||
log_error "Failed to list bouncers"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Output JSON results
|
||||
output_json() {
|
||||
echo "{"
|
||||
local first=true
|
||||
for key in "${!RESULTS[@]}"; do
|
||||
if [[ "$first" == "true" ]]; then
|
||||
first=false
|
||||
else
|
||||
echo ","
|
||||
fi
|
||||
local value="${RESULTS[$key]}"
|
||||
# Escape special characters for JSON
|
||||
value="${value//\\/\\\\}"
|
||||
value="${value//\"/\\\"}"
|
||||
value="${value//$'\n'/\\n}"
|
||||
value="${value//$'\r'/\\r}"
|
||||
value="${value//$'\t'/\\t}"
|
||||
printf ' "%s": "%s"' "$key" "$value"
|
||||
done
|
||||
echo ""
|
||||
echo "}"
|
||||
}
|
||||
|
||||
# Print summary
|
||||
print_summary() {
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " CrowdSec Diagnostic Summary"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
local passed=0
|
||||
local failed=0
|
||||
local warnings=0
|
||||
|
||||
for key in lapi_running lapi_healthy capi_registered capi_reachable console_reachable console_enrolled config_exists config_valid; do
|
||||
case "${RESULTS[$key]:-unknown}" in
|
||||
true) ((passed++)) ;;
|
||||
false) ((failed++)) ;;
|
||||
*) ((warnings++)) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -e "Checks passed: ${GREEN}$passed${NC}"
|
||||
echo -e "Checks failed: ${RED}$failed${NC}"
|
||||
echo -e "Checks unknown: ${YELLOW}$warnings${NC}"
|
||||
echo ""
|
||||
|
||||
if [[ "$failed" -gt 0 ]]; then
|
||||
echo -e "${RED}Some checks failed. See details above.${NC}"
|
||||
echo ""
|
||||
echo "Common solutions:"
|
||||
echo " - If LAPI not running: systemctl start crowdsec"
|
||||
echo " - If CAPI not registered: cscli capi register"
|
||||
echo " - If Console not enrolled: cscli console enroll <token>"
|
||||
echo " - If config missing: Check ${DATA_DIR}/config/"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}All critical checks passed!${NC}"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
if [[ "$JSON_OUTPUT" == "false" ]]; then
|
||||
echo "=========================================="
|
||||
echo " CrowdSec Diagnostic Tool v1.0"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Data directory: ${DATA_DIR}"
|
||||
echo "LAPI port: ${LAPI_PORT}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Run all checks (continue on failure)
|
||||
check_lapi_running || true
|
||||
check_lapi_health || true
|
||||
check_cscli || true
|
||||
check_capi_registered || true
|
||||
check_capi_connectivity || true
|
||||
check_console_api || true
|
||||
check_console_enrolled || true
|
||||
check_config_yaml || true
|
||||
check_acquis_yaml || true
|
||||
check_bouncers || true
|
||||
|
||||
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
||||
output_json
|
||||
else
|
||||
print_summary
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user