File size: 9,291 Bytes
f53e03f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/bin/bash

echo "=== [WiFi Setup Script] Starting... ==="

# WiFi network configuration (set via env or flags)
# Usage:
#   WIFI_SSID="MyWifi" WIFI_PASSWORD="secret" WIFI_GATEWAY="192.168.x.x" ./setup_wifi.sh
#   ./setup_wifi.sh --ssid "MyWifi" --password "secret" --interface "wlan0" --gateway "192.168.x.x"
WIFI_SSID="${WIFI_SSID:-}"
WIFI_PASSWORD="${WIFI_PASSWORD:-}"
CONNECTION_NAME="${CONNECTION_NAME:-}"
WIFI_INTERFACE="${WIFI_INTERFACE:-}"
FALLBACK_SSID="${FALLBACK_SSID:-}"

usage() {
    cat << 'USAGE_EOF'
Usage: setup_wifi.sh [options]

Options:
  --ssid <ssid>            WiFi SSID (required)
  --password <password>    WiFi password (required for secured networks)
  --interface <ifname>     WiFi interface (optional; auto-detect if omitted)
  --connection <name>      Connection profile name (optional; defaults to SSID)
  --gateway <ip>           Gateway IP (optional; sets route/DNS)
  --fallback-ssid <ssid>   Fallback SSID (optional)
  -h, --help               Show this help

You can also set environment variables:
  WIFI_SSID, WIFI_PASSWORD, WIFI_INTERFACE, CONNECTION_NAME, FALLBACK_SSID, WIFI_GATEWAY,
  ROUTE_CLEANUP_GW
USAGE_EOF
}

while [ $# -gt 0 ]; do
    case "$1" in
        --ssid) WIFI_SSID="$2"; shift 2 ;;
        --password) WIFI_PASSWORD="$2"; shift 2 ;;
        --interface) WIFI_INTERFACE="$2"; shift 2 ;;
        --connection) CONNECTION_NAME="$2"; shift 2 ;;
        --fallback-ssid) FALLBACK_SSID="$2"; shift 2 ;;
        --gateway) WIFI_GATEWAY="$2"; shift 2 ;;
        -h|--help) usage; exit 0 ;;
        *)
            echo "[!] Unknown option: $1"
            usage
            exit 2
            ;;
    esac
done

if [ -z "$WIFI_SSID" ]; then
    echo "[βœ—] Missing WiFi SSID. Provide --ssid or WIFI_SSID."
    usage
    exit 2
fi

if [ -z "$CONNECTION_NAME" ]; then
    CONNECTION_NAME="$WIFI_SSID"
fi

if [ -z "$WIFI_INTERFACE" ]; then
    WIFI_INTERFACE=$(nmcli -t -f DEVICE,TYPE device status | awk -F: '$2=="wifi"{print $1; exit}')
fi

if [ -z "$WIFI_INTERFACE" ]; then
    echo "[βœ—] No WiFi interface detected. Provide --interface or WIFI_INTERFACE."
    exit 2
fi

# Network configuration
# If WIFI_GATEWAY is set, routing and DNS will be configured to use it.
WIFI_GATEWAY="${WIFI_GATEWAY:-}"
# Optional default gateway to remove from routing table.
ROUTE_CLEANUP_GW="${ROUTE_CLEANUP_GW:-}"
WIRED_CONNECTION="Wired connection 1"

# Step 1: Unblock and enable WiFi
echo "[1] Unblocking WiFi and enabling interface..."
sudo rfkill unblock wifi
sudo ip link set $WIFI_INTERFACE up

# Step 2: Scan for networks to verify NetworkManager is working
echo "[2] Scanning for WiFi networks..."
sudo nmcli device wifi rescan
sleep 3

# Step 3: Check if the target network is visible
echo "[3] Checking for '$WIFI_SSID' network..."
if sudo nmcli device wifi list | grep -q "$WIFI_SSID"; then
    echo "[βœ“] Network '$WIFI_SSID' found in scan"
    # Try direct connection
    echo "[4] Attempting direct connection to '$WIFI_SSID'..."
    if [ -n "$WIFI_PASSWORD" ]; then
        CONNECT_CMD=(sudo nmcli device wifi connect "$WIFI_SSID" password "$WIFI_PASSWORD")
    else
        CONNECT_CMD=(sudo nmcli device wifi connect "$WIFI_SSID")
    fi
    if "${CONNECT_CMD[@]}"; then
        echo "[βœ“] Successfully connected directly"
        CONNECTION_SUCCESS=true
    else
        echo "[!] Direct connection failed, trying manual profile method..."
        CONNECTION_SUCCESS=false
    fi
else
    echo "[!] Network '$WIFI_SSID' not found in scan (possibly hidden)"
    CONNECTION_SUCCESS=false
fi

# Step 4: If direct connection failed or network not found, create manual connection profile
if [ "$CONNECTION_SUCCESS" != "true" ]; then
    echo "[4] Creating manual connection profile for '$WIFI_SSID'..."
    
    # Remove existing connection profile if it exists
    sudo nmcli connection delete "$CONNECTION_NAME" 2>/dev/null || true
    
    # Create new connection profile
    if [ -n "$WIFI_PASSWORD" ]; then
        ADD_ARGS=(wifi-sec.key-mgmt wpa-psk wifi-sec.psk "$WIFI_PASSWORD")
    else
        ADD_ARGS=()
    fi
    if sudo nmcli connection add type wifi con-name "$CONNECTION_NAME" ifname "$WIFI_INTERFACE" ssid "$WIFI_SSID" "${ADD_ARGS[@]}"; then
        echo "[βœ“] Connection profile created successfully"
        
        echo "[5] Activating connection profile..."
        if sudo nmcli connection up "$CONNECTION_NAME"; then
            echo "[βœ“] Connection profile activated successfully"
            CONNECTION_SUCCESS=true
        else
            echo "[βœ—] Failed to activate connection profile"
            CONNECTION_SUCCESS=false
        fi
    else
        echo "[βœ—] Failed to create connection profile"
        CONNECTION_SUCCESS=false
    fi
fi

# Step 5: Configure network routing priorities if connection successful
if [ "$CONNECTION_SUCCESS" = "true" ]; then
    echo "[5] Configuring network routing priorities..."
    
    # Set WiFi connection to high priority (low metric)
    echo "    Setting WiFi connection priority to 100..."
    sudo nmcli connection modify "$CONNECTION_NAME" ipv4.route-metric 100
    
    # Set wired connection to very low priority (high metric) 
    echo "    Setting wired connection priority to 30000..."
    sudo nmcli connection modify "$WIRED_CONNECTION" ipv4.route-metric 30000 2>/dev/null || true
    
    # Remove any problematic default routes
    echo "    Cleaning up routing table..."
    if [ -n "$ROUTE_CLEANUP_GW" ]; then
        sudo ip route del default via "$ROUTE_CLEANUP_GW" 2>/dev/null || true
    fi
    
    # Ensure WiFi route has highest priority
    if [ -n "$WIFI_GATEWAY" ]; then
        sudo ip route add default via "$WIFI_GATEWAY" dev "$WIFI_INTERFACE" metric 50 2>/dev/null || true
        
        # Configure DNS to use router and public DNS
        echo "    Configuring DNS..."
        sudo tee /etc/resolv.conf > /dev/null << DNS_EOF
nameserver $WIFI_GATEWAY
nameserver 8.8.8.8
nameserver 1.1.1.1
DNS_EOF
    fi
    
    echo "[βœ“] Network routing configured for WiFi priority"
fi

# Step 6: Verify connection status
echo "[6] Checking connection status..."
if [ "$CONNECTION_SUCCESS" = "true" ]; then
    CURRENT_CONNECTION=$(nmcli device status | grep "$WIFI_INTERFACE" | awk '{print $4}')
    if [[ "$CURRENT_CONNECTION" == "$CONNECTION_NAME" ]] || [[ "$CURRENT_CONNECTION" == "$WIFI_SSID" ]]; then
        echo "[βœ“] Successfully connected to '$WIFI_SSID'"
        echo "    Interface: $WIFI_INTERFACE"
        echo "    Connection: $CURRENT_CONNECTION"
    else
        echo "[!] Connection status unclear"
        CONNECTION_SUCCESS=false
    fi
fi

# Step 7: Test internet connectivity
if [ "$CONNECTION_SUCCESS" = "true" ]; then
    echo "[7] Testing internet connectivity..."
    MAX_RETRIES=3
    COUNT=0
    INTERNET_OK=false
    
    while [ "$COUNT" -lt "$MAX_RETRIES" ]; do
        if ping -c 2 -W 5 8.8.8.8 >/dev/null 2>&1; then
            echo "[βœ“] Internet connectivity verified (ping test)"
            
            # Also test DNS resolution
            if curl -s --connect-timeout 5 -I http://google.com >/dev/null 2>&1; then
                echo "[βœ“] DNS resolution and HTTP connectivity verified"
                INTERNET_OK=true
                break
            else
                echo "[!] DNS/HTTP test failed, but ping works. Retrying... ($((COUNT+1))/$MAX_RETRIES)"
            fi
        else
            echo "[!] Internet test failed. Retrying... ($((COUNT+1))/$MAX_RETRIES)"
        fi
        
        sleep 3
        ((COUNT++))
    done
    
    if [ "$INTERNET_OK" != "true" ]; then
        echo "[!] Internet connectivity test failed after $MAX_RETRIES attempts"
        CONNECTION_SUCCESS=false
    fi
fi

# Step 8: Fallback to previous network if connection failed
if [ "$CONNECTION_SUCCESS" != "true" ] && [ -n "$FALLBACK_SSID" ]; then
    echo "[8] Connection to '$WIFI_SSID' failed. Attempting fallback to '$FALLBACK_SSID'..."
    
    # Try to connect to fallback network
    if sudo nmcli device wifi list | grep -q "$FALLBACK_SSID"; then
        echo "[!] Attempting to connect to fallback network '$FALLBACK_SSID'..."
        if sudo nmcli device wifi connect "$FALLBACK_SSID"; then
            echo "[βœ“] Connected to fallback network '$FALLBACK_SSID'"
            
            # Apply routing fixes for fallback network too
            echo "    Applying routing fixes for fallback network..."
            if [ -n "$ROUTE_CLEANUP_GW" ]; then
                sudo ip route del default via "$ROUTE_CLEANUP_GW" 2>/dev/null || true
            fi
            sudo nmcli connection modify "$WIRED_CONNECTION" ipv4.route-metric 30000 2>/dev/null || true
        else
            echo "[βœ—] Failed to connect to fallback network"
        fi
    else
        echo "[!] Fallback network '$FALLBACK_SSID' not available"
    fi
fi

# Step 9: Final status report
echo "[9] Final WiFi status:"
nmcli device status | grep wifi
echo ""
echo "Active connections:"
nmcli connection show --active | head -5
echo ""
echo "Current routing table:"
ip route show | head -5
echo ""
echo "DNS configuration:"
cat /etc/resolv.conf | grep nameserver

echo "=== [WiFi Setup Script] Completed ==="

# Exit with appropriate code
if [ "$CONNECTION_SUCCESS" = "true" ]; then
    exit 0
else
    exit 1
fi