#!/bin/bash INTERFACES_FILE="/etc/network/interfaces" # SHA256 hash of the shell access password. # To change it: echo -n "yourpassword" | sha256sum # Default password: admin SHELL_PASSWORD_HASH="d26c61e6f4963bcfbfab0c209cb4d24043f2f611ffcf8938cb974bda60a92f0c" # ── helpers ────────────────────────────────────────────────────────────────── get_interfaces() { ls /sys/class/net/ 2>/dev/null | grep -v '^lo$' } get_ip() { local iface="$1" ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 } get_netmask() { local iface="$1" local prefix prefix=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f2) [ -z "$prefix" ] && return python3 -c "import ipaddress; print(ipaddress.IPv4Network('0.0.0.0/$prefix', strict=False).netmask)" 2>/dev/null } get_gateway() { ip route show default 2>/dev/null | awk '/default/{print $3; exit}' } is_dhcp() { local iface="$1" grep -A5 "iface $iface" "$INTERFACES_FILE" 2>/dev/null | grep -q "dhcp" } # ── arrow-key menu ──────────────────────────────────────────────────────────── # Usage: arrow_menu result_var "Item 1" "Item 2" ... # Sets result_var to the 0-based index of the chosen item. arrow_menu() { local -n _res="$1"; shift local items=("$@") local count=${#items[@]} local cur=0 tput civis trap 'tput cnorm; echo; exit 130' INT _draw_menu() { for (( i=0; i/dev/null | grep -q "static"; then method="Static" else method="Unknown" fi printf " ║ Interface : %-20s Mode: %-10s ║\n" "$iface" "$method" printf " ║ IP Address: %-45s ║\n" "$ip" printf " ║ Netmask : %-45s ║\n" "$netmask" printf " ║ Gateway : %-45s ║\n" "$gw" echo " ║ ║" done fi echo " ╚══════════════════════════════════════════════════════════════════════════╝" echo "" echo " Use ↑ ↓ to navigate, Enter to select, Ctrl+C to exit" echo "" } # ── select interface ────────────────────────────────────────────────────────── select_interface() { local ifaces mapfile -t ifaces < <(get_interfaces) if [ ${#ifaces[@]} -eq 0 ]; then echo "No network interfaces found." return 1 fi if [ ${#ifaces[@]} -eq 1 ]; then SELECTED_IFACE="${ifaces[0]}" return 0 fi clear echo "" echo "╔══════════════════════════════════════════════════════════════════════════╗" echo "║ Select Interface ║" echo "╚══════════════════════════════════════════════════════════════════════════╝" echo "" local choice arrow_menu choice "${ifaces[@]}" echo "" SELECTED_IFACE="${ifaces[$choice]}" } # ── validate IPv4 ───────────────────────────────────────────────────────────── valid_ip() { local ip="$1" [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1 IFS='.' read -ra octets <<< "$ip" for octet in "${octets[@]}"; do [ "$octet" -le 255 ] || return 1 done return 0 } # ── set static IP ───────────────────────────────────────────────────────────── set_static() { local iface="$1" local new_ip new_netmask new_gw clear echo "" echo "╔══════════════════════════════════════════════════════════════════════════╗" printf "║ Configure Static IP ── Interface: %-34s║\n" "$iface " echo "╚══════════════════════════════════════════════════════════════════════════╝" echo "" local cur_ip cur_mask cur_gw cur_ip=$(get_ip "$iface") cur_mask=$(get_netmask "$iface") cur_gw=$(get_gateway) while true; do read -rp " IP address [${cur_ip:-?}]: " new_ip new_ip="${new_ip:-$cur_ip}" valid_ip "$new_ip" && break echo " Invalid IP address. Try again." done while true; do read -rp " Netmask [${cur_mask:-255.255.255.0}]: " new_netmask new_netmask="${new_netmask:-${cur_mask:-255.255.255.0}}" valid_ip "$new_netmask" && break echo " Invalid netmask. Try again." done while true; do read -rp " Gateway [${cur_gw:-?}]: " new_gw new_gw="${new_gw:-$cur_gw}" valid_ip "$new_gw" && break echo " Invalid gateway. Try again." done echo "" echo "┌──────────────────────────────────────────────────────────────────────────┐" echo "│ Summary │" printf "│ Interface : %-58s │\n" "$iface" printf "│ IP Address: %-58s │\n" "$new_ip" printf "│ Netmask : %-58s │\n" "$new_netmask" printf "│ Gateway : %-58s │\n" "$new_gw" echo "└──────────────────────────────────────────────────────────────────────────┘" echo "" read -rp "Apply these settings? [y/N]: " confirm [[ "$confirm" =~ ^[Yy]$ ]] || { echo "Cancelled."; return; } if [ -f "$INTERFACES_FILE" ]; then cp "$INTERFACES_FILE" "${INTERFACES_FILE}.bak.$(date +%Y%m%d%H%M%S)" fi write_interfaces "$iface" "static" "$new_ip" "$new_netmask" "$new_gw" echo "" echo " Written to $INTERFACES_FILE" echo " Applying configuration..." if command -v ifdown &>/dev/null; then ifdown "$iface" 2>/dev/null ifup "$iface" 2>/dev/null && echo " Done." || echo " ifup failed — you may need to reconnect manually." else ip addr flush dev "$iface" 2>/dev/null ip addr add "${new_ip}/$(mask_to_cidr "$new_netmask")" dev "$iface" 2>/dev/null ip route add default via "$new_gw" 2>/dev/null ip link set "$iface" up 2>/dev/null echo " Done (applied via iproute2)." fi } # ── set DHCP ────────────────────────────────────────────────────────────────── set_dhcp() { local iface="$1" echo "" read -rp "Switch $iface to DHCP? [y/N]: " confirm [[ "$confirm" =~ ^[Yy]$ ]] || { echo "Cancelled."; return; } if [ -f "$INTERFACES_FILE" ]; then cp "$INTERFACES_FILE" "${INTERFACES_FILE}.bak.$(date +%Y%m%d%H%M%S)" fi write_interfaces "$iface" "dhcp" echo " Written to $INTERFACES_FILE" echo " Applying configuration..." if command -v ifdown &>/dev/null; then ifdown "$iface" 2>/dev/null ifup "$iface" 2>/dev/null && echo " Done." || echo " ifup failed — check your DHCP server." else ip addr flush dev "$iface" 2>/dev/null dhclient "$iface" 2>/dev/null && echo " Done." || echo " dhclient failed." fi } # ── write /etc/network/interfaces ──────────────────────────────────────────── write_interfaces() { local target_iface="$1" local method="$2" local new_ip="$3" local new_netmask="$4" local new_gw="$5" local tmpfile tmpfile=$(mktemp) if ! grep -q "iface lo" "$INTERFACES_FILE" 2>/dev/null; then printf "auto lo\niface lo inet loopback\n\n" >> "$tmpfile" fi if [ -f "$INTERFACES_FILE" ]; then awk -v iface="$target_iface" ' /^(auto|allow-hotplug|iface) / && $0 ~ iface { skip=1 } skip && /^(auto|allow-hotplug|iface) / && $0 !~ iface { skip=0 } !skip { print } ' "$INTERFACES_FILE" >> "$tmpfile" fi { echo "" echo "auto $target_iface" if [ "$method" = "static" ]; then echo "iface $target_iface inet static" echo " address $new_ip" echo " netmask $new_netmask" echo " gateway $new_gw" else echo "iface $target_iface inet dhcp" fi } >> "$tmpfile" mv "$tmpfile" "$INTERFACES_FILE" } # ── cidr helper ─────────────────────────────────────────────────────────────── mask_to_cidr() { python3 -c " import ipaddress print(ipaddress.IPv4Network('0.0.0.0/$1', strict=False).prefixlen) " 2>/dev/null || echo "24" } # ── reboot ─────────────────────────────────────────────────────────────────── reboot_confirm() { clear echo "" echo "╔══════════════════════════════════════════════════════════════════════════╗" echo "║ Reboot ║" echo "╚══════════════════════════════════════════════════════════════════════════╝" echo "" read -rp " Are you sure you want to reboot? [y/N]: " confirm if [[ "$confirm" =~ ^[Yy]$ ]]; then echo "" echo " Rebooting..." sleep 1 reboot else echo " Cancelled." echo "" read -rp "Press Enter to continue..." fi } # ── shell access ───────────────────────────────────────────────────────────── shell_access() { clear echo "" echo "╔══════════════════════════════════════════════════════════════════════════╗" echo "║ Shell Access ║" echo "╚══════════════════════════════════════════════════════════════════════════╝" echo "" local attempts=3 while (( attempts-- > 0 )); do local input input_hash read -rsp " Password: " input echo "" input_hash=$(echo -n "$input" | sha256sum | cut -d' ' -f1) if [ "$input_hash" = "$SHELL_PASSWORD_HASH" ]; then echo "" echo " Access granted. Type 'exit' to return to the menu." echo "" bash return else echo " Incorrect password.$( (( attempts > 0 )) && echo " $attempts attempt(s) remaining." || echo "" )" fi done echo " Access denied." echo "" read -rp "Press Enter to continue..." } # ── main menu ───────────────────────────────────────────────────────────────── MENU_ITEMS=("Refresh" "Set Static IP" "Set DHCP" "Shell" "Reboot") main_menu() { local choice while true; do show_status arrow_menu choice "${MENU_ITEMS[@]}" echo "" case "$choice" in 0) ;; # Refresh — just redraw 1) if select_interface; then set_static "$SELECTED_IFACE" fi echo "" read -rp "Press Enter to continue..." ;; 2) if select_interface; then set_dhcp "$SELECTED_IFACE" fi echo "" read -rp "Press Enter to continue..." ;; 3) shell_access ;; 4) reboot_confirm ;; esac done } # ── entry point ─────────────────────────────────────────────────────────────── if [ "$EUID" -ne 0 ]; then echo "This script must be run as root (use sudo)." exit 1 fi main_menu