-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathwizard-run
733 lines (683 loc) · 32.4 KB
/
wizard-run
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
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
#!/bin/vbash
#
# EdgeMAX Wizard "WireGuard" created 11/2021 by CHiL.at
# Version 1.7-20230916-pre
# ^-- previous line is used for version identification, dont remove this line!
#
# Github repository: https://github.com/vchrizz/ER-wizard-WireGuard/
#
# Works on all EdgeRouter and EdgePoint devices (EdgeOS versions 1.9.0+ and 2.0+)
#
wgdir="/config/user-data/wireguard/"
wgsettings="${wgdir}wgsettings.json"
wgsetupscriptfile="/config/scripts/post-config.d/wireguard_setup.sh"
wgautoupdatecronjob="/etc/cron.daily/wireguard_autoupdate"
log="${wgdir}wireguard-wizard.log"
wgpkgapi="https://api.github.com/repos/WireGuard/wireguard-vyatta-ubnt/releases/latest"
wgwizapi="https://api.github.com/repos/vchrizz/ER-wizard-WireGuard/releases/latest"
#
# DO NOT EDIT BELOW HERE !
#
ACTION=$1
INPUT=$2
# vyatta configuration node for wireguard
wgcfg="interfaces wireguard"
cmd=/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper
run=/opt/vyatta/bin/vyatta-op-cmd-wrapper
cli=cli-shell-api
# Viatta cli DOC in: https://vyos.dev/w/development/cli-shell-api/
# if wizard log is greater than 256KB then overwrite with new content
if [ $(wc -c <$log) -ge 262144 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] EdgeMAX WireGuard Wizard started - Session="$$ >$log
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] EdgeMAX WireGuard Wizard started - Session="$$ >>$log
fi
writesetupscript () {
mkdir -p $(dirname $wgsetupscriptfile)
cat >$wgsetupscriptfile <<'ENDSCRIPTCONTENT'
#!/bin/bash
wgdir="/config/user-data/wireguard/"
log="${wgdir}/wireguard-wizard-setup.log"
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] Running WireGuard setup script ..." >$log
wireguardwizard=""
for i in $(find /config/wizard/feature/ -name wizard-run); do
if [ "$(head $i -n 10 | grep -i 'wireguard')" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] WireGuard wizard found at $(dirname $i)" >>$log
wireguardwizard=$i
break
fi
done
if [ ! -f $wireguardwizard ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] Error: WireGuard wizard not found! Exit." >>$log
exit 1
fi
# Check if already installed, do nothing:
dpkg -l wireguard >>$log 2>>$log
if [ $? == 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] wireguard package already installed! Exit" >>$log
exit 0
fi
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] Running install function from wizard ... " >>$log
$wireguardwizard install >>$log
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [setup] Finished WireGuard setup script..." >>$log
exit 0
ENDSCRIPTCONTENT
chmod +x $wgsetupscriptfile
}
writecronjob () {
cat >$wgautoupdatecronjob <<'ENDSCRIPTCONTENT'
#!/bin/bash
wgdir="/config/user-data/wireguard/"
log="${wgdir}/wireguard-wizard.log"
wireguardwizard=""
for i in $(find /config/wizard/feature/ -name wizard-run); do
if [ "$(head $i -n 10 | grep -i 'wireguard')" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] WireGuard wizard found at $(dirname $i)" >>$log
wireguardwizard=$i
break
fi
done
if [ ! -f $wireguardwizard ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] Error: WireGuard wizard not found!" >>$log
exit 1
else
onlinecheck="false"
curl -s --retry 12 --retry-max-time 60 --retry-connrefused --connect-timeout 3 https://api.github.com >/dev/null
if [ $? == 0 ]; then
onlinecheck="true"
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] online-check succeeded ..."
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] online-check failed. Exit."
exit 1
fi
if [[ "$($wireguardwizard load | jq -r .data.pkgstatus)" =~ .*new version found.* ]]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] New WireGuard package version found, upgrading ..." >>$log
if [ "$onlinecheck" == "true" ]; then
rm -f ${wgdir}/*.deb
$wireguardwizard install >>$log
fi
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] Current WireGuard package version is up-to-date." >>$log
fi
if [[ "$($wireguardwizard load | jq -r .data.wizstatus)" =~ .*new version found.* ]]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] New WireGuard wizard version found, upgrading ..." >>$log
if [ "$onlinecheck" == "true" ]; then
rm -f ${wgdir}/ER-wizard-WireGuard.tar
# remove stale setupscript
rm -f /config/scripts/post-config.d/wireguard_setup.sh
# remove stale wgsettings files
rm -f ${wgdir}wgsettings.*
$wireguardwizard install >>$log
fi
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [autoupdate] Current WireGuard wizard version is up-to-date." >>$log
fi
fi
exit 0
ENDSCRIPTCONTENT
chmod +x $wgautoupdatecronjob
}
installwireguard () {
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Starting installation of WireGuard from $wgdir ..."
mkdir -p $wgdir
cd $wgdir
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] check if we are online (if we can reach github.com) ..."
onlinecheck="false"
curl -s --retry 12 --retry-max-time 60 --retry-connrefused --connect-timeout 3 https://api.github.com >/dev/null
if [ $? == 0 ]; then
onlinecheck="true"
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] online-check succeeded ..."
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] online-check failed ..."
fi
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Check system where we are running ..."
edgerouterhw=$(/usr/sbin/ubnt-hal-e getBoardIdE | sed 's/[0-9]$/0/')
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Detected EdgeRouter $edgerouterhw system ..."
edgeosversion=$(/usr/sbin/ubnt-hal show-version | awk '/Version/{split($2,v,".");print v[1];exit}')
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Detected EdgeOS version $edgeosversion ..."
pkgvariant="$edgerouterhw-$edgeosversion"
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Checking for $pkgvariant deb-file in $(pwd) ..."
for file in $(find $wgdir -name ${pkgvariant}*.deb); do
if [[ "$file" =~ /${pkgvariant}*.deb/ ]]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] File $pkgvariant deb-file in $(pwd) found: $file ..."
wgpackage=$file
break
fi
done
if [ "$1" == "forceupgrade" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] -> Forced upgrade from wizard ..."
if [ "$onlinecheck" == "true" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] We are online, remove ${pkgvariant} deb-file and download new one ..."
rm -f ${wgdir}/${pkgvariant}*.deb
rm -f ${wgdir}/ER-wizard-WireGuard.tar
fi
fi
if [ ! -f "$wgpackage" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard deb-file not found, need to download from latest release ..."
if [ "$onlinecheck" == "true" ]; then
curl -sLo /tmp/wgpkglatest ${wgpkgapi}
pkgurl=$(jq -r '.assets[].browser_download_url | select(contains("'$pkgvariant'"))' /tmp/wgpkglatest)
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Download of WireGuard starting from $pkgurl ..."
curl -sLO $pkgurl
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] download done."
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Error: we are not online, can not download. Missing deb-file. Exit."
exit 1
fi
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard deb-file $pkgvariant found in $(pwd) ..."
fi
# Check if already installed do https://github.com/WireGuard/wireguard-vyatta-ubnt/wiki/EdgeOS-and-Unifi-Gateway#upgrade
# else install reusing last config or install normally if no config (no need for restart):
dpkg -l wireguard
if [ $? == 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Upgrading WireGuard for $pkgvariant ..."
eval "interfaces=($($cli listActiveNodes $wgcfg))"
$cmd begin
for interface in "${interfaces[@]}"; do
$cmd set $wgcfg "$interface" route-allowed-ips false
$cmd commit
done
$cmd delete $wgcfg
$cmd commit
rmmod wireguard
dpkg -i ${pkgvariant}*.deb
modprobe wireguard
# The loaded configuration becomes the working configuration and must be committed before it becomes the active configuration.
# config file is saved
$cmd load
$cmd commit
# No need to save, config is restored from file (load) then commited to active config.
$cmd end
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Installing WireGuard for $pkgvariant ..."
# if we have the previous config from wireguard on config.boot (currently loaded config) then:
# TODO(tekert): test this
eval "interfaces=($($cli listActiveNodes $wgcfg))"
if [ "${interfaces[0]}" == "wg0" ]; then
$cmd begin
$cmd delete $wgcfg
$cmd commit
dpkg -i ${pkgvariant}*.deb
modprobe wireguard
$cmd load
$cmd commit
$cmd end
else
dpkg -i ${pkgvariant}*.deb
modprobe wireguard
fi
fi
# Security alert, only update if the user checked auto update or checked the box to manually do a forced update on Apply button.
if [ "$1" == "forceupgrade" ] || [ -w $wgautoupdatecronjob ]; then
if [ ! -f ER-wizard-WireGuard.tar ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard Wizard tar-file not found, need to download from latest release ..."
if [ "$onlinecheck" == "true" ]; then
curl -sLo /tmp/wgwizlatest ${wgwizapi}
wizurl=$(jq -r '.assets[].browser_download_url' /tmp/wgwizlatest)
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Download of Wizard starting from $wizurl ..."
curl -sLO $wizurl
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] download done."
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Error: we are not online, can not download. Missing tar-file. Exit."
exit 1
fi
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard Wizard tar-file found in $(pwd) - installing WireGuard Wizard..."
wireguardwizard=""
for i in $(find /config/wizard/feature/ -name wizard-run); do
if [ "$(head $i -n 10 | grep -i 'wireguard')" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard wizard found in $i" >>$log
wireguardwizard=$i
break
fi
done
fi
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] Installing WireGuard wizard ..."
tar -C $(dirname $wireguardwizard) -xf ER-wizard-WireGuard.tar
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [installer] WireGuard and Wizard installation done."
fi
}
# function called when you click the wizard
load () {
###########################
# WireGuard LOAD function #
###########################
[ ! -d $wgdir ] && mkdir -p $wgdir
wireguardwizard=""
for i in $(find /config/wizard/feature/ -name wizard-run); do
if [ "$(head $i -n 10 | grep -i 'wireguard')" ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] WireGuard wizard found at $i" >>$log
wireguardwizard=$i
break
fi
done
# try to install wireguard and show status (with version information if installed)
pkgstatus="\"pkgstatus\":\"error: not installed.\""
dpkg -l wireguard >>$log 2>>$log
if [ $? != 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] wireguard package not installed! need to install packages." >>$log
installwireguard >>$log 2>>$log
if [ $? == 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] wireguard package installed and configured. all done." >>$log
pkgstatus="\"pkgstatus\":\"success: running wireguard installation ... completed.\""
else
pkgstatus="\"pkgstatus\":\"error: not installed, download or install problem. check $log\""
fi
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] wireguard package already installed! checking for new version on disk ..." >>$log
# check if latest version is installed from packages available in $wgdir
version_installed=$(dpkg -l wireguard | awk '/ii/ { print $3 }')
version_latest=$(curl -s ${wgpkgapi} | jq -r .tag_name)
dpkg --compare-versions $version_latest gt $version_installed
if [ $? == 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] new wireguard package found: $version_latest" >>$log
pkgstatus="info: wireguard $version_installed installed. new version found: $version_latest"
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] latest available wireguard package is already installed: $version_installed (found in $wgdir)" >>$log
pkgstatus="success: wireguard $version_installed installed."
fi
pkgstatus="\"pkgstatus\":\"$pkgstatus\""
fi
# get wireguard process status if unning
procstatus=$(ps x | grep -v awk | awk '/wg/ { print $1" "$5 }' | sed ':a;N;$!ba;s/\n/ /g')
if [ -z "$procstatus" ]; then
procstatus="not running"
fi
procstatus="\"procstatus\":\"$procstatus\""
# get wizard update status
wiz_installed=$(awk '/Version/{print $3;exit}' $wireguardwizard)
if [ -z "$wiz_installed" ]; then
wizstatus="not available"
else
wiz_latest=$(curl -s ${wgwizapi} | jq -r .tag_name)
dpkg --compare-versions $wiz_latest gt $wiz_installed
if [ $? == 0 ]; then
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] new wireguard wizard found: $wiz_latest" >>$log
wizstatus="info: wizard $wiz_installed installed. new version found: $wiz_latest"
else
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] latest available wireguard wizard is already installed: $wiz_installed (found in $wgdir)" >>$log
wizstatus="success: wizard $wiz_installed installed."
fi
fi
wizstatus="\"wizstatus\":\"$wizstatus\""
# setup-config script in case of firmware upgrade
wgsetupscript='"wgsetupscript":""'
if [ -w $wgsetupscriptfile ]; then
wgsetupscript='"wgsetupscript":"on"'
fi
# auto-upgrade cronjob script
autoupdatefromgithub='"autoupdatefromgithub":""'
if [ -w $wgautoupdatecronjob ]; then
autoupdatefromgithub='"autoupdatefromgithub":"on"'
fi
#
# Read current configuration
#
# Checkbox "Enable"
wgenable="\"wgenable\":false"
eval "interfaces=($($cli listActiveNodes $wgcfg))"
if [ "${interfaces[0]}" == "wg0" ]; then
# existsActive: Returns 0 if specified node exists in the current active (running) configuration, 1 otherwise.
$cli existsActive $wgcfg ${interfaces[0]} disable
if [ $? == 1 ]; then
wgenable="\"wgenable\":\"on\"";
fi
fi
# Inputfield "Server Port"
eval "listenport=($($cli returnActiveValue $wgcfg ${interfaces[0]} listen-port))"
listenport="\"listen-port\":\"$listenport\""
# Checkbox "Route allowed IPs" (default value: true)
routeallowedips=""
routeallowedips_vyatta=$($cli returnActiveValue $wgcfg ${interfaces[0]} route-allowed-ips)
if [ -n "$routeallowedips_vyatta" ] && [ $routeallowedips_vyatta == "true" ]; then
routeallowedips="on"
fi
# Inputfield ip address
ipaddress=''
eval "ipaddrvalues=($($cli returnActiveValues $wgcfg ${interfaces[0]} address))"
for ipaddrvalue in "${ipaddrvalues[@]}"; do
[ -n "$ipaddress" ] && ipaddress+=','
ipaddress+="\"$ipaddrvalue\""
done
ipaddress="\"ipaddress\":[$ipaddress]"
# (disabled) Inputfield "My public key"
eval "privatekey=($($run show $wgcfg ${interfaces[0]} private-key))"
if [ -n "$privatekey" ]; then
localpubkey=$(echo "$privatekey" | /usr/bin/wg pubkey)
fi
localpubkey="\"localpubkey\":\"$localpubkey\""
# privatekeycfg can be a file path or key / privatekey always has a key
eval "privatekeycfg=($($cli returnActiveValue $wgcfg ${interfaces[0]} private-key))"
if [ -z "$privatekeycfg" ]; then
echo "[INFO] privatekeycfg=($($cli returnActiveValue $wgcfg ${interfaces[0]} private-key)) is empty!." >> $log
fi
# (hidden) Inputfield "private key"
privatekey="\"privatekey\":\"$privatekeycfg\""
# Inputfield allowed ips for peers QR code
eval "peersallowedips=($($run show configuration commands | awk '/wireguard-wizard-peers-allowed-ips/ {print $5}'))"
peersallowedips="\"peers-allowed-ips\":[\"$peersallowedips\"]"
peersallowedips=${peersallowedips//,/\",\"}
# Inputfield DNS for peers QR code
eval "peersdns=($($run show configuration commands | awk '/wireguard-wizard-peers-dns/ {print $5}'))"
peersdns="\"peers-dns\":[\"$peersdns\"]"
peersdns=${peersdns//,/\",\"}
# Inputfield endpoint for peers QR code
eval "peersendpoint=($($run show configuration commands | awk '/wireguard-wizard-peers-endpoint/ {print $5}'))"
peersendpoint="\"peers-endpoint\":\"$peersendpoint\""
# Peers:
# get current wireguard configuration and return configured values to wizard.html
peerlist=''
eval "peers=($($cli listActiveNodes $wgcfg ${interfaces[0]} peer))"
for peer in "${peers[@]}"; do
if [ -n "$peerlist" ]; then
peerlist+=",{\"public-key\":\"$peer\""
else
peerlist="{\"public-key\":\"$peer\""
fi
eval "settings=($($cli listActiveNodes $wgcfg ${interfaces[0]} peer $peer))"
for setting in "${settings[@]}"; do
if [ "$setting" == "allowed-ips" ]; then
allowedips=''
eval "values=($($cli returnActiveValues $wgcfg ${interfaces[0]} peer $peer allowed-ips))"
for value in "${values[@]}"; do
[ -n "$allowedips" ] && allowedips+=','
allowedips+="\"$value\""
done
[ -n "$allowedips" ] && allowedips="\"allowed-ips\":[$allowedips]" && peerlist+=",$allowedips"
fi
if [ "$setting" == "description" ]; then
description="$($cli returnActiveValue $wgcfg ${interfaces[0]} peer $peer description)"
[ -n "$description" ] && description="\"description\":\"$description\"" && peerlist+=",$description"
fi
if [ "$setting" == "endpoint" ]; then
eval "endpoint=($($cli returnActiveValue $wgcfg ${interfaces[0]} peer $peer endpoint))"
[ -n "$endpoint" ] && endpoint="\"endpoint\":\"$endpoint\"" && peerlist+=",$endpoint"
fi
if [ "$setting" == "persistent-keepalive" ]; then
eval "persistentkeepalive=($($cli returnActiveValue $wgcfg ${interfaces[0]} peer $peer persistent-keepalive))"
[ -n "$persistentkeepalive" ] && persistentkeepalive="\"persistent-keepalive\":\"$persistentkeepalive\"" && peerlist+=",$persistentkeepalive"
fi
if [ "$setting" == "preshared-key" ]; then
eval "presharedkey=($($cli returnActiveValue $wgcfg ${interfaces[0]} peer $peer preshared-key))"
[ -n "$presharedkey" ] && presharedkey="\"preshared-key\":\"$presharedkey\"" && peerlist+=",$presharedkey"
fi
done
latesthandshake="$(wg show wg0 latest-handshakes | grep "$peer" | awk '{print $2}')"
latesthandshakeago="$(expr $(date +%s) - $latesthandshake)"
latesthandshaketext="$(date -ud @$latesthandshakeago +'%M minutes %S seconds ago')"
[ -n "$latesthandshake" ] && [ "$latesthandshake" -gt 0 ] && latesthandshake="\"latesthandshake\":\"$latesthandshaketext\"" && peerlist+=",$latesthandshake"
peerlist+='}'
done
#
# get all variables together for output
#
echo "{\"success\":\"1\",\"data\":{ $pkgstatus,$procstatus,$wizstatus,$wgsetupscript,$autoupdatefromgithub,$wgenable,$listenport,\"route-allowed-ips\":\"$routeallowedips\",$ipaddress,$localpubkey,$privatekey,$peersallowedips,$peersdns,$peersendpoint,\"peerlist\":[$peerlist] }}"
}
# function called when you click apply
apply () {
parse () {
local var=$1
local exp=$2
local val=$(cat $INPUT | jq "$exp" 2>/dev/null)
if [ $(expr index "$exp" []) -eq 0 ]; then
eval "$var=$val"
else
eval "$var=($val)"
fi
}
# setup script
if [ "$(jq -M -r '.wgsetupscript' $INPUT 2>/dev/null)" == "on" ]; then
#if [ ! -f $wgsetupscriptfile ]; then
writesetupscript
#fi
else
rm -f $wgsetupscriptfile >/dev/null 2>/dev/null
fi
# manual upgrade trigger via wizard
[ "$(jq -M -r '.updatefromgithub' $INPUT)" == "on" ] && installwireguard forceupgrade >>$log 2>>$log
# auto-upgrade script
if [ "$(jq -M -r '.autoupdatefromgithub' $INPUT 2>/dev/null)" == "on" ]; then
if [ ! -f $wgautoupdatecronjob ]; then
writecronjob
fi
else
rm -f $wgautoupdatecronjob >/dev/null 2>/dev/null
fi
############################
# WireGuard APPLY function #
############################
local ret=0
local output=''
local -A name
parse wgenable '."wgenable"'
parse privatekey '."privatekey"'
if [ "$wgenable" == "on" ] && [ -z "$privatekey" ]; then
# PROBLEM: EdgeOS WireGuard package "wireguard-vyatta-ubnt" has problems to handle private keys with slashes
# FIX: Retry generation of private keys until one is generated without (forward) slashes.
privatekey='/'
until [[ "$privatekey" != *\/* ]]; do
privatekey=$(wg genkey)
done
fi
parse listenport '."listen-port"'
parse routeallowedips '."route-allowed-ips"'
mapfile -t ipaddress < <(cat $INPUT | jq -c '."ipaddress"' | sed 's/,/ /g;s/\[//;s/\]//;s/\"//g')
#parse peersallowedips '."peers-allowed-ips"'
peersallowedips=$(cat $INPUT | jq -c '."peers-allowed-ips"' | sed 's/\[//;s/\]//;s/\"//g')
#parse peersdns '."peers-dns"'
peersdns=$(cat $INPUT | jq -c '."peers-dns"' | sed 's/\[//;s/\]//;s/\"//g')
parse peersendpoint '."peers-endpoint"'
parse pubkeys '."peerlist"[]|select(has("public-key"?))."public-key"?'
parse descriptions '."peerlist"[]|select(has("public-key"?))."description"?'
parse endpoints '."peerlist"[]|select(has("public-key"?))."endpoint"?'
parse presharedkeys '."peerlist"[]|select(has("public-key"?))."preshared-key"?'
parse persistentkeepalives '."peerlist"[]|select(has("public-key"?))."persistent-keepalive"?'
mapfile -t allowedips < <(cat $INPUT | jq -c '."peerlist"[]|select(has("public-key"?))."allowed-ips"?' | sed 's/,/ /g;s/\[//;s/\]//;s/\"//g')
for pubkey in "${pubkeys[@]}"; do
if [ -z "$pubkey" ] || [ "$pubkey" == null ]; then
continue
fi
if [ -n "${name[${pubkey,,}]}" ]; then
output="Public key <b>'${pubkey,,}'</b> exists more than once"
ret=1
break
fi
name[${pubkey,,}]=1
done
if [ $ret == 0 ]; then
temp=$(mktemp)
(
$cmd begin
ret=0
if $cmd show | grep -q "wireguard-wizard-peers-allowed-ips"; then
if ! $cmd delete custom-attribute wireguard-wizard-peers-allowed-ips; then
echo "$cmd delete custom-attribute wireguard-wizard-peers-allowed-ips failed." >> $log
ret=1
fi
fi
if $cmd show | grep -q "wireguard-wizard-peers-dns"; then
if ! $cmd delete custom-attribute wireguard-wizard-peers-dns; then
echo "$cmd delete custom-attribute wireguard-wizard-peers-dns failed." >> $log
ret=1
fi
fi
eval "interfaces=($($cli listActiveNodes $wgcfg))"
if [ ! "$wgenable" == "on" ]; then
if [ -n "$interfaces" ]; then
$cmd delete $wgcfg ${interfaces[0]} disable
if ! $cmd set $wgcfg ${interfaces[0]} disable; then
echo "set $wgcfg ${interfaces[0]} disable failed." >> $log
ret=1
fi
fi
fi
if [ "$wgenable" == "on" ]; then
interfaces="wg0"
$cmd delete $wgcfg ${interfaces[0]} disable
if ! $cmd set $wgcfg ${interfaces[0]} private-key "${privatekey}"; then
echo "set $wgcfg ${interfaces[0]} private-key \"${privatekey}\" failed." >> $log
ret=1
fi
if [ -n "$listenport" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} listen-port "${listenport}"; then
echo "set $wgcfg ${interfaces[0]} listen-port \"${listenport}\" failed." >> $log
ret=1
fi
else
$cmd delete $wgcfg ${interfaces[0]} listen-port
fi
if [ "$routeallowedips" == "on" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} route-allowed-ips true; then
echo "set $wgcfg ${interfaces[0]} route-allowed-ips true failed." >> $log
ret=1
fi
else
if ! $cmd set $wgcfg ${interfaces[0]} route-allowed-ips false; then
echo "set $wgcfg ${interfaces[0]} route-allowed-ips false failed." >> $log
ret=1
fi
fi
if [ -n "${ipaddress}" ] && [ "${ipaddress}" != "null" ]; then
for oneipaddress in ${ipaddress}; do
if ! $cmd set $wgcfg ${interfaces[0]} address "$oneipaddress"; then
echo "set $wgcfg ${interfaces[0]} address \"$oneipaddress\" failed." >> $log
ret=1
break 2
fi
done
else
$cmd delete $wgcfg ${interfaces[0]} address
fi
if [ -n "$peersallowedips" ]; then
if ! $cmd set custom-attribute wireguard-wizard-peers-allowed-ips; then
echo "set custom-attribute wireguard-wizard-peers-allowed-ips failed." >> $log
fi
if ! $cmd set custom-attribute wireguard-wizard-peers-allowed-ips value "$peersallowedips"; then
echo "set custom-attribute wireguard-wizard-peers-allowed-ips value \"$peersallowedips\" failed." >> $log
fi
fi
if [ -n "$peersdns" ]; then
if ! $cmd set custom-attribute wireguard-wizard-peers-dns; then
echo "set custom-attribute wireguard-wizard-peers-dns failed." >> $log
fi
if ! $cmd set custom-attribute wireguard-wizard-peers-dns value "$peersdns"; then
echo "set custom-attribute wireguard-wizard-peers-dns value \"$peersdns\" failed." >> $log
fi
fi
if [ -n "$peersendpoint" ]; then
if ! $cmd set custom-attribute wireguard-wizard-peers-endpoint; then
echo "set custom-attribute wireguard-wizard-peers-endpoint failed." >> $log
fi
if ! $cmd set custom-attribute wireguard-wizard-peers-endpoint value "$peersendpoint"; then
echo "set custom-attribute wireguard-wizard-peers-endpoint value \"$peersendpoint\" failed." >> $log
fi
fi
j=0
for ((i = 0; i < ${#pubkeys[@]}; i++)); do
if [ -z "${pubkeys[i]}" ] || [ "${pubkeys[i]}" == null ]; then
continue
fi
if [ -n "${descriptions[i]}" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" description "${descriptions[i]}"; then
echo "set $wgcfg ${interfaces[0]} peer \"${pubkeys[i]}\" description \"${descriptions[i]}\" failed." >> $log
ret=1
break
fi
else
$cmd delete $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" description
fi
if [ -n "${endpoints[i]}" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" endpoint "${endpoints[i]}"; then
echo "set $wgcfg ${interfaces[0]} peer \"${pubkeys[i]}\" endpoint \"${endpoints[i]}\" failed." >> $log
ret=1
break
fi
else
$cmd delete $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" endpoint
fi
if [ -n "${persistentkeepalives[i]}" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" persistent-keepalive "${persistentkeepalives[i]}"; then
echo "set $wgcfg ${interfaces[0]} peer \"${pubkeys[i]}\" persistent-keepalive \"${persistentkeepalives[i]}\" failed." >> $log
ret=1
break
fi
else
$cmd delete $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" persistent-keepalive
fi
if [ -n "${presharedkeys[i]}" ]; then
if ! $cmd set $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" preshared-key "${presharedkeys[i]}"; then
echo "set $wgcfg ${interfaces[0]} peer \"${pubkeys[i]}\" preshared-key \"${presharedkeys[i]}\" failed." >> $log
ret=1
break
fi
else
$cmd delete $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" preshared-key
fi
if [ -n "${allowedips[j]}" ] && [ "${allowedips[j]}" != "null" ]; then
$cmd delete $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" allowed-ips
for allowedip in ${allowedips[j]}; do
if ! $cmd set $wgcfg ${interfaces[0]} peer "${pubkeys[i]}" allowed-ips "$allowedip"; then
echo "set $wgcfg ${interfaces[0]} peer \"${pubkeys[i]}\" allowed-ips \"$allowedip\" failed." >> $log
ret=1
break 2
fi
done
fi
if [ $ret == 1 ]; then
echo "something failed, check log!" >> $log
break
fi
j=$(expr $j + 1)
done
# delete old peers
eval "peers=($($cli listActiveNodes $wgcfg ${interfaces[0]} peer))"
for peer in "${peers[@]}"; do
found=
for pubkey in "${pubkeys[@]}"; do
if [ $peer == $pubkey ]; then
found=1
break
fi
done
if [ ! $found ]; then
if ! $cmd delete $wgcfg ${interfaces[0]} peer "$peer"; then
echo "delete $wgcfg ${interfaces[0]} peer \"$peer\" failed." >> $log
ret=1
break
fi
fi
done
fi
if [ $ret == 0 ]; then
$cmd commit || ret=1
fi
if [ $ret == 0 ]; then
$cmd save || ret=1
fi
$cmd end
exit $ret
) >$temp 2>&1
ret=$?
output=$(cat $temp)
rm -f $temp
fi
if [ $ret == 0 ]; then
echo "{\"success\":\"1\"}"
else
output=$(echo $output)
echo "{\"success\":\"0\",\"error\": \"${output//\"/\'}\"}"
fi
}
case "$ACTION" in
install)
installwireguard $2
;;
load)
load
;;
apply)
apply
;;
esac
echo "$(date +%Y-%m-%d/%H:%M:%S.%N) [wizard] EdgeMAX WireGuard Wizard ended - Session="$$ >>$log