335 lines
11 KiB
Bash
Executable file
335 lines
11 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# The following can be update (use a complex delimiter)
|
|
DUMP_DELIMITER="#!#!#!#! SYSDUMP DELIMITER #!#!#!"
|
|
|
|
ensure() {
|
|
command -v "$1" >/dev/null 2>&1 || { echo >&2 "$1 not found, abort..."; exit 1; }
|
|
}
|
|
|
|
safecat() {
|
|
if [ -f "$1" ] && [ -r "$1" ]
|
|
then
|
|
cat "$1"
|
|
else
|
|
echo "File \"$1\" not found or not readable" >> "${LOG_FILE}"
|
|
fi
|
|
}
|
|
|
|
safecatroot() {
|
|
if [ $(id -u) -eq 0 ]
|
|
then
|
|
safecat $@
|
|
else
|
|
echo "File \"$1\" requires root permissions to be read" >> "${LOG_FILE}"
|
|
fi
|
|
}
|
|
|
|
safecmd() {
|
|
if command -v "$1" >/dev/null 2>&1
|
|
then
|
|
$@
|
|
else
|
|
echo "Command $@ not found" >> "${LOG_FILE}"
|
|
fi
|
|
}
|
|
|
|
safecmdroot() {
|
|
if [ $(id -u) -eq 0 ]
|
|
then
|
|
safecmd $@
|
|
else
|
|
echo "Root permissions required for $@" >> "${LOG_FILE}"
|
|
fi
|
|
}
|
|
|
|
safegetentry() {
|
|
[[ ${DUMP_ENTRIES} =~ $1 ]] && cat "${DUMP_FILE}"|jq -r ".[\"${1}\"]"|base64 -d
|
|
}
|
|
|
|
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};/'"${DUMP_DELIMITER}"'/{if(STARTED){STARTED=0}else{STARTED=1}};!/'"${DUMP_DELIMITER}"'/{if(STARTED){print $0}}' > "$newdump"
|
|
mv "$newdump" "$1"
|
|
}
|
|
|
|
sysdump() {
|
|
LOG_FILE=$(mktemp 2>/dev/null|echo "./sysdump.X9_8965252JHFHJGFJHGJHG")
|
|
echo "${DUMP_DELIMITER}"
|
|
# 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 "kernel_config" 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 "systemd-detect-virt" safecmd systemd-detect-virt
|
|
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 "lshw" safecmd lshw
|
|
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
|
|
dump "dmesg" safecmdroot dmesg
|
|
USE_COMMA=0
|
|
dump "dump_log" cat "${LOG_FILE}"
|
|
echo "}"
|
|
echo "${DUMP_DELIMITER}"
|
|
rm "${LOG_FILE}"
|
|
}
|
|
|
|
# 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; }
|
|
|
|
# Setting up dump file
|
|
ensure awk
|
|
ensure jq
|
|
[ $(grep -c "${DUMP_DELIMITER}" "$1") -ne 0 ] && cleandump "$1"
|
|
# Setup safegetentry
|
|
DUMP_FILE="$1"
|
|
DUMP_ENTRIES=$(cat "${DUMP_FILE}"|jq -r "keys[]";)
|
|
|
|
# List entries
|
|
[ "$ACTION" == "list" ] && { ensure jq; echo "$DUMP_ENTRIES"; exit 0; }
|
|
# Parse dump file
|
|
if [ "$ACTION" == "parse" ]
|
|
then
|
|
if [ $# -gt 1 ]
|
|
then
|
|
shift
|
|
for entry in $@
|
|
do
|
|
echo "====================> $entry"
|
|
safegetentry ${entry}
|
|
done
|
|
exit 0
|
|
fi
|
|
while IFS= read -r entry; do
|
|
echo "====================> $entry"
|
|
safegetentry ${entry}
|
|
done <<< "${DUMP_ENTRIES}"
|
|
exit 0
|
|
fi
|
|
# Summarize dump file
|
|
if [ "$ACTION" == "summarize" ]
|
|
then
|
|
OS_RELEASE=$(safegetentry /etc/os-release)
|
|
CPU_INFO=$(safegetentry /proc/cpuinfo)
|
|
MEM_INFO=$(safegetentry /proc/meminfo)
|
|
PING_SUCCESS_COUNT=$(safegetentry ping|grep "packet loss"|cut -d, -f 2|awk '{print $1+0}')
|
|
IPADDR=$(safegetentry ipaddr)
|
|
INFO_DISKS=$(safegetentry df)
|
|
KERNEL_CONFIG=$(safegetentry kernel_config)
|
|
LSHW=$(safegetentry lshw)
|
|
|
|
# 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=$(safegetentry hostname)
|
|
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="Available" || INFO_OTHER_NETWORK="Unreachable"
|
|
INFO_INET4=$(echo "$IPADDR"|awk '/inet /{printf $2", "}'| sed 's/..$//')
|
|
INFO_INET6=$(echo "$IPADDR"|awk '/inet6 /{printf $2", "}'| sed 's/..$//')
|
|
INFO_MEM_TOTAL=$(echo "$MEM_INFO"|awk '/MemTotal/{print $2/1000" MB"}')
|
|
INFO_MEM_FREE=$(echo "$MEM_INFO"|awk '/MemFree/{print $2/1000" MB"}')
|
|
INFO_MEM_SWAP_TOTAL=$(echo "$MEM_INFO"|awk '/SwapTotal/{print $2/1000" MB"}')
|
|
INFO_MEM_SWAP_FREE=$(echo "$MEM_INFO"|awk '/SwapFree/{print $2/1000" MB"}')
|
|
INFO_UPTIME=$(safegetentry uptime|cut -d, -f 1|awk '{$1=$1};1')
|
|
INFO_DUMP_DATE=$(safegetentry date) && INFO_DUMP_DATE=$(date -d "@${INFO_DUMP_DATE}")
|
|
INFO_DUMP_USER=$(safegetentry env|grep "^USER="|cut -d= -f2)
|
|
INFO_TIMEZONE=$(safegetentry /etc/timezone)
|
|
INFO_KERNEL=$(safegetentry /proc/version|awk '/ version /{print $1" v"$3}')
|
|
INFO_IS_VIRT=$(safegetentry systemd-detect-virt|awk 'BEGIN{state="No"};!/none/{state="Yes ("$0")"};END{print(state)}')
|
|
INFO_KERNEL_RAPL=$(echo "$KERNEL_CONFIG"|awk 'BEGIN{DETECTED=0};/^CONFIG_INTEL_RAPL=(y|m)/{DETECTED=1};END{if(DETECTED){print("Supported")}else{print("NA")}}')
|
|
INFO_KERNEL_KVM=$(echo "$KERNEL_CONFIG"|awk 'BEGIN{DETECTED=0};/^CONFIG_KVM=(y|m)/{DETECTED=1};END{if(DETECTED){print("Supported")}else{print("NA")}}')
|
|
INFO_KERNEL_I2C=$(echo "$KERNEL_CONFIG"|awk 'BEGIN{DETECTED=0};/^CONFIG_I2C=(y|m)/{DETECTED=1};END{if(DETECTED){print("Supported")}else{print("NA")}}')
|
|
INFO_KERNEL_SPI=$(echo "$KERNEL_CONFIG"|awk 'BEGIN{DETECTED=0};/^CONFIG_SPI=(y|m)/{DETECTED=1};END{if(DETECTED){print("Supported")}else{print("NA")}}')
|
|
INFO_HW_TYPE=$(echo "$LSHW"|grep -m 1 description| awk '{$1="";print($0)}'|awk '{$1=$1};1')
|
|
INFO_HW_VENDOR=$(echo "$LSHW"|grep -m 1 vendor| awk '{$1="";print($0)}'|awk '{$1=$1};1')
|
|
INFO_HW_VERSION=$(echo "$LSHW"|grep -m 1 version| awk '{$1="";print($0)}'|awk '{$1=$1};1')
|
|
INFO_HW_DISPLAY=$(echo "$LSHW"|grep "\-display" -A20|grep -m 1 product| awk '{$1="";print($0)}'|awk '{$1=$1};1')
|
|
|
|
# Print Information
|
|
echo "====> System <===="
|
|
echo "OS Name: ${INFO_OS_NAME}"
|
|
echo "OS Version: ${INFO_OS_VERSION}"
|
|
echo "Kernel: ${INFO_KERNEL}"
|
|
echo "Hostname: ${INFO_HOSTNAME}"
|
|
echo "Uptime: ${INFO_UPTIME}"
|
|
echo "Virtualization: ${INFO_IS_VIRT}"
|
|
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 "====> RAM <===="
|
|
echo "Total: ${INFO_MEM_TOTAL}"
|
|
echo "Free: ${INFO_MEM_FREE}"
|
|
echo "Swap Total: ${INFO_MEM_SWAP_TOTAL}"
|
|
echo "Swap Free: ${INFO_MEM_SWAP_FREE}"
|
|
echo
|
|
echo "====> Disk <===="
|
|
[ -z "$INFO_DISKS" ] && echo "ERROR: No disks informations (require df)"
|
|
if [ ! -z "$INFO_DISKS" ]
|
|
then
|
|
echo "${INFO_DISKS}"
|
|
fi
|
|
echo
|
|
echo "====> Kernel Config <===="
|
|
[ -z "$KERNEL_CONFIG" ] && echo "ERROR: Kernel config not found"
|
|
if [ ! -z "$KERNEL_CONFIG" ]
|
|
then
|
|
echo "Intel RAPL: ${INFO_KERNEL_RAPL}"
|
|
echo "KVM: ${INFO_KERNEL_KVM}"
|
|
echo "I2C: ${INFO_KERNEL_I2C}"
|
|
echo "SPI: ${INFO_KERNEL_SPI}"
|
|
fi
|
|
echo
|
|
echo "====> Applications <===="
|
|
echo "ssh: $(safegetentry cmd_ssh_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "rsync: $(safegetentry cmd_rsync_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "gcc: $(safegetentry cmd_gcc_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "python3: $(safegetentry cmd_python3_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "wget: $(safegetentry cmd_wget_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "curl: $(safegetentry cmd_curl_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo "tmux: $(safegetentry cmd_tmux_version|wc -c|awk '{if($0>0){print("Available")}else{print("NA")}}')"
|
|
echo
|
|
echo "====> Hardware <===="
|
|
[ -z "$LSHW" ] && echo "ERROR: Require lshw and root permissions"
|
|
if [ ! -z "$LSHW" ]
|
|
then
|
|
echo "Type: ${INFO_HW_TYPE}"
|
|
echo "Vendor: ${INFO_HW_VENDOR}"
|
|
echo "Version: ${INFO_HW_VERSION}"
|
|
echo "Display: ${INFO_HW_DISPLAY}"
|
|
fi
|
|
echo
|
|
echo "====> Other informations <===="
|
|
echo "Dump User: ${INFO_DUMP_USER}"
|
|
echo "Dump Date: ${INFO_DUMP_DATE}"
|
|
echo "Timezone: ${INFO_TIMEZONE}"
|
|
echo "Internet: ${INFO_OTHER_NETWORK}"
|
|
echo "IPv4: ${INFO_INET4}"
|
|
echo "IPv6: ${INFO_INET6}"
|
|
fi
|
|
|