aboutsummaryrefslogtreecommitdiffstats
path: root/main/unbound/migrate-dnscache-to-unbound
blob: 368504f7f64d07d93fd69d803d08ab1ce0ff45a2 (plain) (blame)
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
#!/bin/sh


to_subnet() {
	pref=$1
	case "$pref" in
	*.*.*.*) echo $pref/32;;
	*.*.*) echo $pref.0/24;;
	*.*) echo $pref.0.0/16;;
	*) echo $pref.0.0.0/8;;
	esac
}

gen_config() {
	echo "# Config generated by $0, $(date)"
	echo "server:"
	echo -e "\troot-hints: /usr/share/dns-root-hints/named.root\n"

	[ -n "$IP" ] && echo -e "\tinterface: $IP\n"
	[ -n "$IPSEND" ] && echo -e "\toutgoing-interface: $IPSEND\n"

	for i in $access_control; do
		echo -e "\taccess-control: $i allow"
	done
	echo ""

	# stub zones
	local zonefile ip
	local fwdtype="stub"
	if [ -n "$FORWARDONLY" ]; then
		fwdtype="forward"
	fi
	for zonefile in "$root"/etc/dnscache/servers/*; do
		local zone=${zonefile##*/}
		case "$zone" in
			'@'|'*'|*.apk-new) continue;;
		esac
		echo "${fwdtype}-zone:"
		echo -e "\tname: ${zone}"
		for ip in $(cat $zonefile); do
			echo -e "\t${fwdtype}-addr: $ip"
		done
		echo ""
	done
}

usage() {
	cat >&2 <<EOF
usage: $0 [-h] [-r ROOT]
Migrate dnscache configuration to unbound

This tool will install unbound, migrate the configuration, stop dnscache
and start unbound and remove traces of dnscache.

Options:
 -c  Only dump the config to stdout and exit
 -h  Show this help
 -k  Keep unbound.conf.backup and keep dnscache config
 -r  Look for dnscache config in ROOT/etc/dnscache

EOF
}

root=${ROOT:-/}
dump_config=false
quiet=false
keep_backup=false
while getopts "chr:" opt; do
	case "$opt" in
	'c') dump_config=true;;
	'h') usage; exit;;
	'k') keep_backup=true;;
	'r') root="$OPTARG";;
	'q') quiet=true; quiet_opt=--quiet;;
	esac
done
unbound_conf=${UNBOUND_CONF:-${root%/}/etc/unbound/unbound.conf}

# read dnscache config
if ! [ -f "$root"/etc/conf.d/dnscache ] && ! [ -d "$root"/etc/dnscache ]; then
	echo "No dnscache config found"
	exit 1
fi

confd="$root"/etc/conf.d/dnscache
if [ -r "$confd" ]; then
	. "$confd"
fi

interface="$IP"
outgoing_interface="$IPSEND"

for i in "$root"/etc/dnscache/ip/*; do
	[ -f "$i" ] || continue
	access_control="$access_control $(to_subnet ${i##*/})"
done

if $dump_config; then
	gen_config
	exit 0
fi

# install unbound if needed
if ! apk info -e unbound; then
	apk add $quiet_opt unbound
fi

# generate config
if [ -f "$unbound_conf" ]; then
	$quiet || echo "Backing up $unbound_conf" >&2
	mv "$unbound_conf" "${unbound_conf}".backup
fi

$quiet || echo "Generating $unbound_conf" >&2
gen_config > "$unbound_conf"

# stop dnscache and start unbound
if /etc/init.d/dnscache --quiet status 2>/dev/null; then
	/etc/init.d/dnscache $quiet_opt stop
	if ! /etc/init.d/unbound $quiet_opt start; then
		echo "Failed to start unbound. Starting up dnscache again"
		/etc/init.d/dnscache $quiet_opt start
		exit 1
	fi
fi

# update runlevels
errors=0
if rc-update | grep -q -w dnscache; then
	runlevels=$(rc-update | awk '$1 == "dnscache" { FS="|"; $0 = $0; print $2 }')
	for level in $runlevels; do
		rc-update $quiet_opt add unbound $level \
			|| errors=$(($errors + 1))
		rc-update $quiet_opt del dnscache $level \
			|| errors=$(($errors + 1))
	done
fi

# cleanup if requested
if [ $errors -eq 0 ] && ! $keep_backup ; then
	$quiet || echo "Purging dnscache and dnscache config" >&2
	apk del --purge $quiet_opt dnscache
	rm -rf $root/etc/dnscache $root/etc/conf.d/dnscache
	$quiet || echo "Purging ${unbound_conf}.backup" >&2
	rm -rf ${unbound_conf}.backup
fi

exit $errors