#!/usr/bin/env bash ensure() { command -v "$1" >/dev/null 2>&1 || { echo >&2 "$1 not found, abort..."; exit 1; } } safecat() { [ -f "$1" ] && [ -r "$1" ] && cat "$1" } safecatroot() { [ $(id -u) -eq 0 ] && safecat $@ } safecmd() { command -v "$1" >/dev/null 2>&1 && $@ } safecmdroot() { [ $(id -u) -eq 0 ] && safecmd $@ } dump() { [ -z "$2" ] && return entry=$1 shift value=$($@ 2>&1|base64 -w 0) [ "$USE_COMMA" -eq 1 ] && echo "\"${entry}\": \"${value}\"," [ "$USE_COMMA" -eq 0 ] && echo "\"${entry}\": \"${value}\"" } cleandump() { newdump=$(mktemp) cat "$1" | awk 'BEGIN{STARTED=0} /#!#!#!#! SYSDUMP START HERE #!#!#!#/{STARTED=1};/#!#!#!#! SYSDUMP END HERE #!#!#!#/{STARTED=0};!/#!#!#!#! SYSDUMP START HERE #!#!#!#/{if(STARTED){print $0}}' > "$newdump" mv "$newdump" "$1" } sysdump() { echo "#!#!#!#! SYSDUMP START HERE #!#!#!#" # Start dump echo "{" USE_COMMA=1 # safecat dump "/etc/nftables.conf" safecat /etc/nftables.conf dump "/etc/group" safecat /etc/group dump "$HOME/.bashrc" safecat $HOME/.bashrc dump "$HOME/.bash_profile" safecat $HOME/.bash_profile dump "/etc/fstab" safecat /etc/fstab dump "/etc/ssh/sshd_config" safecat /etc/ssh/sshd_config dump "/proc/cpuinfo" safecat /proc/cpuinfo dump "/etc/os-release" safecat /etc/os-release dump "/proc/zoneinfo" safecat /proc/zoneinfo dump "/proc/meminfo" safecat /proc/meminfo dump "/proc/cmdline" safecat /proc/cmdline dump "/proc/version" safecat /proc/version dump "/etc/resolv.conf" safecat /etc/resolv.conf dump "/etc/sysctl.conf" safecat /etc/sysctl.conf dump "/etc/apt/sources.list" safecat /etc/apt/sources.list dump "/etc/hosts" safecat /etc/hosts dump "/etc/bash.bashrc" safecat /etc/bash.bashrc dump "/etc/timezone" safecat /etc/timezone dump "/boot/config-$(uname -r)" safecat /boot/config-$(uname -r) # safecatroot dump "/etc/shadow" safecatroot /etc/shadow dump "/etc/sudoers" safecatroot /etc/sudoers # safecmd dump "date" date +%s dump "hostname" safecmd hostname dump "id" safecmd id dump "env" safecmd env dump "top" safecmd top -b -n 1 dump "locale" safecmd locale dump "systemctl" safecmd systemctl --no-pager dump "free" safecmd free -h dump "df" safecmd df -h dump "boot_folder" safecmd ls -R /boot/ dump "home_folder" safecmd ls -al ${HOME} dump "root_folder" safecmd ls -al / dump "uid" safecmd id -u dump "gid" safecmd id -g dump "gids" safecmd id -G dump "ipaddr" safecmd ip addr dump "uname" safecmd uname -a dump "lsb_release" safecmd lsb_release dump "uptime" safecmd uptime dump "mount" safecmd mount dump "lscpu" safecmd lscpu dump "lsblk" safecmd lsblk dump "lsusb" safecmd lsusb dump "lsmod" safecmd lsmod dump "lspci" safecmd lspci dump "lsirq" safecmd lsirq dump "lsfd" safecmd lsfd dump "glxinfo" safecmd glxinfo -B dump "compgen" safecmd compgen -c dump "openssl" safecmd openssl dump "users" safecmd users dump "declare" safecmd declare dump "ping" safecmd ping -c 2 -W 2 4.2.2.2 # dump versions for cmd in bash gcc ld python3 cmake make tar zip gzip bzip2 xz cpio wget rsync curl node pip apt cat systemctl gpg R ruby awk grep sshfs docker java do dump "cmd_${cmd}_version" safecmd $cmd --version done dump "cmd_ssh_version" safecmd sshd -V dump "cmd_tmux_version" safecmd tmux -V dump "cmd_nginx_version" safecmd nginx -v dump "cmd_go_version" safecmd go version # safecmdroot dump "dmidecode" safecmdroot dmidecode dump "iptables" safecmdroot iptables -L dump "fdisk" safecmdroot fdisk -l USE_COMMA=0 dump "dmesg" safecmdroot dmesg echo "}" echo "#!#!#!#! SYSDUMP END HERE #!#!#!#" } # Parse arguments POSITIONAL_ARGS=() ACTION="dump" while [[ $# -gt 0 ]]; do case $1 in -l|--list-entries) ACTION="list" shift ;; -s|--summarize) ACTION="summarize" shift # past value ;; -p|--parse) ACTION="parse" shift # past value ;; -h|--help) echo "Usage: $0 [OPTION] [DUMP_FILE] [ENTRIES]" echo " -l, --list-entries: Show available entries from a dump file" echo " -p, --parse: Parse the content of a dump file" echo " Example 1: $0 -p dump.json" echo " Example 2: $0 -p dump.json uname uptime" echo " -s, --summarize: Summarize a dump file" echo " -h, --help: Show this help" exit 0 ;; -*|--*) echo "Unknown option $1" exit 1 ;; *) POSITIONAL_ARGS+=("$1") # save positional arg shift # past argument ;; esac done set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters # Check requirements ensure base64 [ "$ACTION" == "dump" ] && [ $# -ne 0 ] && { echo "I do not understand the following: $@"; exit 1; } [ "$ACTION" != "dump" ] && [ $# -eq 0 ] && { echo "Missing dump file path"; exit 1; } [ "$ACTION" != "dump" ] && [ ! -f "$1" ] && { echo "File \"$1\" not found"; exit 1; } # Do dump [ "$ACTION" == "dump" ] && { sysdump; exit 0; } [ $(grep -c '#!#!#!#! SYSDUMP START HERE #!#!#!#' "$1") -ne 0 ] && cleandump "$1" # List entries [ "$ACTION" == "list" ] && { ensure jq; cat "$1"|jq -r "keys[]"; exit 0; } # Parse dump file if [ "$ACTION" == "parse" ] then ensure jq file=$1 if [ $# -gt 1 ] then shift for entry in $@ do echo "====================> $entry" cat "$file"|jq -r ".[\"${entry}\"]"|base64 -d done exit 0 fi while IFS= read -r entry; do echo "====================> $entry" cat "$file"|jq -r ".[\"${entry}\"]"|base64 -d done <<< "$(cat "$file"|jq -r 'keys[]')" exit 0 fi # Summarize dump file if [ "$ACTION" == "summarize" ] then ensure jq file=$1 OS_RELEASE=$(cat "$file"|jq -r '.["/etc/os-release"]'|base64 -d) CPU_INFO=$(cat "$file"|jq -r '.["/proc/cpuinfo"]'|base64 -d) PING_SUCCESS_COUNT=$(cat "$file"|jq -r '.["ping"]'|base64 -d|grep "packet loss"|cut -d, -f 2|awk '{print $1+0}') # Extract infos INFO_OS_NAME=$(echo "$OS_RELEASE"|grep "^NAME=" | cut -d'"' -f 2) INFO_OS_VERSION=$(echo "$OS_RELEASE"|grep "^VERSION=" | cut -d'"' -f 2) INFO_HOSTNAME=$(cat "$file"|jq -r '.["hostname"]'|base64 -d) INFO_CPU_MODEL=$(echo "$CPU_INFO"|grep "model name" | cut -d':' -f 2|uniq|awk '{$1=$1};1') INFO_CPU_CORE_N_PHY=$(echo "$CPU_INFO"|grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') INFO_CPU_CORE_N_VIRT=$(echo "$CPU_INFO"|grep -c ^processor /proc/cpuinfo) [ "$INFO_CPU_CORE_N_PHY" -eq "$INFO_CPU_CORE_N_VIRT" ] && INFO_CPU_HYPERTHREADING="off" || INFO_CPU_HYPERTHREADING="on" [ $PING_SUCCESS_COUNT -gt 0 ] && INFO_OTHER_NETWORK="on" || INFO_OTHER_NETWORK="off" INFO_INET4=$(cat "$file"|jq -r '.["ipaddr"]'|base64 -d|awk '/inet /{printf $2", "}'| sed 's/..$//') INFO_INET6=$(cat "$file"|jq -r '.["ipaddr"]'|base64 -d|awk '/inet6 /{printf $2", "}'| sed 's/..$//') # Print Information echo "====> System <====" echo "OS Name: ${INFO_OS_NAME}" echo "OS Version: ${INFO_OS_VERSION}" echo "Hostname: ${INFO_HOSTNAME}" echo echo "====> CPU <====" echo "Model: ${INFO_CPU_MODEL}" echo "Physical Core Count: ${INFO_CPU_CORE_N_PHY}" echo "Logical Core Count: ${INFO_CPU_CORE_N_VIRT}" echo "HyperThreading State: ${INFO_CPU_HYPERTHREADING}" echo echo "====> Other informations <====" echo "Network State: ${INFO_OTHER_NETWORK}" echo "IPv4: ${INFO_INET4}" echo "IPv6: ${INFO_INET6}" fi