1
+ #! /bin/sh
2
+ # Copyright 2016-2017 Dan Luedtke <[email protected] >
3
+ # Licensed to the public under the Apache License 2.0.
4
+
5
+ WG=/usr/bin/amneziawg
6
+ if [ ! -x $WG ]; then
7
+ logger -t " amnezia-wg" " error: missing amnezia-wg-tools (${WG} )"
8
+ exit 0
9
+ fi
10
+
11
+ [ -n " $INCLUDE_ONLY " ] || {
12
+ . /lib/functions.sh
13
+ . ../netifd-proto.sh
14
+ init_proto " $@ "
15
+ }
16
+
17
+ proto_amneziawg_init_config () {
18
+ proto_config_add_string " private_key"
19
+ proto_config_add_int " listen_port"
20
+ proto_config_add_int " mtu"
21
+ proto_config_add_string " fwmark"
22
+ proto_config_add_int " awg_jc"
23
+ proto_config_add_int " awg_jmin"
24
+ proto_config_add_int " awg_jmax"
25
+ proto_config_add_int " awg_s1"
26
+ proto_config_add_int " awg_s2"
27
+ proto_config_add_int " awg_h1"
28
+ proto_config_add_int " awg_h2"
29
+ proto_config_add_int " awg_h3"
30
+ proto_config_add_int " awg_h4"
31
+ available=1
32
+ no_proto_task=1
33
+ }
34
+
35
+ proto_amneziawg_is_kernel_mode () {
36
+ if [ ! -e /sys/module/amneziawg ]; then
37
+ modprobe amneziawg > /dev/null 2& > 1 || true
38
+
39
+ if [ -e /sys/module/amneziawg ]; then
40
+ return 0
41
+ else
42
+ if [ ! command -v " ${WG_QUICK_USERSPACE_IMPLEMENTATION:- amneziawg-go} " > /dev/null ]; then
43
+ ret=$?
44
+ echo " Please install either kernel module (kmod-amneziawg package) or user-space implementation in /usr/bin/amneziawg-go."
45
+ exit $?
46
+ else
47
+ return 1
48
+ fi
49
+ fi
50
+ else
51
+ return 0
52
+ fi
53
+ }
54
+
55
+ proto_amneziawg_setup_peer () {
56
+ local peer_config=" $1 "
57
+
58
+ local disabled
59
+ local public_key
60
+ local preshared_key
61
+ local allowed_ips
62
+ local route_allowed_ips
63
+ local endpoint_host
64
+ local endpoint_port
65
+ local persistent_keepalive
66
+
67
+ config_get_bool disabled " ${peer_config} " " disabled" 0
68
+ config_get public_key " ${peer_config} " " public_key"
69
+ config_get preshared_key " ${peer_config} " " preshared_key"
70
+ config_get allowed_ips " ${peer_config} " " allowed_ips"
71
+ config_get_bool route_allowed_ips " ${peer_config} " " route_allowed_ips" 0
72
+ config_get endpoint_host " ${peer_config} " " endpoint_host"
73
+ config_get endpoint_port " ${peer_config} " " endpoint_port"
74
+ config_get persistent_keepalive " ${peer_config} " " persistent_keepalive"
75
+
76
+ if [ " ${disabled} " -eq 1 ]; then
77
+ # skip disabled peers
78
+ return 0
79
+ fi
80
+
81
+ if [ -z " $public_key " ]; then
82
+ echo " Skipping peer config $peer_config because public key is not defined."
83
+ return 0
84
+ fi
85
+
86
+ echo " [Peer]" >> " ${wg_cfg} "
87
+ echo " PublicKey=${public_key} " >> " ${wg_cfg} "
88
+ if [ " ${preshared_key} " ]; then
89
+ echo " PresharedKey=${preshared_key} " >> " ${wg_cfg} "
90
+ fi
91
+ for allowed_ip in $allowed_ips ; do
92
+ echo " AllowedIPs=${allowed_ip} " >> " ${wg_cfg} "
93
+ done
94
+ if [ " ${endpoint_host} " ]; then
95
+ case " ${endpoint_host} " in
96
+ * :* )
97
+ endpoint=" [${endpoint_host} ]"
98
+ ;;
99
+ * )
100
+ endpoint=" ${endpoint_host} "
101
+ ;;
102
+ esac
103
+ if [ " ${endpoint_port} " ]; then
104
+ endpoint=" ${endpoint} :${endpoint_port} "
105
+ else
106
+ endpoint=" ${endpoint} :51820"
107
+ fi
108
+ echo " Endpoint=${endpoint} " >> " ${wg_cfg} "
109
+ fi
110
+ if [ " ${persistent_keepalive} " ]; then
111
+ echo " PersistentKeepalive=${persistent_keepalive} " >> " ${wg_cfg} "
112
+ fi
113
+
114
+ if [ ${route_allowed_ips} -ne 0 ]; then
115
+ for allowed_ip in ${allowed_ips} ; do
116
+ case " ${allowed_ip} " in
117
+ * :* /* )
118
+ proto_add_ipv6_route " ${allowed_ip%%/* } " " ${allowed_ip##*/ } "
119
+ ;;
120
+ * .* /* )
121
+ proto_add_ipv4_route " ${allowed_ip%%/* } " " ${allowed_ip##*/ } "
122
+ ;;
123
+ * :* )
124
+ proto_add_ipv6_route " ${allowed_ip%%/* } " " 128"
125
+ ;;
126
+ * .* )
127
+ proto_add_ipv4_route " ${allowed_ip%%/* } " " 32"
128
+ ;;
129
+ esac
130
+ done
131
+ fi
132
+ }
133
+
134
+ ensure_key_is_generated () {
135
+ local private_key
136
+ private_key=" $( uci get network." $1 " .private_key) "
137
+
138
+ if [ " $private_key " == " generate" ]; then
139
+ local ucitmp
140
+ oldmask=" $( umask) "
141
+ umask 077
142
+ ucitmp=" $( mktemp -d) "
143
+ private_key=" $( " ${WG} " genkey) "
144
+ uci -q -t " $ucitmp " set network." $1 " .private_key=" $private_key " && \
145
+ uci -q -t " $ucitmp " commit network
146
+ rm -rf " $ucitmp "
147
+ umask " $oldmask "
148
+ fi
149
+ }
150
+
151
+ proto_amneziawg_setup () {
152
+ local config=" $1 "
153
+ local wg_dir=" /tmp/wireguard"
154
+ local wg_cfg=" ${wg_dir} /${config} "
155
+
156
+ local private_key
157
+ local listen_port
158
+ local mtu
159
+
160
+ # Amnezia WG specific parameters
161
+ local awg_jc
162
+ local awg_jmin
163
+ local awg_jmax
164
+ local awg_s1
165
+ local awg_s2
166
+ local awg_h1
167
+ local awg_h2
168
+ local awg_h3
169
+ local awg_h4
170
+
171
+ ensure_key_is_generated " ${config} "
172
+
173
+ config_load network
174
+ config_get private_key " ${config} " " private_key"
175
+ config_get listen_port " ${config} " " listen_port"
176
+ config_get addresses " ${config} " " addresses"
177
+ config_get mtu " ${config} " " mtu"
178
+ config_get fwmark " ${config} " " fwmark"
179
+ config_get ip6prefix " ${config} " " ip6prefix"
180
+ config_get nohostroute " ${config} " " nohostroute"
181
+ config_get tunlink " ${config} " " tunlink"
182
+
183
+ config_get awg_jc " ${config} " " awg_jc"
184
+ config_get awg_jmin " ${config} " " awg_jmin"
185
+ config_get awg_jmax " ${config} " " awg_jmax"
186
+ config_get awg_s1 " ${config} " " awg_s1"
187
+ config_get awg_s2 " ${config} " " awg_s2"
188
+ config_get awg_h1 " ${config} " " awg_h1"
189
+ config_get awg_h2 " ${config} " " awg_h2"
190
+ config_get awg_h3 " ${config} " " awg_h3"
191
+ config_get awg_h4 " ${config} " " awg_h4"
192
+
193
+ ip link del dev " ${config} " 2> /dev/null
194
+
195
+ if proto_amneziawg_is_kernel_mode; then
196
+ logger -t " amneziawg" " info: using kernel-space kmod-amneziawg for ${WG} "
197
+ ip link add dev " ${config} " type amneziawg
198
+ else
199
+ logger -t " amneziawg" " info: using user-space amneziawg-go for ${WG} "
200
+ amneziawg-go " ${config} "
201
+ fi
202
+
203
+ if [ " ${mtu} " ]; then
204
+ ip link set mtu " ${mtu} " dev " ${config} "
205
+ fi
206
+
207
+ proto_init_update " ${config} " 1
208
+
209
+ umask 077
210
+ mkdir -p " ${wg_dir} "
211
+ echo " [Interface]" > " ${wg_cfg} "
212
+ echo " PrivateKey=${private_key} " >> " ${wg_cfg} "
213
+ if [ " ${listen_port} " ]; then
214
+ echo " ListenPort=${listen_port} " >> " ${wg_cfg} "
215
+ fi
216
+ if [ " ${fwmark} " ]; then
217
+ echo " FwMark=${fwmark} " >> " ${wg_cfg} "
218
+ fi
219
+ # AWG
220
+ if [ " ${awg_jc} " ]; then
221
+ echo " Jc = ${awg_jc} " >> " ${wg_cfg} "
222
+ fi
223
+ if [ " ${awg_jmin} " ]; then
224
+ echo " Jmin = ${awg_jmin} " >> " ${wg_cfg} "
225
+ fi
226
+ if [ " ${awg_jmax} " ]; then
227
+ echo " Jmax = ${awg_jmax} " >> " ${wg_cfg} "
228
+ fi
229
+ if [ " ${awg_s1} " ]; then
230
+ echo " S1 = ${awg_s1} " >> " ${wg_cfg} "
231
+ fi
232
+ if [ " ${awg_s2} " ]; then
233
+ echo " S2 = ${awg_s2} " >> " ${wg_cfg} "
234
+ fi
235
+ if [ " ${awg_h1} " ]; then
236
+ echo " H1 = ${awg_h1} " >> " ${wg_cfg} "
237
+ fi
238
+ if [ " ${awg_h2} " ]; then
239
+ echo " H2 = ${awg_h2} " >> " ${wg_cfg} "
240
+ fi
241
+ if [ " ${awg_h3} " ]; then
242
+ echo " H3 = ${awg_h3} " >> " ${wg_cfg} "
243
+ fi
244
+ if [ " ${awg_h4} " ]; then
245
+ echo " H4 = ${awg_h4} " >> " ${wg_cfg} "
246
+ fi
247
+
248
+ config_foreach proto_amneziawg_setup_peer " wireguard_${config} "
249
+
250
+ # apply configuration file
251
+ ${WG} setconf ${config} " ${wg_cfg} "
252
+ WG_RETURN=$?
253
+
254
+ rm -f " ${wg_cfg} "
255
+
256
+ if [ ${WG_RETURN} -ne 0 ]; then
257
+ sleep 5
258
+ proto_setup_failed " ${config} "
259
+ exit 1
260
+ fi
261
+
262
+ for address in ${addresses} ; do
263
+ case " ${address} " in
264
+ * :* /* )
265
+ proto_add_ipv6_address " ${address%%/* } " " ${address##*/ } "
266
+ ;;
267
+ * .* /* )
268
+ proto_add_ipv4_address " ${address%%/* } " " ${address##*/ } "
269
+ ;;
270
+ * :* )
271
+ proto_add_ipv6_address " ${address%%/* } " " 128"
272
+ ;;
273
+ * .* )
274
+ proto_add_ipv4_address " ${address%%/* } " " 32"
275
+ ;;
276
+ esac
277
+ done
278
+
279
+ for prefix in ${ip6prefix} ; do
280
+ proto_add_ipv6_prefix " $prefix "
281
+ done
282
+
283
+ # endpoint dependency
284
+ if [ " ${nohostroute} " != " 1" ]; then
285
+ ${WG} show " ${config} " endpoints | \
286
+ sed -E ' s/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \
287
+ while IFS=$' \t ' read -r key address port; do
288
+ [ -n " ${port} " ] || continue
289
+ proto_add_host_dependency " ${config} " " ${address} " " ${tunlink} "
290
+ done
291
+ fi
292
+
293
+ proto_send_update " ${config} "
294
+ }
295
+
296
+ proto_amneziawg_teardown () {
297
+ local config=" $1 "
298
+ proto_amneziawg_check_installed
299
+ if proto_amneziawg_is_kernel_mode; then
300
+ ip link del dev " ${config} " > /dev/null 2>&1
301
+ else
302
+ rm -f /var/run/wireguard/${config} .sock
303
+ fi
304
+ }
305
+
306
+ [ -n " $INCLUDE_ONLY " ] || {
307
+ add_protocol amneziawg
308
+ }
0 commit comments