forked from hotice/AP-Hotspot
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathap-hotspot
476 lines (447 loc) · 12.9 KB
/
ap-hotspot
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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
#!/bin/bash
# Script to set up a WiFi Hotspot in Ubuntu that works with
# Android and Windows Phone.
#
# Copyright (C) 2014 Alin Andrei <[email protected]>
# Copyright (C) 2014 Satyajit sahoo
# Copyright (C) 2014 Roessler Alexander <[email protected]>
#
# This scipt is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 3 of the License,
# or (at your option) any later version.
#
# The script is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this script. If not, see <http://www.gnu.org/licenses/>.
# Global variables
logfile="/tmp/hostapd.log"
pidfile="/tmp/hotspot.pid"
hotspotconfig="/etc/ap-hotspot.conf"
dnsmasqconfig="/etc/dnsmasq.d/ap-hotspot.rules"
systemdservice="/lib/systemd/ap-hotspot.service"
systemdsymlink="/etc/systemd/system/ap-hotspot.service"
user=$(who | awk '{print $1}' | sed '/^root$/d' | uniq)
WMPID=$(ps -u $user | tail -n 1 | awk '{print $1}')
DBUS=$(egrep -z 'DBUS_SESSION_BUS_ADDRESS|DISPLAY' /proc/${WMPID}/environ | sed -r -e 's/(.)DBUS_/\1 DBUS_/' -e 's/(.)DISPLAY/\1 DISPLAY/')
startup_delay=20
if command -v route > /dev/null; then
IFCONFIG_EXISTS="yes"
else
IFCONFIG_EXISTS=
fi
if command -v service > /dev/null; then
UPSTART_EXISTS="yes"
else
UPSTART_EXISTS=
fi
if command -v systemctl > /dev/null; then
SYSTEMD_EXISTS="yes"
else
SYSTEMD_EXISTS=
fi
if command -v wicd > /dev/null; then
WICD_EXISTS="yes"
else
WICD_EXISTS=
fi
if tput colors &> /dev/null; then
COLORS="YES"
else
COLORS=
fi
show_msg() {
echo -e "$@"
}
show_info() {
if [[ $COLORS ]]; then
echo -e "\033[1;34m$@\033[0m"
else
echo -e "$@"
fi
}
show_warn() {
if [[ $COLORS ]]; then
echo -e "\033[1;33m$@\033[0m"
else
echo -e "$@"
fi
}
show_err() {
if [[ $COLORS ]]; then
echo -e "\033[1;31m$@\033[0m" 1>&2
else
echo -e "$@"
fi
}
show_debug() {
while read input; do
[[ "$debug" == "true" ]] && echo -e "$input"
done
}
show_notify() {
su $user -s /bin/bash -c "${DBUS} notify-send -h int:transient:1 -i \"network-wireless\" \"$@\""
}
check_root() {
# Check if user is root
if [[ ! $(whoami) = "root" ]]; then
show_err "Please run the script as root"
exit 1
fi
}
check_supported() {
# Check if the wireless card supports Access Point mode. This script won't work if it doesn't support it
NL80211=1
if [[ ! $(iw list 2>&1 | grep -A6 "Supported interface modes" | grep AP$) ]]; then
if [[ $(iw list 2>&1) == "nl80211 not found." ]]; then
NL80211=0
if [[ ! $(hostapd -v 2>&1 | grep "hostapd v0.8.x") == "hostapd v0.8.x" ]]; then
show_err "You need hostapd version 0.8 for this driver to work"
exit 1
fi
else
show_err "Your wireless card or driver does not support Access Point mode"
exit 1
fi
fi
}
check_network() {
# Check if Wireless is disabled
if [[ $(iwconfig "$INTERFACE_WLAN" 2>&1 | grep "Tx-Power=off") ]]; then
show_err "WiFi is disabled, please enable WiFi before running this script"
exit 1
# Check if Wireless is enabled, but connected to a network
elif [[ ! $(iwconfig "$INTERFACE_WLAN" 2>&1 | grep "ESSID:off/any") && $(iwconfig "$INTERFACE_WLAN" 2>&1 | grep "ESSID:") ]]; then
show_err "Please disconnect WiFi before proceeding"
exit 1
fi
}
check_connected() {
# Monitor logfile for connected devices
lines_con="0"
lines_dis="0"
while [[ -f "$logfile" ]]; do
if [[ "$lines_con" < $(grep -c "AP-STA-CONNECTED" "$logfile") ]]; then
show_notify "New device connected to Hotspot"
(( lines_con++ ))
elif [[ "$lines_dis" < $(grep -c "AP-STA-DISCONNECTED" "$logfile") ]]; then
show_notify "Device disconnected from Hotspot"
(( lines_dis++ ))
fi
sleep 5
done
}
check_systemd() {
if [[ ! $SYSTEMD_EXISTS ]]; then
show_err "Registering AP-Hotspot as service is only supported on systems with Systemd"
exit 1
fi
}
configure() {
# Check root
check_root
# Check supported
check_supported
[ $NL80211 -eq 0 ] && show_warn "Driver does not support nl80211, trying rtl871xdrv"
# Reset config
rm -f "$hotspotconfig"
rm -f "$dnsmasqconfig"
# Detect configuration
show_msg "Detecting configuration..."
#Figuring out Default Interent Interface
if command -v route > /dev/null; then
INTERFACE_NET=$(route | grep -iw "default" | awk '{print $NF}')
elif command -v ip > /dev/null; then
INTERFACE_NET=$(ip route | grep -iw "default" | awk '{print $5}')
fi
#Figuring out Wireless Interface
if command -v iwconfig > /dev/null; then #Checking presence of iwconfig
INTERFACE_WLAN=$(iwconfig 2>&1 | grep "^wlan" | sed -e 's/ .*//g' | tail -n 1) #Assuming interface uses old wlan convention
if [[ ! $INTERFACE_WLAN ]]; then
INTERFACE_WLAN=$(iwconfig 2>&1 | grep "^wlp" | sed -e 's/ .*//g' | tail -n 1) #Assuming interface uses new wlp convention
fi
elif command -v iw > /dev/null; then
INTERFACE_WLAN=$(iw dev 2>&1 | grep "wlan" | awk '{print $2'} | tail -n 1)
if [[ ! $INTERFACE_WLAN ]]; then
INTERFACE_WLAN=$(iwconfig 2>&1 | grep "^wlp" | sed -e 's/ .*//g' | tail -n 1)
fi
fi
SSID="myhotspot"
WPAPASS="qwerty0987"
# Network interface connected to the Internet
if [[ ! $INTERFACE_NET ]]; then
show_warn "Failed to detect the network interface connected to the Internet. Please enter your network interface (e.g.- eth1):"
else
show_msg "Detected $INTERFACE_NET as the network interface connected to the Internet. Press ENTER if this is correct or enter the desired interface below (e.g.- eth0, ppp0 etc.):"
fi
read interface_net
[[ "$interface_net" ]] && INTERFACE_NET="$interface_net"
# WiFi interface
if [[ ! $INTERFACE_WLAN ]]; then
show_warn "Failed to detect the WiFi interface. Please enter your WiFi interface (e.g.- wlan0):"
else
show_msg "Detected $INTERFACE_WLAN as your WiFi interface. Press ENTER if this is correct or enter the desired interface (e.g.- wlan1):"
fi
read interface_wlan
[[ "$interface_wlan" ]] && INTERFACE_WLAN="$interface_wlan"
# Hotspot SSID
show_msg "Enter the desired Access Point name or press ENTER to use the default one ($SSID):"
read ssid
[[ "$ssid" ]] && SSID="$ssid"
# WPA Passphrase
show_msg "Enter the desired WPA Passphrase below or press ENTER to use the default one ($WPAPASS):"
read wpapass
wpapass_size=${#wpapass}
if ! [ "$wpapass_size" -eq 0 -o "$wpapass_size" -ge 8 -a "$wpapass_size" -le 38 ]; then
show_err "WPA password must be between 8 and 38 characters long"
exit 1
fi
[[ "$wpapass" ]] && WPAPASS="$wpapass"
if [ $NL80211 -eq 1 ]; then
DRIVER=nl80211
else
DRIVER=rtl871xdrv
fi
# Write the hostapd config file
cat <<EOF | tee "$hotspotconfig" > /dev/null 2>&1
# WiFi Hotspot
interface=$INTERFACE_WLAN
driver=$DRIVER
#Access Point
ssid=$SSID
hw_mode=g
# WiFi Channel:
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=$WPAPASS
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF
# Add the required bits to the dnsmasq config file
if [[ ! $(grep "Bind to only one interface" "$dnsmasqconfig" > /dev/null 2>&1) ]]; then
cat <<EOF | tee "$dnsmasqconfig" > /dev/null 2>&1
# Bind to only one interface
bind-interfaces
# Choose interface for binding
interface=$INTERFACE_WLAN
# Specify range of IP addresses for DHCP leases
dhcp-range=192.168.150.2,192.168.150.10,12h
#INTERFACE_NET=$INTERFACE_NET
EOF
chmod +x "$dnsmasqconfig"
fi
}
get_vars() {
# Run Configuration Wizard if config files don't exist
[[ ! -f "$hotspotconfig" || ! -f "$dnsmasqconfig" ]] && configure
# Get $INTERFACE_NET and $INTERFACE_WLAN from the config files
INTERFACE_WLAN=$(grep "interface" "$hotspotconfig" | sed -e 's/interface=//g')
INTERFACE_NET=$(grep "INTERFACE_NET" "$dnsmasqconfig" | sed -e 's/#INTERFACE_NET=//g')
}
start() {
# Check previous process
if [[ -f "$pidfile" ]]; then
show_err "Another process is already running"
exit 1
fi
# Check root
check_root
# Check supported
check_supported
# Get variables
get_vars
# Check network
check_network
# Write the PID to a file
echo "$$" > "$pidfile"
show_info "Starting Wireless Hotspot..."
# Set up the services
if [[ $UPSTART_EXISTS ]]; then
service hostapd stop 2>&1 | show_debug
service dnsmasq stop 2>&1 | show_debug
if [[ $WICD_EXISTS ]]; then
service wicd stop 2>&1 | show_debug
fi
update-rc.d hostapd disable 2>&1 | show_debug
update-rc.d dnsmasq disable 2>&1 | show_debug
else
systemctl stop hostapd 2>&1 | show_debug
systemctl stop dnsmasq 2>&1 | show_debug
if [[ $WICD_EXISTS ]]; then
systemctl stop wicd 2>&1 | show_debug
fi
systemctl disable hostapd 2>&1 | show_debug
systemctl disable dnsmasq 2>&1 | show_debug
fi
# Configure IP address for WLAN
if [[ $IFCONFIG_EXISTS ]]; then
ifconfig "$INTERFACE_WLAN" 192.168.150.1 2>&1 | show_debug
else #using ip command
ip addr flush dev "$INTERFACE_WLAN" 2>&1 | show_debug
ip addr add 192.168.150.1 dev "$INTERFACE_WLAN" 2>&1 | show_debug
fi
# Start DHCP/DNS server
if [[ $UPSTART_EXISTS ]]; then
service dnsmasq restart 2>&1 | show_debug
else
systemctl restart dnsmasq 2>&1 | show_debug
fi
# Enable routing
sysctl net.ipv4.ip_forward=1 2>&1 | show_debug
# Enable NAT
iptables -t nat -A POSTROUTING -o "$INTERFACE_NET" -j MASQUERADE 2>&1 | show_debug
# Run access point daemon
if [[ $(hostapd --help 2>&1 | grep "\-f") ]]; then
rm -f "$logfile"
touch "$logfile"
hostapd -B "$hotspotconfig" -f "$logfile"
while :
do
[[ $(grep "Using interface" "$logfile") ]] && show_info "Wireless Hotspot active" && show_notify "Wireless Hotspot active" && break
sleep 5
done
check_connected 2>&1 &
disown
else
hostapd -B "$hotspotconfig" 2>&1 | show_debug
show_info "Wireless Hotspot active"
fi
}
stop() {
# Check root
check_root
# Get variables
get_vars
# Kill process
show_info "Stopping Wireless Hotspot..."
if [[ -f "$pidfile" ]]; then
pid=$(cat "$pidfile")
rm -f "$pidfile"
[[ $(grep -s "ap-hotspot" "/proc/$pid/cmdline") ]] && kill -9 "$pid"
fi
# Delete log
rm -f "$logfile"
# Disable NAT
iptables -D POSTROUTING -t nat -o "$INTERFACE_NET" -j MASQUERADE 2>&1 | show_debug
# Disable routing
sysctl net.ipv4.ip_forward=0 2>&1 | show_debug
# Set up the services
if [[ $UPSTART_EXISTS ]]; then
service hostapd stop 2>&1 | show_debug
service dnsmasq stop 2>&1 | show_debug
if [[ $WICD_EXISTS ]]; then
service wicd start 2>&1 | show_debug
fi
else
systemctl stop hostapd 2>&1 | show_debug
systemctl stop dnsmasq 2>&1 | show_debug
if [[ $WICD_EXISTS ]]; then
systemctl start wicd 2>&1 | show_debug
fi
fi
# Disable WiFi and disable newly created mon.WLAN network
if [[ $IFCONFIG_EXISTS ]]; then
if [[ ! -z $(ifconfig | grep "mon.$INTERFACE_WLAN") ]]; then
# Check if the hotspot is active
ifconfig "mon.$INTERFACE_WLAN" down
fi
ifconfig "$INTERFACE_WLAN" down
else #Using ip command
if [[ ! -z $(ip addr | grep "mon.$INTERFACE_WLAN") ]]; then
# Check if the hotspot is active
ip link set "mon.$INTERFACE_WLAN" down
fi
ip link set "$INTERFACE_WLAN" down
ip link set "$INTERFACE_WLAN" up
fi
}
restart() {
show_info "Restarting Wireless Hotspot..."
stop
start
}
enable() {
# Check root
check_root
# Check systemd
check_systemd
show_info "Enabling Wireless Hotspot Service"
# Write systemd service file
cat <<EOF | tee "$systemdservice" > /dev/null 2>&1
[Unit]
Description=Creates a Wifi access point
After=syslog.target network.target
[Service]
Type=oneshot
RemainAfterExit=yes
KillMode=none
ExecStart=/bin/bash -c "sleep $startup_delay; /usr/bin/ap-hotspot start"
ExecStop=/bin/bash -c "/usr/bin/ap-hotspot stop"
[Install]
WantedBy=multi-user.target
EOF
# Create symlink
ln -f "$systemdservice" "$systemdsymlink"
# Register service
systemctl daemon-reload
systemctl enable ap-hotspot.service
if [[ $WICD_EXISTS ]]; then
if [[ $UPSTART_EXISTS ]]; then
update-rc.d wicd disable 2>&1 | show_debug
else
systemctl disable wicd 2>&1 | show_debug
fi
fi
}
disable() {
# Check root
check_root
# Check systemd
check_systemd
show_info "Disabling Wireless Hotspot Service"
# Disable service
systemctl disable ap-hotspot.service
if [[ $WICD_EXISTS ]]; then
if [[ $UPSTART_EXISTS ]]; then
update-rc.d wicd enable 2>&1 | show_debug
else
systemctl enable wicd 2>&1 | show_debug
fi
fi
# Remove files
rm "$systemdsymlink"
rm "$systemdservice"
}
case "$1" in
start)
start;;
stop)
stop;;
restart)
restart;;
enable)
enable;;
disable)
disable;;
configure)
configure;;
debug)
debug="true"
start;;
*)
args=( "start" "stop" "restart" "enable" "disable" "configure" "debug" )
desc=( "start wireless hotspot" "stop wireless hotspot" "restart wireless hotspot" "enable wireless hotspot service" "disable wireless hotspot service" "configure hotspot" "start with detailed messages" )
echo -e "Usage:\tap-hotspot [argument]\n"
for ((i=0; i < ${#args[@]}; i++)); do
printf "\t%-15s%-s\n" "${args[i]}" "${desc[i]}"
done
exit;;
esac