-
Notifications
You must be signed in to change notification settings - Fork 135
/
entrypoint.sh
executable file
·266 lines (230 loc) · 8.73 KB
/
entrypoint.sh
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
#! /usr/bin/env bash
set -e
action="$1"
LEGACY_KEYS_DIR="/opt/dnscrypt-wrapper/etc/keys"
LEGACY_LISTS_DIR="/opt/dnscrypt-wrapper/etc/lists"
LEGACY_STATE_DIR="${LEGACY_KEYS_DIR}/state"
KEYS_DIR="/opt/encrypted-dns/etc/keys"
STATE_DIR="${KEYS_DIR}/state"
LISTS_DIR="/opt/encrypted-dns/etc/lists"
CONF_DIR="/opt/encrypted-dns/etc"
CONFIG_FILE="${KEYS_DIR}/encrypted-dns.toml"
CONFIG_FILE_TEMPLATE="${CONF_DIR}/encrypted-dns.toml.in"
SERVICES_DIR="/etc/runit/runsvdir/svmanaged"
init() {
if [ "$(is_initialized)" = yes ]; then
start
exit $?
fi
anondns_enabled="false"
anondns_blacklisted_ips=""
metrics_address="127.0.0.1:9100"
while getopts "h?N:E:T:AM:" opt; do
case "$opt" in
h | \?) usage ;;
N) provider_name=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
E) ext_addresses=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
T) tls_proxy_upstream_address=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
A) anondns_enabled="true" ;;
M) metrics_address=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
esac
done
[ -z "$provider_name" ] && usage
case "$provider_name" in
.*) usage ;;
2.dnscrypt-cert.*) ;;
*) provider_name="2.dnscrypt-cert.${provider_name}" ;;
esac
[ -z "$ext_addresses" ] && usage
case "$ext_addresses" in
.*) usage ;;
0.*)
echo "Do not use 0.0.0.0, use an actual external IP address" >&2
exit 1
;;
esac
listen_addresses=$(get_listen_addresses "$ext_addresses")
tls_proxy_configuration=""
if [ -n "$tls_proxy_upstream_address" ]; then
tls_proxy_configuration="upstream_addr = \"${tls_proxy_upstream_address}\""
fi
domain_blacklist_file="${LISTS_DIR}/blacklist.txt"
domain_blacklist_configuration=""
if [ -s "$domain_blacklist_file" ]; then
chown _encrypted-dns:_encrypted-dns "$domain_blacklist_file"
domain_blacklist_configuration="domain_blacklist = \"${domain_blacklist_file}\""
fi
echo "Provider name: [$provider_name]"
echo "$provider_name" >"${KEYS_DIR}/provider_name"
chmod 644 "${KEYS_DIR}/provider_name"
sed \
-e "s#@PROVIDER_NAME@#${provider_name}#" \
-e "s#@LISTEN_ADDRESSES@#${listen_addresses}#" \
-e "s#@TLS_PROXY_CONFIGURATION@#${tls_proxy_configuration}#" \
-e "s#@DOMAIN_BLACKLIST_CONFIGURATION@#${domain_blacklist_configuration}#" \
-e "s#@ANONDNS_ENABLED@#${anondns_enabled}#" \
-e "s#@ANONDNS_BLACKLISTED_IPS@#${anondns_blacklisted_ips}#" \
-e "s#@METRICS_ADDRESS@#${metrics_address}#" \
"$CONFIG_FILE_TEMPLATE" >"$CONFIG_FILE"
mkdir -p -m 700 "${STATE_DIR}"
chown _encrypted-dns:_encrypted-dns "${STATE_DIR}"
if [ -f "${KEYS_DIR}/secret.key" ]; then
echo "Importing the previous secret key [${KEYS_DIR}/secret.key]"
/opt/encrypted-dns/sbin/encrypted-dns \
--config "$CONFIG_FILE" \
--import-from-dnscrypt-wrapper "${KEYS_DIR}/secret.key" \
--dry-run >/dev/null || exit 1
mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated"
fi
/opt/encrypted-dns/sbin/encrypted-dns \
--config "$CONFIG_FILE" --dry-run |
tee "${KEYS_DIR}/provider-info.txt"
echo
echo -----------------------------------------------------------------------
echo
echo "Congratulations! The container has been properly initialized."
echo "Take a look up above at the way dnscrypt-proxy has to be configured in order"
echo "to connect to your resolver. Then, start the container with the default command."
}
provider_info() {
ensure_initialized
echo
cat "${KEYS_DIR}/provider-info.txt"
echo
}
legacy_compat() {
if [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
return 0
fi
if [ -f "${LEGACY_KEYS_DIR}/provider-info.txt" ] && [ -f "${LEGACY_KEYS_DIR}/provider_name" ]; then
echo "Using [${LEGACY_KEYS_DIR}] for keys" >&2
mkdir -p -m 755 "${KEYS_DIR}"
mv -f "${KEYS_DIR}/provider-info.txt" "${KEYS_DIR}/provider-info.txt.migrated" 2>/dev/null || :
ln -s "${LEGACY_KEYS_DIR}/provider-info.txt" "${KEYS_DIR}/provider-info.txt" 2>/dev/null || :
mv -f "${KEYS_DIR}/provider_name" "${KEYS_DIR}/provider_name.migrated" 2>/dev/null || :
ln -s "${LEGACY_KEYS_DIR}/provider_name" "${KEYS_DIR}/provider_name" 2>/dev/null || :
mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated" 2>/dev/null || :
ln -s "${LEGACY_KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key" 2>/dev/null || :
mkdir -p -m 700 "${LEGACY_STATE_DIR}"
chown _encrypted-dns:_encrypted-dns "${KEYS_DIR}" "${STATE_DIR}" "${LEGACY_STATE_DIR}"
mv -f "$STATE_DIR" "${STATE_DIR}.migrated" 2>/dev/null || :
ln -s "$LEGACY_STATE_DIR" "${STATE_DIR}" 2>/dev/null || :
fi
if [ -f "${LEGACY_LISTS_DIR}/blacklist.txt" ]; then
echo "Using [${LEGACY_LISTS_DIR}] for lists" >&2
mkdir -p -m 755 "${LISTS_DIR}"
mv -f "${LISTS_DIR}/blacklist.txt" "${LISTS_DIR}/blacklist.txt.migrated" 2>/dev/null || :
ln -s "${LEGACY_LISTS_DIR}/blacklist.txt" "${LISTS_DIR}/blacklist.txt" 2>/dev/null || :
chown _encrypted-dns:_encrypted-dns "${LISTS_DIR}" "${LEGACY_LISTS_DIR}/blacklist.txt"
fi
}
is_initialized() {
if [ -f "$CONFIG_FILE" ] && [ -f "${STATE_DIR}/encrypted-dns.state" ] && [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
echo yes
else
legacy_compat
if [ -f "$CONFIG_FILE" ] && [ -f "${STATE_DIR}/encrypted-dns.state" ] && [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
echo yes
else
echo no
fi
fi
}
ensure_initialized() {
if [ "$(is_initialized)" = no ]; then
if [ -d "$LEGACY_KEYS_DIR" ]; then
echo "Please provide an initial configuration (init -N <provider_name> -E <external IP>)" >&2
fi
exit 1
fi
}
start() {
ensure_initialized
if [ -f "${KEYS_DIR}/secret.key" ]; then
echo "Importing the previous secret key [${KEYS_DIR}/secret.key]"
/opt/encrypted-dns/sbin/encrypted-dns \
--config "$CONFIG_FILE" \
--import-from-dnscrypt-wrapper "${KEYS_DIR}/secret.key" \
--dry-run >/dev/null || exit 1
mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated"
fi
/opt/encrypted-dns/sbin/encrypted-dns \
--config "$CONFIG_FILE" --dry-run |
tee "${KEYS_DIR}/provider-info.txt"
find /var/svc -mindepth 1 -maxdepth 1 -type d | while read -r service; do
ln -s -f "$service" "${SERVICES_DIR}/"
done
exec /etc/runit/2 </dev/null >/dev/null 2>/dev/null
}
shell() {
exec /bin/bash
}
is_ipv6() {
case "$1" in
\[[a-fA-F0-9:.]*\]:[0-9]*)
echo yes
;;
[0-9.]*:[0-9]*)
echo no
;;
*)
echo "IP and port should be specified as 'ipv4_addr:port' or '[ipv6_addr]:port'" >&2
exit 1
;;
esac
}
get_listen_addresses() {
listen_addresses=""
ext_addresses="$1"
OIFS="$IFS"
IFS=","
for ext_address in $ext_addresses; do
localport=$(echo "$ext_address" | sed -E 's/.*:([0-9]*)$/\1/')
if [ -z "$localport" ]; then
localport="443"
fi
entry="{ local = "
v6=$(is_ipv6 "$ext_address")
if [ "$v6" = "yes" ]; then
entry="${entry}\"[::]:${localport}\""
else
entry="${entry}\"0.0.0.0:${localport}\""
fi
entry="${entry}, external = \"${ext_address}\" }"
if [ -n "$listen_addresses" ]; then
listen_addresses="${listen_addresses}, "
fi
listen_addresses="${listen_addresses}${entry}"
done
IFS="$OIFS"
echo "${listen_addresses}"
}
usage() {
cat <<EOT
Commands
========
* init -N <provider_name> -E <external ip>:<port>[,<external ip>:<port>...]
initialize the container for a server accessible at ip <external ip> on port
<port>, for a provider named <provider_name>. This is required only once.
If TLS connections to the same port have to be redirected to a HTTPS server
(e.g. for DoH), add -T <https server ip>:<port>
To enable Anonymized DNS relaying, add -A.
* start (default command): start the resolver and the dnscrypt server proxy.
Ports 443/udp and 443/tcp have to be publicly exposed.
* provider-info: prints the provider name and provider public key.
* shell: run a shell.
This container has a single volume that you might want to securely keep a
backup of: /opt/encrypted-dns/etc/keys
EOT
exit 1
}
case "$action" in
start) start ;;
init)
shift
init "$@"
;;
provider-info) provider_info ;;
shell) shell ;;
*) usage ;;
esac