projects/aports·blob master · refs

354 lines · 11.1 KiB

1#!/bin/sh
2# Contributor: Stuart Cardall <[email protected]>
3# dnscrypt-proxy setup script to choose DNS Resolver & install / configure / remove DNS Caching
4###############################################################################################
5
6config='/etc/conf.d/dnscrypt-proxy'
7dhcpconfig='/etc/dhcp/dhclient.conf'
8unboundconfig='/etc/unbound/unbound.conf'
9
10SCRIPT=$(echo "`basename $0`")
11
12NORMAL="\033[1;0m"
13STRONG="\033[1;1m"
14RED="\033[1;31m"
15GREEN="\033[1;32m"
16
17print_question() {
18 local prompt="${STRONG}$1 ${RED}$2${NORMAL}"
19 printf "${prompt} %s"
20}
21
22print_strong() {
23 local prompt="${STRONG}$1 ${RED}$2${NORMAL}"
24 printf "${prompt} %s\n"
25}
26
27print_green() {
28 local prompt="${GREEN}${STRONG}$1 ${NORMAL}"
29 printf "${prompt} %s\n"
30}
31
32print_table() {
33 local choice="${RED}${STRONG}$1${NORMAL}"
34 local resolver="${STRONG}$2"
35 local location="${GREEN}$3"
36 printf "${choice} ${resolver} ${location} %s\n"
37}
38
39die() {
40 print_table "ERROR:" "$1" > /dev/null 1>&2
41 exit 1
42}
43
44restart_interface(){
45INTERFACES=$(echo | ifconfig | grep "Link encap" | sed '/lo/d' | cut -d"L" -f1)
46print_question "\nChoose external interface to restart from the following:"
47print_question "\n\n$INTERFACES" "[ default: eth0 ]"
48
49while :
50do
51 read RESTART
52 # Sanitize input
53 export RESTART_CLEAN="`echo "${RESTART}" | tr -cd '[[:alnum:]]'`"
54
55 if [ ! $RESTART ] ;then
56 RESTART_CLEAN=eth0
57 fi
58
59 # tr will strip invalid input to nothing which passes grep
60 if [ "$RESTART_CLEAN" != "" ] && echo "$INTERFACES" | grep -e "$RESTART_CLEAN" 1>/dev/null; then
61 break
62 else
63 #move the cursor & clear the line
64 echo -en "\033[1A\033[28C\022[K"
65 fi
66done
67}
68
69choose_ip(){
70IPADDR=$(ifconfig |grep -B1 "inet addr" |awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' |awk -F" " '{ print $1 ": " $3 }'| sed 's/addr//')
71if echo "$IPADDR" | grep -e "127.0.0.2" 1>/dev/null && which unbound 1> /dev/null; then
72 defaultip='127.0.0.2'
73 IPADDR_CHOICE=$(echo "$IPADDR" | sed '/lo::127.0.0.1:/d')
74else
75 defaultip='127.0.0.1'
76 IPADDR_CHOICE=$(echo "$IPADDR" | sed '/lo:1::127.0.0.2:/d')
77fi
78
79print_question "\nChoose Dnscrypt IP from the following addresses:\n"
80print_question "\n$IPADDR_CHOICE\t" "[ default: $defaultip ]"
81
82while :
83do
84 read IP
85 # Sanitize input
86 export IP_CLEAN="`echo "${IP}" | tr -cd '[[:xdigit:]] [:] [.]'`"
87 if [ ! $IP ]; then
88 IP_CLEAN=$defaultip
89 fi
90 # tr will strip invalid input to nothing which passes grep
91 if [ "$IP_CLEAN" != "" ] && echo "$IPADDR_CHOICE" | grep -e "$IP_CLEAN" 1>/dev/null; then
92 print_green "\nIP: $IP_CLEAN Selected"; break
93 else
94 #move the cursor & clear the line
95 echo -en "\033[1A\033[49C\033[K"
96 fi
97done
98}
99
100choose_port(){
101if grep -e "127.0.0.2" /etc/network/interfaces 1>/dev/null; then
102 defaultport=40
103else
104 defaultport=53
105fi
106
107print_question "\nChoose Dnscrypt Port:" "[ default: $defaultport ]"
108while :
109do
110 read DNSPORT
111 # Sanitize input to an integer and assign to new variable
112 export DNSPORT_CLEAN="`echo "${DNSPORT}" | tr -cd '[0-9]'`"
113 if [ ! $DNSPORT ]; then
114 DNSPORT_CLEAN=$defaultport
115 fi
116
117 if [ $DNSPORT_CLEAN -gt 0 2>/dev/null ] && [ $DNSPORT_CLEAN -le 65535 2>/dev/null ]; then
118 print_green "\nPort: $DNSPORT_CLEAN Selected"; break
119 else
120 #move the cursor & clear the line
121 echo -en "\033[1A\033[39C\033[K"
122 fi
123done
124}
125
126update_unbound(){
127if [ -f $unboundconfig ]; then
128 if grep "Settings from "$SCRIPT"" $unboundconfig 1>/dev/null; then
129 #update forward zone
130 START=$(sed -n "\%Settings from $SCRIPT%=" $unboundconfig)
131 LINE=$(expr $START + 3 )
132 sed "$LINE c \ forward-addr: $IP_CLEAN@$DNSPORT_CLEAN" $unboundconfig -i
133
134 else
135 # allow querying of localhost
136 START=$(sed -n '/do-not-query-localhost:/=' $unboundconfig)
137 sed "$START c \do-not-query-localhost: no #set by $SCRIPT" $unboundconfig -i
138 # create catch all forward zone
139 echo -e "##### Settings from $SCRIPT #####" >> $unboundconfig
140 echo -e 'forward-zone:' >> $unboundconfig
141 echo -e ' name: "."' >> $unboundconfig
142 echo -e " forward-addr: $IP_CLEAN@$DNSPORT_CLEAN" >> $unboundconfig
143 fi
144print_strong "\n$unboundconfig settings updated to:"
145print_green "--------------------------------------------------------"
146print_table "do-not-query-localhost: no"
147print_table ""
148print_table 'forward-zone:'
149print_table ' name: "."'
150print_table " forward-addr: $IP_CLEAN@$DNSPORT_CLEAN"
151print_green "--------------------------------------------------------"
152fi
153}
154
155restart_services(){
156# add / restart services - dnscrypt must be restarted first
157echo ""
158for srv in "dnscrypt-proxy" "unbound"; do
159 if which $srv 1> /dev/null; then
160 rc-status default | grep $srv 1> /dev/null
161 if [ "$?" != "0" ]; then
162 print_green "Adding $srv to Default Run Level"
163 rc-update add $srv default
164 fi
165 rc-service $srv restart
166 fi
167done
168}
169
170modify_config(){
171choose_ip; choose_port
172
173# update dnscrypt listening ip & port
174LINE=$(sed -n '/DNSCRYPT_LOCALIP=/=' $config)
175sed "$LINE c DNSCRYPT_LOCALIP=$IP_CLEAN:$DNSPORT_CLEAN" $config -i
176
177# update dhclient.conf
178if [ -f $dhcpconfig ]; then
179 if grep 'supersede domain-name-servers' $dhcpconfig 1>/dev/null; then
180 LINE=$(sed -n '/supersede domain-name-servers/=' $dhcpconfig)
181 sed "$LINE c supersede domain-name-servers $IP" $dhcpconfig -i
182 else
183 echo "supersede domain-name-servers $IP" >> $dhcpconfig
184 fi
185fi
186
187# update resolv.conf & unbound
188LINE=$(sed -n '/nameserver/=' /etc/resolv.conf)
189sed "$LINE c nameserver 127.0.0.1" /etc/resolv.conf -i
190if [ "$removecache" != "Y" ] && [ "$removecache" != "y" ]; then
191 update_unbound
192fi
193
194restart_interface
195
196print_strong "\n/etc/conf.d/dnscrypt-proxy Listening Address updated to:"
197print_green "--------------------------------------------------------"
198print_table "DNSCRYPT_LOCALIP=$IP_CLEAN:$DNSPORT_CLEAN"
199print_green "--------------------------------------------------------\n"
200}
201
202rm_loopback(){
203START=$(sed -n "\%Settings from $SCRIPT%=" /etc/network/interfaces)
204LINE=$(expr $START + 4)
205sed -i ''$START','$LINE'd' /etc/network/interfaces
206print_green "2nd Loopback interface removed"
207}
208
209# END Functions ###################################################################################
210
211# Do some sanity checking.
212if [ $(/usr/bin/id -u) != "0" ]; then
213 die 'DNScrypt Setup must be run by root'
214fi
215
216##### Download DNS Resolver details ################################################################
217
218url='https://raw.githubusercontent.com/dyne/dnscrypt-proxy/master/dnscrypt-resolvers.csv'
219output='/tmp/dnscrypt.list'
220
221echo -e "Retrieving current list of free DNS Resolvers\n"
222wget -q --no-check-certificate $url -O $output
223sed -i 's|\"||g' $output
224
225totalservers=$(cat $output | tail -n +2 | wc -l)
226
227if [ $totalservers = 0 ]; then
228 die "Could not contact $url"
229fi
230
231# colour table ##################################################################################
232
233colourheading=$(awk 'BEGIN { format = "%-8s%-35s%-30s%-10s%-10s%-10s%-25s\n"
234 printf format, "#", "Name", "Location", "DNSSEC", "No Logs", "Namecoin", "Resolver Address" }')
235
236colourline=$(awk 'BEGIN { format = "%-8s%-35s%-30s%-10s%-10s%-10s%-25s\n"
237 printf format, "----", "----------------------------------------", "------------------------------", "----------",\
238 "----------", "----------", "-----------------------------------" }')
239
240print_green "$colourheading"
241print_green "$colourline"
242
243tmpfile=$(mktemp)
244
245cat $output | awk 'BEGIN{FS=""}{gsub(/," " /," "); print}' | tail -n +2 > $tmpfile
246
247awk -F"," 'BEGIN {format="%-8s%-35s%-30s%-10s%-10s%-10s%-25s\n"}{ printf format, "["NR"]",$1,$4,$8,$9,$10,$11}' $tmpfile
248
249print_green "$colourline"
250print_question "Please choose a DNS Resolver for dnscrypt-proxy to query:" "[1 - $totalservers]"
251
252###### Process Input #############################################################################
253
254while :
255do
256 read DNS
257 # Sanitize input to an integer
258 export DNS_CLEAN="`echo "${DNS}" | tr -cd '[0-9]'`"
259
260 if [ $DNS_CLEAN -gt 0 2>/dev/null ] && [ $DNS_CLEAN -le $totalservers 2>/dev/null ]; then
261 break
262 else
263 #move the cursor & clear the line
264 echo -en "\033[1A\033[67C\033[K"
265 fi
266done
267
268RESOLVER=$(cat $tmpfile | tr -d "\"" | tr "," ";" | sed -n "$DNS_CLEAN"p |awk -F';' '{print $11}')
269PROVIDER=$(cat $tmpfile | tr -d "\"" | tr "," ";" | sed -n "$DNS_CLEAN"p |awk -F';' '{print $12}')
270PUBKEY=$(cat $tmpfile | tr -d "\"" | tr "," ";" | sed -n "$DNS_CLEAN"p |awk -F';' '{print $13}')
271
272######## END Changes ###########################################################################
273
274if [ ! -f "$config" ]; then
275 touch $config
276 echo "DNSCRYPT_LOGFILE=/var/log/dnscrypt-proxy/dnscrypt-proxy.log" >> $config
277 echo "DNSCRYPT_LOCALIP=127.0.0.1:53" >> $config
278fi
279
280# remove existing Resolver config
281if grep "RESOLVER" $config 1> /dev/null; then
282 sed -e '/RESOLVER/d' -e '/PROVIDER/d' -e '/PUBKEY/d' $config -i
283fi
284
285# update Resolver config
286echo "RESOLVER=$RESOLVER" >> $config
287echo "PROVIDER=$PROVIDER" >> $config
288echo "PUBKEY=$PUBKEY" >> $config
289
290print_strong "\nResolver Settings updated in:" "$config"
291print_green "---------------------------------------------------------------------------------------------"
292print_table "RESOLVER :" "$RESOLVER"
293print_table "PROVIDER :" "$PROVIDER"
294print_table "PUBLIC KEY :" "$PUBKEY"
295print_green "---------------------------------------------------------------------------------------------"
296
297# install unbound
298if ! which unbound 1> /dev/null; then
299 print_question "Install Unbound (Caching DNS Server)" "[ Y / N: Default ]"
300 read installsrv
301 if [ "$(echo $installsrv | tr '[A-Z]' '[a-z]')" = "y" ]; then
302 apk add -q unbound
303 else
304 echo "nameserver 127.0.0.1" > /etc/resolv.conf
305 fi
306fi
307
308# check for / setup secondary loopback for dns caching
309if which unbound 1> /dev/null && ! grep "address 127.0.0.2" /etc/network/interfaces 1> /dev/null; then
310 IP=127.0.0.2
311 echo "##### Settings from $SCRIPT #####" >> /etc/network/interfaces
312 echo "auto lo:1" >> /etc/network/interfaces
313 echo "iface lo:1 inet static" >> /etc/network/interfaces
314 echo "address $IP" >> /etc/network/interfaces
315 echo "netmask 255.0.0.0" >> /etc/network/interfaces
316 ifconfig lo:1 $IP up
317fi
318
319# modify caching
320if grep "address 127.0.0.2" /etc/network/interfaces 1> /dev/null && [ ! $installsrv ]; then
321 print_question "\nRemove DNS Caching (Unbound) / Secondary loopback device ?" "[ Y / N: Default ]"; read removecache
322 if [ "$(echo $removecache | tr '[A-Z]' '[a-z]')" = "y" ]; then
323 # remove loopback settings
324 rm_loopback
325 echo -e ""; rc-service unbound stop; apk del unbound
326 else
327 print_green "\nSecondary Loopback for DNS Caching configured @ 127.0.0.2"
328 IP=127.0.0.2
329 fi
330fi
331
332# modify ip / ports
333if [ $installsrv ] || [ "$(echo $removecache | tr '[A-Z]' '[a-z]')" = "y" ]; then
334 modify_config
335elif grep -q 127.0.0.2 /etc/network/interfaces && ! which unbound 1> /dev/null; then
336 rm_loopback
337 kill $(cat /var/run/unbound/unbound.pid)
338 modify_config
339else
340 print_question "\nModify dnscrypt-proxy ip / port ?" "[ Y / N: default ]"; read updateip
341 if [ "$(echo $updateip | tr '[A-Z]' '[a-z]')" = "y" ]; then
342 modify_config
343 fi
344fi
345
346if [ "$RESTART_CLEAN" != "" ]; then
347 ifdown $RESTART_CLEAN && ifup $RESTART_CLEAN
348 print_green "Interface $RESTART_CLEAN restarted"
349fi
350
351restart_services
352
353exit 0
354