dda32051ac
- cloudpanel: allow ftp, smtp, dns, http, https, smtps, imaps, pop3s, and admin panel ports - coolify: allow http, https, and dashboard port after install - pterodactyl: allow http, https, wings daemon (8080), and sftp (2022) ports - uptime-kuma: allow app port on install - proxmox: add open_firewall_ports() with ufw guard checks and new menu option [9]
334 lines
14 KiB
Bash
Executable File
334 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# LXS - System Tools
|
|
# Description: Essential system monitoring and diagnostic tools
|
|
# Author: LXS
|
|
# Date: 2025
|
|
|
|
# Load LXS common library (colors, separator, run_spinner, loggers)
|
|
LXS_RAW_BASE="${LXS_RAW_BASE:-https://git.hyko.cx/hykocx/lxs/raw/branch/main}"
|
|
_lib=$(curl -fsSL "${LXS_RAW_BASE}/lib/common.sh") || { echo "Failed to fetch lib/common.sh" >&2; exit 1; }
|
|
eval "$_lib"
|
|
unset _lib
|
|
export LXS_LOG_FILE="/tmp/lxs_system_tools.log"
|
|
|
|
# Run a sibling tool script. Prefers a file next to this script (installed
|
|
# layout); falls back to downloading from LXS_RAW_BASE.
|
|
run_sibling() {
|
|
local script_path=$1
|
|
shift
|
|
local script_name self_dir resolved src="${BASH_SOURCE[0]}"
|
|
script_name=$(basename "$script_path")
|
|
|
|
if [ -n "$src" ]; then
|
|
resolved=$(readlink -f "$src" 2>/dev/null) \
|
|
|| resolved=$(realpath "$src" 2>/dev/null) \
|
|
|| resolved="$src"
|
|
self_dir=$(dirname "$resolved")
|
|
fi
|
|
|
|
if [ -n "$self_dir" ] && [ -f "${self_dir}/${script_name}" ]; then
|
|
chmod +x "${self_dir}/${script_name}" 2>/dev/null || true
|
|
"${self_dir}/${script_name}" "$@"
|
|
return $?
|
|
fi
|
|
|
|
local temp_file exit_code
|
|
temp_file=$(mktemp "/tmp/lxs.${script_name%.*}.XXXXXX.sh")
|
|
echo -e "${PURPLE}[*] Downloading ${BOLD}${script_name}${NC}${PURPLE}...${NC}"
|
|
if curl -fsSL -H "Cache-Control: no-cache" -o "${temp_file}" "${LXS_RAW_BASE}/${script_path}"; then
|
|
echo -e "${GREEN}[✓] Downloaded${NC}"
|
|
chmod +x "${temp_file}"
|
|
"${temp_file}" "$@"
|
|
exit_code=$?
|
|
rm -f "${temp_file}"
|
|
return $exit_code
|
|
else
|
|
echo -e "${RED}[✗] Failed to download ${script_path}${NC}"
|
|
rm -f "${temp_file}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Menu: System Tools
|
|
menu_system_tools() {
|
|
while true; do
|
|
clear
|
|
echo -e "${WHITE}╔═══════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${WHITE}║ SYSTEM TOOLS ║${NC}"
|
|
echo -e "${WHITE}╚═══════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
echo -e " ${CYAN}[1]${NC} View system informations"
|
|
echo -e " ${CYAN}[2]${NC} Check disk space"
|
|
echo -e " ${CYAN}[3]${NC} Check memory usage"
|
|
echo -e " ${CYAN}[4]${NC} Check CPU load"
|
|
echo -e " ${CYAN}[5]${NC} Check network"
|
|
echo -e " ${CYAN}[6]${NC} View system logs (last 50 lines)"
|
|
echo -e " ${CYAN}[7]${NC} Show top resource-consuming processes"
|
|
echo -e " ${CYAN}[8]${NC} Check disk health (SMART)"
|
|
echo -e " ${PURPLE}[9]${NC} Server Benchmark"
|
|
echo -e " ${YELLOW}[10]${NC} Harden Server"
|
|
echo -e " ${RED}[0]${NC} Exit"
|
|
echo ""
|
|
echo -e -n "${BOLD}Choice [0-10]: ${NC}"
|
|
read -r choice
|
|
|
|
echo ""
|
|
|
|
case $choice in
|
|
1)
|
|
# View system informations
|
|
clear
|
|
echo -e "${WHITE}╔═══════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${WHITE}║ SYSTEM INFORMATION ║${NC}"
|
|
echo -e "${WHITE}╚═══════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Operating System:${NC}"
|
|
echo -e " $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Kernel Version:${NC}"
|
|
echo -e " $(uname -r)"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}System Uptime:${NC}"
|
|
echo -e " $(uptime -p 2>/dev/null || uptime | awk -F'up ' '{print $2}' | awk -F',' '{print $1}')"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Load Average:${NC}"
|
|
echo -e " $(uptime | awk -F'load average:' '{print $2}')"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}CPU Information:${NC}"
|
|
echo -e " Model: $(lscpu | grep "Model name" | cut -d':' -f2 | xargs)"
|
|
echo -e " Cores: $(nproc)"
|
|
echo -e " Architecture: $(uname -m)"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Memory:${NC}"
|
|
local total_mem=$(free -h | awk '/^Mem:/ {print $2}')
|
|
local used_mem=$(free -h | awk '/^Mem:/ {print $3}')
|
|
local available_mem=$(free -h | awk '/^Mem:/ {print $7}')
|
|
echo -e " Total: $total_mem"
|
|
echo -e " Used: $used_mem"
|
|
echo -e " Available: $available_mem"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Disk Space:${NC}"
|
|
echo -e " Total: $(df -h / | awk 'NR==2 {print $2}')"
|
|
echo -e " Used: $(df -h / | awk 'NR==2 {print $3}')"
|
|
echo -e " Available: $(df -h / | awk 'NR==2 {print $4}')"
|
|
echo -e " Usage: $(df -h / | awk 'NR==2 {print $5}')"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Network:${NC}"
|
|
echo -e " Hostname: $(hostname)"
|
|
echo -e " Local IP: $(hostname -I | awk '{print $1}')"
|
|
echo -e " Public IP: $(get_public_ip)"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}${BOLD}Installed Software:${NC}"
|
|
if command -v git &> /dev/null; then
|
|
echo -e " ${GREEN}[✓]${NC} Git: $(git --version 2>/dev/null | cut -d' ' -f3)"
|
|
else
|
|
echo -e " ${GRAY}[ ]${NC} Git: Not installed"
|
|
fi
|
|
|
|
if command -v docker &> /dev/null; then
|
|
echo -e " ${GREEN}[✓]${NC} Docker: $(docker --version 2>/dev/null | cut -d' ' -f3 | tr -d ',')"
|
|
else
|
|
echo -e " ${GRAY}[ ]${NC} Docker: Not installed"
|
|
fi
|
|
|
|
if command -v node &> /dev/null; then
|
|
echo -e " ${GREEN}[✓]${NC} Node.js: $(node --version 2>/dev/null)"
|
|
else
|
|
echo -e " ${GRAY}[ ]${NC} Node.js: Not installed"
|
|
fi
|
|
|
|
if command -v python3 &> /dev/null; then
|
|
echo -e " ${GREEN}[✓]${NC} Python3: $(python3 --version 2>/dev/null | cut -d' ' -f2)"
|
|
else
|
|
echo -e " ${GRAY}[ ]${NC} Python3: Not installed"
|
|
fi
|
|
;;
|
|
2)
|
|
# Check disk space
|
|
echo -e "${CYAN}${BOLD}Disk Space Usage:${NC}"
|
|
echo ""
|
|
df -h
|
|
echo ""
|
|
show_separator
|
|
echo -e "${CYAN}${BOLD}Inode Usage:${NC}"
|
|
echo ""
|
|
df -i
|
|
;;
|
|
3)
|
|
# Check memory usage
|
|
echo -e "${CYAN}${BOLD}Memory Usage:${NC}"
|
|
echo ""
|
|
free -h
|
|
echo ""
|
|
show_separator
|
|
echo -e "${CYAN}${BOLD}Detailed Memory Info:${NC}"
|
|
echo ""
|
|
cat /proc/meminfo | head -10
|
|
;;
|
|
4)
|
|
# Check CPU load
|
|
echo -e "${CYAN}${BOLD}CPU Load and Top Processes:${NC}"
|
|
echo ""
|
|
uptime
|
|
echo ""
|
|
show_separator
|
|
echo ""
|
|
top -bn1 | head -20
|
|
;;
|
|
5)
|
|
# Check network
|
|
echo -e "${CYAN}${BOLD}Network Check:${NC}"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}[1/5]${NC} Network Interfaces:"
|
|
echo ""
|
|
ip -brief addr show 2>/dev/null || ifconfig -a
|
|
echo ""
|
|
|
|
echo -e "${CYAN}[2/5]${NC} Public IP Address:"
|
|
PUBLIC_IP=$(get_public_ip)
|
|
echo -e " ${WHITE}$PUBLIC_IP${NC}"
|
|
echo ""
|
|
|
|
echo -e "${CYAN}[3/5]${NC} DNS Resolution Test:"
|
|
echo -e -n " Testing google.com... "
|
|
if nslookup google.com >/dev/null 2>&1; then
|
|
echo -e "${GREEN}OK${NC}"
|
|
else
|
|
echo -e "${RED}FAILED${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
echo -e "${CYAN}[4/5]${NC} Internet Connectivity Test:"
|
|
echo -e -n " Pinging google.com... "
|
|
if ping -c 1 google.com >/dev/null 2>&1; then
|
|
echo -e "${GREEN}OK${NC}"
|
|
else
|
|
echo -e "${RED}FAILED${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
echo -e "${CYAN}[5/5]${NC} Open Ports:"
|
|
echo ""
|
|
if command -v ss &> /dev/null; then
|
|
ss -tulpn 2>/dev/null | grep LISTEN || echo " No listening ports or insufficient permissions"
|
|
elif command -v netstat &> /dev/null; then
|
|
netstat -tulpn 2>/dev/null | grep LISTEN || echo " No listening ports or insufficient permissions"
|
|
else
|
|
echo " ${YELLOW}Neither ss nor netstat available${NC}"
|
|
fi
|
|
;;
|
|
6)
|
|
# View system logs
|
|
echo -e "${CYAN}${BOLD}System Logs (last 50 lines):${NC}"
|
|
echo ""
|
|
sudo journalctl -n 50 --no-pager
|
|
;;
|
|
7)
|
|
# Show top resource-consuming processes
|
|
echo -e "${CYAN}${BOLD}Top Memory-Consuming Processes:${NC}"
|
|
echo ""
|
|
ps aux --sort=-%mem | head -15
|
|
echo ""
|
|
show_separator
|
|
echo ""
|
|
echo -e "${CYAN}${BOLD}Top CPU-Consuming Processes:${NC}"
|
|
echo ""
|
|
ps aux --sort=-%cpu | head -15
|
|
;;
|
|
8)
|
|
# Check disk health
|
|
echo -e "${CYAN}${BOLD}Disk Health Check (SMART):${NC}"
|
|
echo ""
|
|
if command -v smartctl &> /dev/null; then
|
|
disks=$(lsblk -d -n -p -o NAME,TYPE | grep "disk" | awk '{print $1}')
|
|
if [ -z "$disks" ]; then
|
|
echo -e "${RED}[✗] No disks found${NC}"
|
|
else
|
|
for disk in $disks; do
|
|
disk_name=$(basename "$disk")
|
|
show_separator
|
|
echo -e "${WHITE}Disk: $disk${NC}"
|
|
|
|
# Get disk info
|
|
disk_size=$(lsblk -d -n -o SIZE "$disk" 2>/dev/null)
|
|
disk_model=$(lsblk -d -n -o MODEL "$disk" 2>/dev/null | xargs)
|
|
disk_rota=$(cat /sys/block/$disk_name/queue/rotational 2>/dev/null)
|
|
|
|
echo -e " Size: ${CYAN}$disk_size${NC}"
|
|
[ -n "$disk_model" ] && echo -e " Model: ${CYAN}$disk_model${NC}"
|
|
[ "$disk_rota" == "0" ] && echo -e " Type: ${CYAN}SSD/Virtual${NC}" || echo -e " Type: ${CYAN}HDD${NC}"
|
|
echo ""
|
|
|
|
# Check if it's a virtual disk
|
|
if [[ $disk == *"/dev/vd"* ]] || [[ $disk == *"/dev/xvd"* ]]; then
|
|
echo -e " ${YELLOW}[!] Virtual disk detected - SMART not available${NC}"
|
|
echo -e " ${GRAY}[i] Virtual disks don't support SMART monitoring${NC}"
|
|
else
|
|
# Try SMART check for physical disks
|
|
smart_output=$(sudo smartctl -H "$disk" 2>&1)
|
|
if echo "$smart_output" | grep -q "PASSED"; then
|
|
echo -e " ${GREEN}[✓] SMART Status: PASSED${NC}"
|
|
elif echo "$smart_output" | grep -q "FAILED"; then
|
|
echo -e " ${RED}[✗] SMART Status: FAILED${NC}"
|
|
echo -e " ${RED}[!] WARNING: Disk may be failing!${NC}"
|
|
else
|
|
echo -e " ${YELLOW}[!] SMART not available for this disk${NC}"
|
|
fi
|
|
fi
|
|
echo ""
|
|
done
|
|
show_separator
|
|
fi
|
|
else
|
|
echo -e "${RED}[✗] smartmontools is not installed${NC}"
|
|
echo ""
|
|
read -p "Would you like to install it? (y/n): " install_smart
|
|
if [[ $install_smart =~ ^[Yy]$ ]]; then
|
|
echo ""
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
export NEEDRESTART_MODE=a
|
|
export NEEDRESTART_SUSPEND=1
|
|
run_spinner "Updating package list..." "sudo apt update -qq"
|
|
run_spinner "Installing smartmontools..." "sudo apt install -y -qq smartmontools -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
|
echo ""
|
|
echo -e "${GRAY}[i] Run this option again to check disk health${NC}"
|
|
fi
|
|
fi
|
|
;;
|
|
9)
|
|
run_sibling "tools/server-benchmark.sh"
|
|
;;
|
|
10)
|
|
run_sibling "tools/harden.sh"
|
|
;;
|
|
0)
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo -e "${RED}[✗] Invalid option. Please select 0-10.${NC}"
|
|
sleep 2
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
echo ""
|
|
show_separator
|
|
echo ""
|
|
read -p "Press Enter to continue..."
|
|
done
|
|
}
|
|
|
|
menu_system_tools
|
|
|