diff options
| author | silly <u65487754@gmail.com> | 2026-04-07 05:20:08 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-07 05:20:08 +0000 |
| commit | 1464a8a62bcd0e80fdf0fbfc1751428566abf77c (patch) | |
| tree | 4ba2d317d09acebc1f2487fe25156d3df3ac07f5 /.config/scripts/network.sh | |
| parent | 75d3cfbb6be6f1640b3dfb0965ff4b2a9070ec4c (diff) | |
Create network.sh
Diffstat (limited to '.config/scripts/network.sh')
| -rw-r--r-- | .config/scripts/network.sh | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/.config/scripts/network.sh b/.config/scripts/network.sh new file mode 100644 index 0000000..70f01e8 --- /dev/null +++ b/.config/scripts/network.sh @@ -0,0 +1,227 @@ +#!/bin/bash + +WG_DIR="/etc/wireguard" +LAST_VPN="$HOME/.cache/last_vpn" + +notify() { + notify-send -a "network" "$1" "$2" 2>/dev/null || true +} + +wg_active() { + wg show interfaces 2>/dev/null | tr ' ' '\n' | grep -v '^$' +} + +wg_configs() { + for f in "$WG_DIR"/*.conf; do + [[ -f "$f" ]] && basename "$f" .conf + done +} + +config_prefix() { + echo "$1" | grep -oP '^[a-z]+-[a-z]+' +} + +current_ssid() { + nmcli -t -f active,ssid dev wifi 2>/dev/null \ + | awk -F: '/^yes/{print $2}' | head -1 +} + +rofi_pick() { + rofi -dmenu -p ">" +} + +wg_down() { + local iface="$1" + sudo bash -c " + wg-quick down '$iface' 2>/dev/null || true + ip link delete '$iface' 2>/dev/null || true + while ip rule del not fwmark 51820 table 51820 2>/dev/null; do :; done + while ip rule del table main suppress_prefixlength 0 2>/dev/null; do :; done + ip route flush table 51820 2>/dev/null || true + while ip -6 rule del not fwmark 51820 table 51820 2>/dev/null; do :; done + while ip -6 rule del table main suppress_prefixlength 0 2>/dev/null; do :; done + ip -6 route flush table 51820 2>/dev/null || true + nft delete table inet wg-quick-'$iface' 2>/dev/null || true + resolvconf -u 2>/dev/null || true + " + local con + con=$(nmcli -t -f name,type con show --active 2>/dev/null \ + | awk -F: '/wireless/{print $1}' | head -1) + [[ -n "$con" ]] && nmcli con up "$con" 2>/dev/null +} + +vpn_connect() { + local iface="$1" + local return_fn="$2" + mapfile -t active < <(wg_active) + for a in "${active[@]}"; do + wg_down "$a" + done + sudo resolvconf -u 2>/dev/null + if sudo wg-quick up "$iface"; then + echo "$iface" > "$LAST_VPN" + notify "vpn" "connected: $iface" + else + notify "vpn" "error: $iface" + $return_fn + fi +} + + +vpn_servers() { + local location="$1" + mapfile -t active < <(wg_active) + mapfile -t configs < <(wg_configs) + + local options="" + for cfg in "${configs[@]}"; do + [[ $(config_prefix "$cfg") != "$location" ]] && continue + if printf '%s\n' "${active[@]}" | grep -qx "$cfg"; then + options+="$cfg (on)\n" + else + options+="$cfg\n" + fi + done + options+="back" + + local choice + choice=$(echo -e "$options" | rofi_pick) + [[ "$choice" == "back" || -z "$choice" ]] && { vpn_locations; return; } + + local iface="${choice/ (on)/}" + + if printf '%s\n' "${active[@]}" | grep -qx "$iface"; then + if wg_down "$iface"; then + notify "vpn" "disconnected: $iface" + else + notify "vpn" "error: $iface" + fi + vpn_servers "$location" + else + vpn_connect "$iface" "vpn_servers $location" + fi +} + +vpn_locations() { + mapfile -t configs < <(wg_configs) + + declare -A seen + local locations="" + for cfg in "${configs[@]}"; do + local prefix + prefix=$(config_prefix "$cfg") + if [[ -n "$prefix" && -z "${seen[$prefix]+x}" ]]; then + seen[$prefix]=1 + locations+="$prefix\n" + fi + done + locations+="back" + + local location + location=$(echo -e "$locations" | rofi_pick) + [[ "$location" == "back" || -z "$location" ]] && { vpn_menu; return; } + + vpn_servers "$location" +} + +vpn_menu() { + local active_vpn + active_vpn=$(wg_active | head -1) + + local toggle_label + [[ -n "$active_vpn" ]] && toggle_label="on" || toggle_label="off" + + local choice + choice=$(printf 'locations\n%s\nback\n' "$toggle_label" | rofi_pick) + + case "$choice" in + locations) vpn_locations ;; + on|off) + if [[ -n "$active_vpn" ]]; then + if wg_down "$active_vpn"; then + notify "vpn" "disconnected: $active_vpn" + else + notify "vpn" "error: $active_vpn" + vpn_menu + fi + else + local last="" + [[ -f "$LAST_VPN" ]] && last=$(cat "$LAST_VPN") + if [[ -n "$last" ]]; then + vpn_connect "$last" vpn_menu + else + notify "vpn" "no previous server, pick one from locations" + vpn_menu + fi + fi + ;; + back) main_menu ;; + esac +} + +wifi_menu() { + local ssid + ssid=$(current_ssid) + + local choice + choice=$(printf 'scan\ndisconnect\nback' | rofi_pick) + + case "$choice" in + scan) + nmcli dev wifi rescan 2>/dev/null + local networks + networks=$(nmcli -t -f ssid,signal,security dev wifi list 2>/dev/null \ + | awk -F: 'NF>=1 && $1!="" {printf "%-36s %s %s\n", $1, $2, $3}' \ + | sort -k2 -rn | head -40) + + local picked + picked=$(echo "$networks" | rofi_pick) + [[ -z "$picked" ]] && { wifi_menu; return; } + + local target + target=$(echo "$picked" | awk '{print $1}') + + if ! nmcli dev wifi connect "$target" 2>/dev/null; then + local pass + pass=$(rofi -dmenu -password -p "password >" < /dev/null) + [[ -z "$pass" ]] && { wifi_menu; return; } + nmcli dev wifi connect "$target" password "$pass" \ + && notify "wifi" "connected: $target" \ + || notify "wifi" "failed: $target" + else + notify "wifi" "connected: $target" + fi + wifi_menu + ;; + disconnect) + local con + con=$(nmcli -t -f name,type con show --active \ + | awk -F: '/wireless/{print $1}' | head -1) + [[ -n "$con" ]] \ + && nmcli con down "$con" && notify "wifi" "disconnected" \ + || notify "wifi" "nothing to disconnect" + wifi_menu + ;; + back) main_menu ;; + esac +} + +main_menu() { + local ssid + ssid=$(current_ssid) + local active_vpn + active_vpn=$(wg_active | head -1) + + local choice + choice=$(printf 'wifi%s\nvpn%s\n' \ + "${ssid:+ ($ssid)}" \ + "${active_vpn:+ ($active_vpn)}" \ + | rofi_pick) + + case "$choice" in + wifi*) wifi_menu ;; + vpn*) vpn_menu ;; + esac +} + +main_menu |
