-
Notifications
You must be signed in to change notification settings - Fork 1
/
install-attnative6
executable file
·431 lines (353 loc) · 14 KB
/
install-attnative6
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
#!/bin/sh
################################################################################
# File: install-attnative6
# Description: Script to generate and install a configuration file for the
# dibbler DHCPv6 client and a helper script, intended for use on routers
# connected to u-Verse Fiber with the Residential Gateway bypassed.
# Results in native IPv6 with Prefix Delegation.
# Requires: dibbler-client, template files in current directory
# Template file names: client.conf.template, pdsplit.sh.template
################################################################################
help() {
cat << EOF
Generate, and optionally install, a configuration file and helper script for
dibbler-client to mimic DHCPv6 behavior of a Motorola NVG599.
Usage: $0 [OPTION]...
All options are optional. Any missing information required for this script to
run will be queried interactively if not supplied on the command line.
Mandatory arguments to long options are mandatory for short options too.
Help:
-h, --help print this help
Interfaces:
-w, --wan=WAN WAN interface name
-l, --lan=LAN LAN interface name
Residential Gateway:
-m, --mfg=MFG RG manufacturer (either 'pace' or 'motorola')
-s, --serial=SERIAL RG serial number (enter completely and exactly)
Quiet mode:
-q, --quiet accept all defaults below unless explicitly overridden
with (additional) command-line arguments; do not ask
for final approval at summary screen (careful!)
The following options have defaults - they all default to 'no' (except for the
-path options, which have defaults as shown). However, the user will still be
asked to review and approve them if -q/--quiet is not specified.
WAN workaround and paths:
-b, --bind-wan bind address from prefix delegation to WAN interface
(workaround enables direct IPv6 connectivity from WAN)
--conf-path=CPATH configuration file should be installed to CPATH
(default: '/etc/dibbler')
--hlp-path=HPATH helper script should be installed to HPATH
(default: '/etc/dibbler')
--log-path=LPATH helper script should write its own log to LPATH
(default: '/var/log/dibbler')
Installation:
-i, --install same as both --install-conf and --install-hlp
--install-conf install configuration file
--install-hlp install helper script
-c, --clear-leases clear any existing dibbler-client lease database
EOF
}
### Helpers ###
err() { echo "${B}$1${N}" >&2; }
die() { err "EXIT WITH ERROR: $1"; [ "$2" = "y" ] && help; exit 1; }
ask() {
printf "%s" " ${B}$2:${N} "; read ans
[ -z "$ans" ] && ans="$3"
eval "$1=\$ans"
}
confirm() {
ask t "Enter 'yes' exactly to confirm [default=no]"
[ "$t" = "yes" ] && eval "$1=yes" || eval "$1=no"
}
checkvars() {
ret=0; msg=; tmp=
for n in $(seq 1 $#); do
vname=$(eval echo \$"$n"); vval=$(eval echo \$"$vname")
if [ -n "$vval" ]; then
[ -n "$msg" ] && msg="$msg, "; msg="$msg$vname='$vval'"; ret=$((ret + 1))
else
[ -n "$tmp" ] && tmp="$tmp, "; tmp="$tmp$vname"
fi
done
[ $ret -gt 0 ] && msg="(got $msg; need $tmp)" && echo "$msg"; return $ret
}
# this awk one-liner should be fully portable
ascii2hex() { echo "$*" | awk 'BEGIN{for(n=0;n<256;n++)ord[sprintf("%c",n)]=n}{len=split($0,c,"");for(i=1;i<=len;i++)printf("%X",ord[c[i]])}'; }
### Template files ###
CONFTMPL=client.conf.template
HLPTMPL=pdsplit.sh.template
### Environment ###
INSTALLERPATH="$0"
ALLOWINST=no
B=$(tput bold)
U=$(tput smul)
N=$(tput sgr0)
WAN=
LAN=
MFG=
SERIAL=
QUIET=no
BINDWAN=
CONFPATH=
HLPPATH=
LOGPATH=
INSTC=
INSTH=
CLRDB=
### Major parts ###
printinfo() {
cat << EOF
${B}${U}attnative6: Native IPv6 on AT&T with dibbler-client${N}
This installer can generate and install configuration files for the dibbler
DHCPv6 client that make it request a global unicast address (a "public",
semi-permanent IPv6 address) and a Prefix Delegation (PD) very similarly to an
Arris Motorola NVG599. The result is native dual-stack IPv6 connectivity on a
router connected to a u-Verse Fiber ONT while bypassing the AT&T Residential
Gateway, either directly or via a managed switch.
See ${U}https://is.gd/wokixe${N} for more details on the bypass process. Also see
${U}https://github.com/kangtastic/attnative6${N} for more details on this installer.
${B}NOTE:${N} Works best if run ${B}BEFORE STARTING dibbler-client FOR THE FIRST TIME${N}.
(${U}If you're just generating a new helper script, disregard this.${N})
EOF
}
getinterfaces() {
msg=$(checkvars WAN LAN); ret=$?; [ $ret -eq 2 ] && return
cat << EOF
${B}INTERFACES${N} $msg
We need the names of the WAN-facing and LAN-facing interfaces on this system.
If bypassing using an EAP proxy, the WAN-facing interface is probably named
something like "eth0.0".
EOF
while [ -z "$WAN" ]; do ask WAN "WAN interface name"; done
while [ -z "$LAN" ]; do ask LAN "LAN interface name"; done
}
getrginfo() {
msg=$(checkvars MFG SERIAL); ret=$?; [ $ret -eq 2 ] && return
cat << EOF
${B}RG INFORMATION${N} $msg
We need your Residential Gateway's manufacturer and serial number.
If the serial number contains any capital/small letters, enter them exactly.
From this we can reconstruct the DUID-EN to send during DHCPv6 requests.
(${U}If you're just generating a new helper script, it doesn't matter what you${N}
${U}enter here.${N})
EOF
while ! ([ "$MFG" = "1" ] || [ "$MFG" = "2" ]); do
ask MFG "Manufacturer [1=Pace, 2=Motorola]"
done
while [ -z "$SERIAL" ]; do ask SERIAL "Serial number"; done
}
getbindwan() {
msg=$(checkvars BINDWAN); ret=$?; [ $ret -eq 1 ] && return
cat << EOF
${B}IPv6 ON WAN WORKAROUND${N}
The address that AT&T assigns to the WAN interface isn't enabled on their end
for routing to the public IPv6 Internet. (It's a /128 in 2001:506:6000::/35.)
As a workaround, we can bind a single address from the prefix delegation in
the same /64 subnet as the LAN interface to the WAN interface. (This will be
a /128 address in 2600:1700::/28, which AT&T has made publicly routable.)
${B}Use this workaround?${N} Just press ENTER to accept the default (no).
EOF
while ! ([ "$BINDWAN" = "yes" ] || [ "$BINDWAN" = "no" ]);
do confirm BINDWAN;
done
}
getpaths() {
msg=$(checkvars CONFPATH HLPPATH LOGPATH); ret=$?; [ $ret -eq 3 ] && return
cat << EOF
${B}PATHS${N} $msg
We will generate a configuration file and a helper script named ${U}client.conf${N}
and ${U}pdsplit.sh${N}, which should be installed in ${B}/etc/dibbler${N}.
The helper script should also write its own logs in ${B}/var/log/dibbler${N}.
${B}Change these directories?${N} Just press ENTER to accept the defaults.
EOF
while [ -z "$CONFPATH" ]; do
ask CONFPATH "Config file directory [default=/etc/dibbler]" /etc/dibbler
done
while [ -z "$HLPPATH" ]; do
ask HLPPATH "Helper script directory [default=/etc/dibbler]" /etc/dibbler
done
while [ -z "$LOGPATH" ]; do
ask LOGPATH "Helper script log directory [default=/var/log/dibbler]" /var/log/dibbler
done
}
getinstall() {
msg=$(checkvars INSTC INSTH CLRDB); ret=$?; [ $ret -eq 3 ] && return
cat << EOF
${B}INSTALL OPTIONS${N} $msg
EOF
if ([ -z "$INSTC" ] || [ -z "$INSTH" ]); then
cat << EOF
We can install the configuration file and the helper script. (${U}If you're just${N}
${U}generating a new helper script, don't install client.conf.${N})
EOF
[ -z "$INSTC" ] && echo " ${B}Install ${U}client.conf${N}${B} (the config file) into ${U}${CONFPATH}${N}${B}?"
while [ -z "$INSTC" ]; do confirm INSTC; done
[ -z "$INSTH" ] && echo " ${B}Install ${U}pdsplit.sh${N}${B} (the helper script) into ${U}${HLPPATH}${N}${B}?"
while [ -z "$INSTH" ]; do confirm INSTH; done
fi
if [ -f /var/lib/dibbler/client-duid ]; then
cat << EOF
${B}dibbler-client${N} has already run and created a DHCPv6 lease database. Clearing
it is probably necessary, unless you got IPv6 while bypassed because of this
installer. (${U}If you're just generating a new helper script, don't clear${N}
${U}the database.${N})
Technical reason: ${B}dibbler-client${N} generated a DUID-LLT from your MAC address
and stored it in the lease database, even without receiving any leases. Sadly,
the new DUID-EN we generate and insert into ${B}client.conf${N} will then be ignored.
${B}Clear dibbler-client's DHCPv6 lease database?${N}
EOF
while [ -z "$CLRDB" ]; do confirm CLRDB; done
fi
}
printsummary() {
cat << EOF
${B}SUMMARY${N}
WAN interface ${B}$WAN${N}
LAN interface ${B}$LAN${N}
RG manufacturer ${B}$([ $MFG = 1 ] && echo Pace || echo Motorola)${N}
RG serial number ${B}$SERIAL${N}
Bind address from PD to WAN ${B}$BINDWAN${N}
Configuration file directory ${B}$CONFPATH${N}
Helper script directory ${B}$HLPPATH${N}
Helper script log directory ${B}$LOGPATH${N}
Install configuration file ${B}$INSTC${N}
Install helper script ${B}$INSTH${N}
Clear dibbler's lease database ${B}$CLRDB${N}
EOF
}
generate() {
from_template() {
f="$1"; of="$2"
cp "$f" "$of" &&
sed -s "s|__INSTALLERPATH__|$(readlink -f "$INSTALLERPATH")|" -i.bak "$of" &&
sed -e "s|__DATE__|$(date -R)|" -i.bak "$of" &&
sed -e "s|__WAN__|$WAN|" -i.bak "$of" &&
sed -e "s|__LAN__|$LAN|" -i.bak "$of" &&
sed -e "s|__DUIDEN__|$DUIDEN|" -i.bak "$of" &&
sed -e "s|__CONFPATH__|$CONFPATH|" -i.bak "$of" &&
sed -e "s|__HLPPATH__|$HLPPATH|" -i.bak "$of" &&
sed -e "s|__LOGPATH__|$LOGPATH|" -i.bak "$of" &&
sed -e "s|__BINDWAN__|$BINDWAN|" -i.bak "$of" &&
rm "$of.bak" || return 1
}
[ "$MFG" = "1" ] && MFG="00D09E" || MFG="001E46"
DUIDEN=$(ascii2hex "$MFG-$SERIAL") && DUIDEN="0x$DUIDEN"
conf=$(echo $CONFTMPL | sed 's|.template||')
hlp=$(echo $HLPTMPL | sed 's|.template||')
from_template "$CONFTMPL" "$conf" && s_conf="Success" || s_conf="Failure"
from_template "$HLPTMPL" "$hlp" && s_hlp="Success" || s_hlp="Failure"
cat << EOF
${B}GENERATE${N}
Configuration file (client.conf) ${B}$s_conf${N}
Helper script (pdsplit.sh) ${B}$s_hlp${N}
EOF
[ "$s_conf" = "Success" ] && [ "$s_hlp" = "Success" ] || return 1
}
install() {
INST="no"
for v in INSTC INSTH CLRDB; do
val=$(eval echo \$$v); [ "$val" = "yes" ] && INST="yes"
done
[ "$INST" = "no" ] && return
# Status of overall installation and subprocedures
s_inst="Success"
for v in s_kill s_instc s_insth s_clear; do
eval $v="Failed"
done
if [ -n "$(pgrep dibbler-client)" ]; then
killall dibbler-client && s_kill="Success"
else
s_kill="N/A"
fi
if [ "$INSTC" = "yes" ]; then
mkdir -p "$CONFPATH" && mv "$conf" "$CONFPATH" && s_instc="Success"
else
s_instc="N/A"
fi
if [ "$INSTH" = "yes" ] && chmod +x "$hlp"; then
mkdir -p "$HLPPATH" && mv "$hlp" "$HLPPATH" && s_insth="Success"
else
s_insth="N/A"
fi
if [ -f /var/lib/dibbler/client-duid ] && [ "$CLRDB" = "yes" ]; then
rm -f /var/lib/dibbler/client* && s_clear="Success"
else
s_clear="N/A"
fi
for v in s_kill s_instc s_insth s_clear; do
val=$(eval echo \$$v); [ "$val" = "Failed" ] && s_inst="Failed"
done
cat << EOF
${B}RESULTS${N}
Kill running instances of dibbler-client ${B}$s_kill${N}
Install configuration file ${B}$s_instc${N}
Install helper script ${B}$s_insth${N}
Clear dibbler's lease database ${B}$s_clear${N}
EOF
[ "$s_inst" = "Success" ] || return 1
}
### MAIN ###
# Options #
OPTS=$(getopt -o hw:l:m:s:qbic --long help,wan:,lan:,mfg:,serial:,quiet,bind-wan,conf-path:,hlp-path:,log-path:,install,install-conf,install-hlp,clear-leases -n 'parse-options' -- "$@")
[ $? != 0 ] && err "Failed to parse some options; ignoring"
eval set -- "$OPTS"
while true; do
case "$1" in
-h | --help ) help; exit 0 ;;
-w | --wan ) WAN="$2"; shift; shift ;;
-l | --lan ) LAN="$2"; shift; shift ;;
-m | --mfg )
if [ "$2" = "pace" ] || [ "$2" = "1" ]; then MFG=1
elif [ "$2" = "motorola" ] || [ "$2" = "2" ]; then MFG=2
else die "-m/--mfg: failed to parse argument '$2'" "y"; fi; shift; shift ;;
-s | --serial ) SERIAL="$2"; shift; shift ;;
-q | --quiet ) QUIET=yes; shift ;;
-b | --bind-wan ) BINDWAN=yes; shift ;;
--conf-path ) CONFPATH="$2"; shift; shift ;;
--hlp-path ) HLPPATH="$2"; shift; shift ;;
--log-path ) LOGPATH="$2"; shift; shift ;;
-i | --install ) INSTC=yes; INSTH=yes; shift ;;
--install-conf ) INSTC=yes; shift ;;
--install-hlp ) INSTH=yes; shift ;;
-c | --clear-leases ) CLRDB=yes; shift ;;
-- ) shift; break ;;
* ) break ;;
esac
done
# Sanity checks #
for f in "$CONFTMPL" "$HLPTMPL"; do
[ -f "$f" ] || die "$f not found in $PWD"
done
[ -x "$(which dibbler-client)" ] && [ "$(whoami)" = "root" ] && ALLOWINST=yes
if [ "$ALLOWINST" != "yes" ]; then
for v in INSTC INSTH CLRDB; do eval "$v=disabled"; done
err "Not root, or dibbler-client not found; installation functions disabled."
fi
## Run parts ##
[ "$QUIET" != "yes" ] && printinfo
getinterfaces; getrginfo
[ "$QUIET" != "yes" ] && getbindwan && getpaths && getinstall
# Set defaults for any options that are still empty #
[ -z "$BINDWAN" ] && BINDWAN=no
[ -z "$CONFPATH" ] && CONFPATH=/etc/dibbler
[ -z "$HLPPATH" ] && HLPPATH=/etc/dibbler
[ -z "$LOGPATH" ] && LOGPATH=/var/log/dibbler
for v in INSTC INSTH CLRDB; do [ -z "$(eval echo \$$v)" ] && eval $v=no; done
printsummary
# Point of no return #
if [ "$QUIET" != "yes" ]; then
cat << EOF
${B}Please confirm that the above summary is correct, or this installer will quit.${N}
EOF
confirm trigger
if [ "$trigger" = "no" ]; then
printf "\n%s\n" "${B}User quit. Bye!${N}"; exit
fi
fi
generate || die "Failed during generation step."
install || die "Failed during installation step."
cat << EOF
${B}FINISHED${N}
(Run 'systemctl restart dibbler-client' as root to start or restart the client
on a reasonably recent Linux.)
EOF