mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-07-15 20:06:54 +00:00
658 lines
26 KiB
Bash
658 lines
26 KiB
Bash
#!/bin/bash
|
||
# ==========================================================
|
||
# ProxMenu - Network Management and Repair Tool
|
||
# ==========================================================
|
||
# Author : MacRimi
|
||
# Copyright : (c) 2024 MacRimi
|
||
# License : MIT (https://raw.githubusercontent.com/MacRimi/ProxMenux/main/LICENSE)
|
||
# Version : 1.1
|
||
# Last Updated: 08/07/2025
|
||
# ==========================================================
|
||
|
||
# Description:
|
||
# Advanced network management and troubleshooting tool for Proxmox VE.
|
||
# Features include interface detection, bridge management, connectivity testing,
|
||
# network diagnostics, configuration backup/restore, and automated repairs.
|
||
|
||
# Configuration ============================================
|
||
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
|
||
BASE_DIR="/usr/local/share/proxmenux"
|
||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||
VENV_PATH="/opt/googletrans-env"
|
||
BACKUP_DIR="/var/backups/proxmenux"
|
||
|
||
if [[ -f "$UTILS_FILE" ]]; then
|
||
source "$UTILS_FILE"
|
||
fi
|
||
|
||
load_language
|
||
initialize_cache
|
||
|
||
# ==========================================================
|
||
# Utility Functions
|
||
create_backup_dir() {
|
||
[ ! -d "$BACKUP_DIR" ] && mkdir -p "$BACKUP_DIR"
|
||
}
|
||
|
||
backup_network_config() {
|
||
create_backup_dir
|
||
local timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
|
||
local backup_file="$BACKUP_DIR/interfaces_backup_$timestamp"
|
||
cp /etc/network/interfaces "$backup_file"
|
||
msg_ok "$(translate "Network configuration backed up")"
|
||
echo "$backup_file"
|
||
}
|
||
|
||
# ==========================================================
|
||
# Network Detection Functions
|
||
detect_network_method() {
|
||
# Detect Netplan
|
||
if compgen -G "/etc/netplan/*.yaml" > /dev/null; then
|
||
echo "netplan"
|
||
return 0
|
||
fi
|
||
|
||
# Detect systemd-networkd
|
||
if systemctl is-active --quiet systemd-networkd 2>/dev/null; then
|
||
echo "systemd-networkd"
|
||
return 0
|
||
fi
|
||
|
||
# Detect NetworkManager
|
||
if systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
||
echo "networkmanager"
|
||
return 0
|
||
fi
|
||
|
||
# Default: Debian/Proxmox classic
|
||
echo "classic"
|
||
}
|
||
|
||
detect_physical_interfaces() {
|
||
ip -o link show | awk -F': ' '$2 !~ /^(lo|veth|dummy|bond|tap|tun|docker|br-)/ && $2 !~ /vmbr/ {print $2}' | sort
|
||
}
|
||
|
||
detect_bridge_interfaces() {
|
||
ip -o link show | awk -F': ' '$2 ~ /^vmbr/ {print $2}' | sort
|
||
}
|
||
|
||
detect_all_interfaces() {
|
||
ip -o link show | awk -F': ' '$2 !~ /^(lo|veth|dummy|tap|tun)/ {print $2}' | sort
|
||
}
|
||
|
||
get_interface_info() {
|
||
local interface="$1"
|
||
local info=""
|
||
|
||
# Get IP address
|
||
local ip=$(ip -4 addr show "$interface" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' | head -1)
|
||
[ -z "$ip" ] && ip="$(translate "No IP")"
|
||
|
||
# Get status
|
||
local status=$(ip link show "$interface" 2>/dev/null | grep -o "state [A-Z]*" | cut -d' ' -f2)
|
||
[ -z "$status" ] && status="UNKNOWN"
|
||
|
||
# Get MAC address
|
||
local mac=$(ip link show "$interface" 2>/dev/null | grep -o "link/ether [a-f0-9:]*" | cut -d' ' -f2)
|
||
[ -z "$mac" ] && mac="$(translate "No MAC")"
|
||
|
||
echo "$interface|$ip|$status|$mac"
|
||
}
|
||
|
||
# ==========================================================
|
||
|
||
show_routing_table_() {
|
||
local route_info=""
|
||
route_info+="$(translate "Routing Table")\n"
|
||
route_info+="$(printf '=%.0s' {1..30})\n\n"
|
||
route_info+="$(ip route show)\n\n"
|
||
route_info+="$(translate "Default Gateway"): $(ip route | grep default | awk '{print $3}' | head -1)\n"
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Routing Information")" \
|
||
--msgbox "$route_info" 20 80
|
||
}
|
||
|
||
|
||
show_routing_table() {
|
||
local route_info=""
|
||
local default_gw=$(ip route | grep default | awk '{print $3}' | head -1)
|
||
local routes=$(ip route show)
|
||
local route_count=$(echo "$routes" | wc -l)
|
||
|
||
route_info+="🗺️ $(translate "Routing Table")\n"
|
||
route_info+="$(printf '═%.0s' {1..60})\n\n"
|
||
|
||
if [ -z "$routes" ]; then
|
||
route_info+="⚠️ $(translate "No routing information found.")\n\n"
|
||
else
|
||
route_info+="$(translate "Total routes"): $route_count\n\n"
|
||
|
||
while read -r line; do
|
||
if [[ "$line" == *"default"* ]]; then
|
||
route_info+="➡️ $line\n"
|
||
else
|
||
route_info+=" • $line\n"
|
||
fi
|
||
done <<< "$routes"
|
||
route_info+="\n"
|
||
route_info+="🌍 $(translate "Default Gateway"): ${default_gw:-$(translate "Not found")}\n"
|
||
fi
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Routing Information")" \
|
||
--msgbox "$route_info" 20 80
|
||
}
|
||
|
||
|
||
# ==========================================================
|
||
# Network Testing Functions
|
||
test_connectivity() {
|
||
local test_results=""
|
||
local tests=(
|
||
"8.8.8.8|Google DNS"
|
||
"1.1.1.1|Cloudflare DNS"
|
||
"$(ip route | grep default | awk '{print $3}' | head -1)|Gateway"
|
||
)
|
||
show_proxmenux_logo
|
||
msg_info "$(translate "Test Connectivity")"
|
||
test_results+="$(translate "Connectivity Test Results")\n"
|
||
test_results+="$(printf '=%.0s' {1..35})\n\n"
|
||
|
||
for test in "${tests[@]}"; do
|
||
IFS='|' read -r target name <<< "$test"
|
||
if [ -n "$target" ] && [ "$target" != "" ]; then
|
||
if ping -c 2 -W 3 "$target" >/dev/null 2>&1; then
|
||
test_results+="✓ $name ($target): $(translate "OK")\n"
|
||
else
|
||
test_results+="✗ $name ($target): $(translate "FAILED")\n"
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# DNS Resolution test
|
||
if nslookup google.com >/dev/null 2>&1; then
|
||
test_results+="✓ $(translate "DNS Resolution"): $(translate "OK")\n"
|
||
else
|
||
test_results+="✗ $(translate "DNS Resolution"): $(translate "FAILED")\n"
|
||
fi
|
||
cleanup
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Connectivity Test")" \
|
||
--msgbox "$test_results" 20 70
|
||
}
|
||
|
||
advanced_network_diagnostics() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
show_proxmenux_logo
|
||
msg_info "$(translate "Advanced Diagnostics")"
|
||
sleep 1
|
||
|
||
local diag_info=""
|
||
|
||
diag_info+="$(translate "Advanced Network Diagnostics")\n"
|
||
diag_info+="$(printf '=%.0s' {1..40})\n\n"
|
||
|
||
# Network statistics
|
||
diag_info+="$(translate "Active Connections"): $(ss -tuln | wc -l)\n"
|
||
diag_info+="$(translate "Listening Ports"): $(ss -tln | grep LISTEN | wc -l)\n"
|
||
diag_info+="$(translate "Network Interfaces"): $(ip link show | grep -c "^[0-9]")\n\n"
|
||
|
||
# Check for common issues
|
||
diag_info+="$(translate "Common Issues Check"):\n"
|
||
|
||
# Check if NetworkManager is running (shouldn't be on Proxmox)
|
||
if systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
||
diag_info+="⚠ $(translate "NetworkManager is running (may cause conflicts)")\n"
|
||
|
||
if dialog --title "$(translate "NetworkManager Detected")" \
|
||
--yesno "$(translate "NetworkManager is running, which may conflict with Proxmox.")\n\n$(translate "Do you want to disable and remove it now?")" 10 70; then
|
||
|
||
dialog --infobox "$(translate "Disabling and removing NetworkManager...")" 6 60
|
||
systemctl stop NetworkManager >/dev/null 2>&1
|
||
systemctl disable NetworkManager >/dev/null 2>&1
|
||
apt-get purge -y network-manager >/dev/null 2>&1
|
||
|
||
diag_info+="✓ $(translate "NetworkManager has been removed successfully")\n"
|
||
else
|
||
diag_info+="ℹ️ $(translate "User chose not to remove NetworkManager")\n"
|
||
fi
|
||
else
|
||
diag_info+="✓ $(translate "NetworkManager not running")\n"
|
||
fi
|
||
|
||
# Check for duplicate IPs
|
||
local ips=($(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | sort | uniq -d))
|
||
if [ ${#ips[@]} -gt 0 ]; then
|
||
diag_info+="⚠ $(translate "Duplicate IP addresses found"): ${ips[*]}\n"
|
||
else
|
||
diag_info+="✓ $(translate "No duplicate IP addresses")\n"
|
||
fi
|
||
|
||
cleanup
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Network Diagnostics")" \
|
||
--msgbox "$diag_info" 20 70
|
||
}
|
||
|
||
|
||
# ==========================================================
|
||
# SAFE Network Analysis Functions (NO AUTO-REPAIR)
|
||
# ==========================================================
|
||
|
||
analyze_bridge_configuration() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
show_proxmenux_logo
|
||
msg_info "$(translate "Analyzing Bridge Configuration - READ ONLY MODE")"
|
||
sleep 1
|
||
|
||
local physical_interfaces=($(detect_physical_interfaces))
|
||
local bridges=($(detect_bridge_interfaces))
|
||
local analysis_report=""
|
||
local issues_found=0
|
||
local suggestions=""
|
||
|
||
analysis_report+="🔍 $(translate "BRIDGE CONFIGURATION ANALYSIS")\n"
|
||
analysis_report+="$(printf '=%.0s' {1..50})\n\n"
|
||
cleanup
|
||
if [ ${#bridges[@]} -eq 0 ]; then
|
||
analysis_report+="ℹ️ $(translate "No bridges found in system")\n"
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Bridge Analysis")" --msgbox "$analysis_report" 10 60
|
||
return
|
||
fi
|
||
|
||
# Analyze each bridge
|
||
for bridge in "${bridges[@]}"; do
|
||
analysis_report+="🌉 $(translate "Bridge"): $bridge\n"
|
||
|
||
# Get current configuration
|
||
local current_ports=$(grep -A5 "iface $bridge" /etc/network/interfaces 2>/dev/null | grep "bridge-ports" | cut -d' ' -f2-)
|
||
local bridge_ip=$(ip -4 addr show "$bridge" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' | head -1)
|
||
local bridge_status=$(ip link show "$bridge" 2>/dev/null | grep -o "state [A-Z]*" | cut -d' ' -f2)
|
||
|
||
analysis_report+=" 📍 $(translate "Status"): ${bridge_status:-UNKNOWN}\n"
|
||
analysis_report+=" 🌐 $(translate "IP"): ${bridge_ip:-$(translate "No IP assigned")}\n"
|
||
analysis_report+=" 🔌 $(translate "Configured Ports"): ${current_ports:-$(translate "None")}\n"
|
||
|
||
if [ -n "$current_ports" ]; then
|
||
local invalid_ports=""
|
||
local valid_ports=""
|
||
|
||
# Check each configured port
|
||
for port in $current_ports; do
|
||
if ip link show "$port" >/dev/null 2>&1; then
|
||
valid_ports+="$port "
|
||
analysis_report+=" ✅ $(translate "Port") $port: $(translate "EXISTS")\n"
|
||
else
|
||
invalid_ports+="$port "
|
||
analysis_report+=" ❌ $(translate "Port") $port: $(translate "NOT FOUND")\n"
|
||
((issues_found++))
|
||
fi
|
||
done
|
||
|
||
# Generate suggestions for invalid ports
|
||
if [ -n "$invalid_ports" ]; then
|
||
suggestions+="🔧 $(translate "SUGGESTION FOR") $bridge:\n"
|
||
if [ ${#physical_interfaces[@]} -gt 0 ]; then
|
||
suggestions+=" $(translate "Replace invalid port(s)") '$invalid_ports' $(translate "with"): ${physical_interfaces[0]}\n"
|
||
suggestions+=" $(translate "Command"): sed -i 's/bridge-ports.*/bridge-ports ${physical_interfaces[0]}/' /etc/network/interfaces\n"
|
||
else
|
||
suggestions+=" $(translate "Remove invalid port(s)") '$invalid_ports'\n"
|
||
suggestions+=" $(translate "Command"): sed -i 's/bridge-ports.*/bridge-ports none/' /etc/network/interfaces\n"
|
||
fi
|
||
suggestions+="\n"
|
||
fi
|
||
else
|
||
analysis_report+=" ⚠️ $(translate "No ports configured")\n"
|
||
if [ ${#physical_interfaces[@]} -gt 0 ]; then
|
||
suggestions+="🔧 $(translate "SUGGESTION FOR") $bridge:\n"
|
||
suggestions+=" $(translate "Consider adding physical interface"): ${physical_interfaces[0]}\n"
|
||
suggestions+=" $(translate "Command"): sed -i '/iface $bridge/a\\ bridge-ports ${physical_interfaces[0]}' /etc/network/interfaces\n\n"
|
||
fi
|
||
fi
|
||
analysis_report+="\n"
|
||
done
|
||
|
||
# Summary
|
||
analysis_report+="📊 $(translate "ANALYSIS SUMMARY")\n"
|
||
analysis_report+="$(printf '=%.0s' {1..25})\n"
|
||
analysis_report+="$(translate "Bridges analyzed"): ${#bridges[@]}\n"
|
||
analysis_report+="$(translate "Issues found"): $issues_found\n"
|
||
|
||
|
||
local auto_only=$(grep "^auto" /etc/network/interfaces | awk '{print $2}' | while read i; do
|
||
grep -q "^iface $i" /etc/network/interfaces || echo "$i"
|
||
done)
|
||
|
||
if [ -n "$auto_only" ]; then
|
||
analysis_report+="⚠️ $(translate "Interfaces defined with 'auto' but no 'iface' block"): $auto_only\n"
|
||
((issues_found++))
|
||
fi
|
||
|
||
analysis_report+="$(translate "Physical interfaces available"): ${#physical_interfaces[@]}\n\n"
|
||
|
||
if [ $issues_found -gt 0 ]; then
|
||
analysis_report+="$suggestions"
|
||
analysis_report+="⚠️ $(translate "IMPORTANT"): $(translate "No changes have been made to your system")\n"
|
||
analysis_report+="$(translate "Use the Guided Repair option to fix issues safely")\n"
|
||
else
|
||
analysis_report+="✅ $(translate "No bridge configuration issues found")\n"
|
||
fi
|
||
|
||
# Show analysis in scrollable dialog
|
||
local temp_file=$(mktemp)
|
||
echo -e "$analysis_report" > "$temp_file"
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Bridge Configuration Analysis")" \
|
||
--textbox "$temp_file" 25 80
|
||
rm -f "$temp_file"
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
analyze_network_configuration() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
show_proxmenux_logo
|
||
msg_info "$(translate "Analyzing Network Configuration - READ ONLY MODE")"
|
||
sleep 1
|
||
|
||
local configured_interfaces=($(grep "^iface" /etc/network/interfaces | awk '{print $2}' | grep -v "lo"))
|
||
local analysis_report=""
|
||
local issues_found=0
|
||
local suggestions=""
|
||
|
||
analysis_report+="🔍 $(translate "NETWORK CONFIGURATION ANALYSIS")\n"
|
||
analysis_report+="$(printf '=%.0s' {1..50})\n\n"
|
||
|
||
cleanup
|
||
if [ ${#configured_interfaces[@]} -eq 0 ]; then
|
||
analysis_report+="ℹ️ $(translate "No network interfaces configured (besides loopback)")\n"
|
||
dialog --title "$(translate "Configuration Analysis")" --msgbox "$analysis_report" 10 60
|
||
return
|
||
fi
|
||
|
||
analysis_report+="📋 $(translate "CONFIGURED INTERFACES")\n"
|
||
analysis_report+="$(printf '=%.0s' {1..30})\n"
|
||
|
||
# Analyze each configured interface
|
||
for iface in "${configured_interfaces[@]}"; do
|
||
analysis_report+="🔌 $(translate "Interface"): $iface\n"
|
||
|
||
# Check if interface exists physically
|
||
if ip link show "$iface" >/dev/null 2>&1; then
|
||
local status=$(ip link show "$iface" 2>/dev/null | grep -o "state [A-Z]*" | cut -d' ' -f2)
|
||
local ip=$(ip -4 addr show "$iface" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' | head -1)
|
||
|
||
analysis_report+=" ✅ $(translate "Status"): $(translate "EXISTS") ($status)\n"
|
||
analysis_report+=" 🌐 $(translate "IP"): ${ip:-$(translate "No IP assigned")}\n"
|
||
|
||
# Check if it's a bridge or bond (these are virtual, so it's normal they exist)
|
||
if [[ $iface =~ ^(vmbr|bond) ]]; then
|
||
analysis_report+=" ℹ️ $(translate "Type"): $(translate "Virtual interface (normal)")\n"
|
||
else
|
||
analysis_report+=" ℹ️ $(translate "Type"): $(translate "Physical interface")\n"
|
||
fi
|
||
else
|
||
analysis_report+=" ❌ $(translate "Status"): $(translate "NOT FOUND")\n"
|
||
analysis_report+=" ⚠️ $(translate "Issue"): $(translate "Configured but doesn't exist")\n"
|
||
((issues_found++))
|
||
|
||
# Only suggest removal for non-virtual interfaces
|
||
if [[ ! $iface =~ ^(vmbr|bond) ]]; then
|
||
suggestions+="🔧 $(translate "SUGGESTION FOR") $iface:\n"
|
||
suggestions+=" $(translate "This interface is configured but doesn't exist physically")\n"
|
||
suggestions+=" $(translate "Consider removing its configuration")\n"
|
||
suggestions+=" $(translate "Command"): sed -i '/iface $iface/,/^$/d' /etc/network/interfaces\n\n"
|
||
fi
|
||
fi
|
||
analysis_report+="\n"
|
||
done
|
||
|
||
# Summary
|
||
analysis_report+="📊 $(translate "ANALYSIS SUMMARY")\n"
|
||
analysis_report+="$(printf '=%.0s' {1..25})\n"
|
||
analysis_report+="$(translate "Interfaces configured"): ${#configured_interfaces[@]}\n"
|
||
analysis_report+="$(translate "Issues found"): $issues_found\n\n"
|
||
|
||
if [ $issues_found -gt 0 ]; then
|
||
analysis_report+="$suggestions"
|
||
analysis_report+="⚠️ $(translate "IMPORTANT"): $(translate "No changes have been made to your system")\n"
|
||
analysis_report+="$(translate "Use the Guided Cleanup option to fix issues safely")\n"
|
||
else
|
||
analysis_report+="✅ $(translate "No configuration issues found")\n"
|
||
fi
|
||
|
||
# Show analysis in scrollable dialog
|
||
local temp_file=$(mktemp)
|
||
echo -e "$analysis_report" > "$temp_file"
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Network Configuration Analysis")" \
|
||
--textbox "$temp_file" 25 80
|
||
rm -f "$temp_file"
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
restart_network_service() {
|
||
if dialog --title "$(translate "Restart Network")" \
|
||
--yesno "\n$(translate "This will restart the network service and may cause a brief disconnection. Continue?")" 10 60; then
|
||
|
||
show_proxmenux_logo
|
||
msg_info "$(translate "Restarting network service...")"
|
||
|
||
if systemctl restart networking; then
|
||
msg_ok "$(translate "Network service restarted successfully")"
|
||
else
|
||
msg_error "$(translate "Failed to restart network service")"
|
||
msg_warn "$(translate "If you lose connectivity, you can restore from backup using the console.")"
|
||
fi
|
||
|
||
msg_success "$(translate "Press ENTER to continue...")"
|
||
read -r
|
||
fi
|
||
}
|
||
|
||
|
||
|
||
# ==========================================================
|
||
# Configuration Management
|
||
show_network_config() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
local config_content
|
||
config_content=$(cat /etc/network/interfaces)
|
||
show_proxmenux_logo
|
||
echo -e
|
||
echo -e
|
||
echo "========== $(translate "Network Configuration File") =========="
|
||
echo
|
||
cat /etc/network/interfaces
|
||
echo
|
||
msg_success "$(translate "Press Enter to continue...")"
|
||
read -r
|
||
}
|
||
|
||
|
||
create_network_backup_manual() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
show_proxmenux_logo
|
||
echo -e
|
||
msg_info "$(translate "Creating backup of network interfaces configuration...")"
|
||
sleep 3
|
||
backup_network_config
|
||
echo -e
|
||
msg_success "$(translate "Press Enter to continue...")"
|
||
read -r
|
||
|
||
}
|
||
|
||
|
||
|
||
restore_network_backup() {
|
||
|
||
NETWORK_METHOD=$(detect_network_method)
|
||
|
||
if [[ "$NETWORK_METHOD" != "classic" ]]; then
|
||
dialog --title "Unsupported Network Stack" \
|
||
--msgbox "WARNING: This script only supports the classic Debian/Proxmox network configuration (/etc/network/interfaces).\n\nDetected: $NETWORK_METHOD.\n\nAborting for safety.\n\nPlease configure your network using your distribution's supported tools." 14 70
|
||
exit 1
|
||
fi
|
||
|
||
local backups=($(ls -1 "$BACKUP_DIR"/interfaces_backup_* 2>/dev/null | sort -r))
|
||
|
||
if [ ${#backups[@]} -eq 0 ]; then
|
||
dialog --backtitle "ProxMenux" --title "$(translate "No Backups")" \
|
||
--msgbox "\n$(translate "No network configuration backups found.")" 14 60
|
||
return
|
||
fi
|
||
|
||
local menu_items=()
|
||
local counter=1
|
||
|
||
for backup in "${backups[@]}"; do
|
||
local filename=$(basename "$backup")
|
||
local timestamp=$(basename "$backup" | sed 's/interfaces_backup_//')
|
||
menu_items+=("$counter" "$timestamp")
|
||
((counter++))
|
||
done
|
||
|
||
local selection=$(dialog --backtitle "ProxMenux" --title "$(translate "Restore Backup")" \
|
||
--menu "$(translate "Select backup to restore:"):" 20 70 12 \
|
||
"${menu_items[@]}" 3>&1 1>&2 2>&3)
|
||
|
||
if [ -n "$selection" ] && [ "$selection" -ge 1 ] && [ "$selection" -le ${#backups[@]} ]; then
|
||
local selected_backup="${backups[$((selection-1))]}"
|
||
|
||
|
||
if dialog --backtitle "ProxMenux" --title "$(translate "Preview Backup")" \
|
||
--yesno "\n$(translate "Do you want to view the selected backup before restoring?")" 8 60; then
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Backup Preview")" \
|
||
--textbox "$selected_backup" 22 80
|
||
fi
|
||
|
||
if dialog --backtitle "ProxMenux" --title "$(translate "Confirm Restore")" \
|
||
--yesno "\n$(translate "Are you sure you want to restore this backup?\nCurrent configuration will be overwritten.")\n\n$(translate "For your safety, a backup of the current configuration will be created automatically before restoring.")" 14 70; then
|
||
|
||
local pre_restore_backup=$(backup_network_config)
|
||
cp "$selected_backup" /etc/network/interfaces
|
||
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Backup Restored")" \
|
||
--msgbox "\n$(translate "Network configuration has been restored from backup.")" 8 60
|
||
|
||
|
||
if dialog --backtitle "ProxMenux" --title "$(translate "Restart Network")" \
|
||
--yesno "\n$(translate "Do you want to restart the network service now to apply changes?")" 8 60; then
|
||
if systemctl restart networking; then
|
||
dialog --backtitle "ProxMenux" --title "$(translate "Network Restarted")" \
|
||
--msgbox "\n$(translate "Network service restarted successfully.")" 8 50
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
|
||
|
||
launch_iftop() {
|
||
if ! command -v iftop &>/dev/null; then
|
||
apt-get update -qq && apt-get install -y iftop &>/dev/null
|
||
fi
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "iftop usage")" --msgbox "\n$(translate "To exit iftop, press q")" 8 50
|
||
clear
|
||
iftop
|
||
}
|
||
|
||
launch_iptraf() {
|
||
if ! command -v iptraf-ng &>/dev/null; then
|
||
apt-get update -qq && apt-get install -y iptraf-ng &>/dev/null
|
||
fi
|
||
|
||
dialog --backtitle "ProxMenux" --title "$(translate "iptraf-ng usage")" --msgbox "\n$(translate "To exit iptraf-ng, press x")" 8 50
|
||
clear
|
||
iptraf-ng
|
||
}
|
||
|
||
|
||
# ==========================================================
|
||
# Main Menu
|
||
show_main_menu() {
|
||
while true; do
|
||
local selection=$(dialog --clear \
|
||
--backtitle "ProxMenux" \
|
||
--title "$(translate "Network Management - SAFE MODE")" \
|
||
--menu "$(translate "Select an option:"):" 20 70 12 \
|
||
"1" "$(translate "Real-time network usage (iftop)")" \
|
||
"2" "$(translate "Network monitoring tool (iptraf-ng)")" \
|
||
"3" "$(translate "Show Routing Table")" \
|
||
"4" "$(translate "Test Connectivity")" \
|
||
"5" "$(translate "Advanced Diagnostics")" \
|
||
"6" "$(translate "Analyze Bridge Configuration")" \
|
||
"7" "$(translate "Analyze Network Configuration")" \
|
||
"8" "$(translate "Restart Network Service")" \
|
||
"9" "$(translate "Show Network Config File")" \
|
||
"10" "$(translate "Create Network Backup")" \
|
||
"11" "$(translate "Restore Network Backup")" \
|
||
"0" "$(translate "Return to Main Menu")" \
|
||
3>&1 1>&2 2>&3)
|
||
|
||
case $selection in
|
||
1) launch_iftop ;;
|
||
2) launch_iptraf ;;
|
||
3) show_routing_table ;;
|
||
4) test_connectivity ;;
|
||
5) advanced_network_diagnostics ;;
|
||
6) analyze_bridge_configuration ;;
|
||
7) analyze_network_configuration ;;
|
||
8) restart_network_service ;;
|
||
9) show_network_config ;;
|
||
10) create_network_backup_manual ;;
|
||
11) restore_network_backup ;;
|
||
0|"") exec bash <(curl -s "$REPO_URL/scripts/menus/main_menu.sh") ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
|
||
# ==========================================================
|
||
show_main_menu
|