blob: 79344a37925f630bfe447206c921aa4aaf3c9cce [file] [log] [blame]
Simon Kelleyc72daea2012-01-05 21:33:27 +00001#!/bin/sh
2### BEGIN INIT INFO
3# Provides: dnsmasq
4# Required-Start: $network $remote_fs $syslog
5# Required-Stop: $network $remote_fs $syslog
6# Default-Start: 2 3 4 5
7# Default-Stop: 0 1 6
8# Description: DHCP and DNS server
9### END INIT INFO
10
Simon Kelley332c41e2016-05-01 22:36:46 +010011# Don't exit on error status
12set +e
Simon Kelleyc72daea2012-01-05 21:33:27 +000013
14PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
15DAEMON=/usr/sbin/dnsmasq
16NAME=dnsmasq
17DESC="DNS forwarder and DHCP server"
Simon Kelley343b7b42019-04-08 16:50:13 +010018INSTANCE="${2}"
Simon Kelleyc72daea2012-01-05 21:33:27 +000019
20# Most configuration options in /etc/default/dnsmasq are deprecated
21# but still honoured.
22ENABLED=1
Simon Kelley343b7b42019-04-08 16:50:13 +010023if [ -r /etc/default/${NAME}${INSTANCE:+.${INSTANCE}} ]; then
24 . /etc/default/${NAME}${INSTANCE:+.${INSTANCE}}
Simon Kelleyc72daea2012-01-05 21:33:27 +000025fi
26
Simon Kelley343b7b42019-04-08 16:50:13 +010027# Get the system locale, so that messages are in the correct language, and the
Simon Kelleyc72daea2012-01-05 21:33:27 +000028# charset for IDN is correct
29if [ -r /etc/default/locale ]; then
Simon Kelley343b7b42019-04-08 16:50:13 +010030 . /etc/default/locale
31 export LANG
Simon Kelleyc72daea2012-01-05 21:33:27 +000032fi
33
Simon Kelley332c41e2016-05-01 22:36:46 +010034# The following test ensures the dnsmasq service is not started, when the
Simon Kelley343b7b42019-04-08 16:50:13 +010035# package 'dnsmasq' is removed but not purged, even if the dnsmasq-base
Simon Kelley332c41e2016-05-01 22:36:46 +010036# package is still in place.
Simon Kelley9bb39982016-07-16 22:06:01 +010037test -e /usr/share/dnsmasq/installed-marker || exit 0
Simon Kelley343b7b42019-04-08 16:50:13 +010038
39test -x ${DAEMON} || exit 0
Simon Kelleyc72daea2012-01-05 21:33:27 +000040
41# Provide skeleton LSB log functions for backports which don't have LSB functions.
42if [ -f /lib/lsb/init-functions ]; then
Simon Kelley343b7b42019-04-08 16:50:13 +010043 . /lib/lsb/init-functions
Simon Kelleyc72daea2012-01-05 21:33:27 +000044else
Simon Kelley343b7b42019-04-08 16:50:13 +010045 log_warning_msg () {
46 echo "${@}."
47 }
Simon Kelleyc72daea2012-01-05 21:33:27 +000048
Simon Kelley343b7b42019-04-08 16:50:13 +010049 log_success_msg () {
50 echo "${@}."
51 }
Simon Kelleyc72daea2012-01-05 21:33:27 +000052
Simon Kelley343b7b42019-04-08 16:50:13 +010053 log_daemon_msg () {
54 echo -n "${1}: ${2}"
55 }
Simon Kelleyc72daea2012-01-05 21:33:27 +000056
Simon Kelley343b7b42019-04-08 16:50:13 +010057 log_end_msg () {
58 if [ "${1}" -eq 0 ]; then
59 echo "."
60 elif [ "${1}" -eq 255 ]; then
61 /bin/echo -e " (warning)."
62 else
63 /bin/echo -e " failed!"
64 fi
65 }
Simon Kelleyc72daea2012-01-05 21:33:27 +000066fi
67
68# RESOLV_CONF:
69# If the resolvconf package is installed then use the resolv conf file
70# that it provides as the default. Otherwise use /etc/resolv.conf as
71# the default.
72#
73# If IGNORE_RESOLVCONF is set in /etc/default/dnsmasq or an explicit
74# filename is set there then this inhibits the use of the resolvconf-provided
75# information.
76#
Simon Kelley343b7b42019-04-08 16:50:13 +010077# Note that if the resolvconf package is installed it is not possible to
Simon Kelleyc72daea2012-01-05 21:33:27 +000078# override it just by configuration in /etc/dnsmasq.conf, it is necessary
79# to set IGNORE_RESOLVCONF=yes in /etc/default/dnsmasq.
80
Simon Kelley343b7b42019-04-08 16:50:13 +010081if [ ! "${RESOLV_CONF}" ] &&
82 [ "${IGNORE_RESOLVCONF}" != "yes" ] &&
Simon Kelleyc72daea2012-01-05 21:33:27 +000083 [ -x /sbin/resolvconf ]
84then
Simon Kelley343b7b42019-04-08 16:50:13 +010085 RESOLV_CONF=/run/dnsmasq/resolv.conf
Simon Kelleyc72daea2012-01-05 21:33:27 +000086fi
87
Simon Kelley343b7b42019-04-08 16:50:13 +010088for INTERFACE in ${DNSMASQ_INTERFACE}; do
89 DNSMASQ_INTERFACES="${DNSMASQ_INTERFACES} -i ${INTERFACE}"
Simon Kelleyc72daea2012-01-05 21:33:27 +000090done
91
Simon Kelley343b7b42019-04-08 16:50:13 +010092for INTERFACE in ${DNSMASQ_EXCEPT}; do
93 DNSMASQ_INTERFACES="${DNSMASQ_INTERFACES} -I ${INTERFACE}"
Simon Kelleyc72daea2012-01-05 21:33:27 +000094done
95
Simon Kelley343b7b42019-04-08 16:50:13 +010096if [ ! "${DNSMASQ_USER}" ]; then
Simon Kelleyc72daea2012-01-05 21:33:27 +000097 DNSMASQ_USER="dnsmasq"
98fi
99
Simon Kelley1a9a3482014-03-05 15:01:08 +0000100# This tells dnsmasq to ignore DNS requests that don't come from a local network.
Simon Kelley343b7b42019-04-08 16:50:13 +0100101# It's automatically ignored if --interface --except-interface, --listen-address
Simon Kelley1a9a3482014-03-05 15:01:08 +0000102# or --auth-server exist in the configuration, so for most installations, it will
103# have no effect, but for otherwise-unconfigured installations, it stops dnsmasq
104# from being vulnerable to DNS-reflection attacks.
105
Simon Kelley343b7b42019-04-08 16:50:13 +0100106DNSMASQ_OPTS="${DNSMASQ_OPTS} --local-service"
Simon Kelley1a9a3482014-03-05 15:01:08 +0000107
Simon Kelley343b7b42019-04-08 16:50:13 +0100108# If the dns-root-data package is installed, then the trust anchors will be
109# available in ROOT_DS, in BIND zone-file format. Reformat as dnsmasq
Simon Kelleyc43b8a62014-09-07 19:34:39 +0100110# --trust-anchor options.
111
112ROOT_DS="/usr/share/dns/root.ds"
113
Simon Kelley343b7b42019-04-08 16:50:13 +0100114if [ -f ${ROOT_DS} ]; then
Simon Kelley39d85502017-12-14 21:23:34 +0000115 DNSMASQ_OPTS="$DNSMASQ_OPTS `env LC_ALL=C sed -rne "s/^([.a-zA-Z0-9]+)([[:space:]]+[0-9]+)*([[:space:]]+IN)*[[:space:]]+DS[[:space:]]+/--trust-anchor=\1,/;s/[[:space:]]+/,/gp" $ROOT_DS | tr '\n' ' '`"
Simon Kelleyc43b8a62014-09-07 19:34:39 +0100116fi
117
Simon Kelleyc72daea2012-01-05 21:33:27 +0000118start()
119{
Simon Kelley343b7b42019-04-08 16:50:13 +0100120 # Return
121 # 0 if daemon has been started
122 # 1 if daemon was already running
123 # 2 if daemon could not be started
Simon Kelleyc72daea2012-01-05 21:33:27 +0000124
Simon Kelley343b7b42019-04-08 16:50:13 +0100125 # /run may be volatile, so we need to ensure that
126 # /run/dnsmasq exists here as well as in postinst
127 if [ ! -d /run/dnsmasq ]; then
128 mkdir /run/dnsmasq || { [ -d /run/dnsmasq ] || return 2 ; }
129 chown dnsmasq:nogroup /run/dnsmasq || return 2
130 fi
131 [ -x /sbin/restorecon ] && /sbin/restorecon /run/dnsmasq
132
133 start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} --test > /dev/null || return 1
134 start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} -- \
135 -x /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid \
136 ${MAILHOSTNAME:+ -m ${MAILHOSTNAME}} \
137 ${MAILTARGET:+ -t ${MAILTARGET}} \
138 ${DNSMASQ_USER:+ -u ${DNSMASQ_USER}} \
139 ${DNSMASQ_INTERFACES:+ ${DNSMASQ_INTERFACES}} \
140 ${DHCP_LEASE:+ -l ${DHCP_LEASE}} \
141 ${DOMAIN_SUFFIX:+ -s ${DOMAIN_SUFFIX}} \
142 ${RESOLV_CONF:+ -r ${RESOLV_CONF}} \
143 ${CACHESIZE:+ -c ${CACHESIZE}} \
144 ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} \
145 ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} \
146 || return 2
Simon Kelleyc72daea2012-01-05 21:33:27 +0000147}
148
149start_resolvconf()
150{
151# If interface "lo" is explicitly disabled in /etc/default/dnsmasq
152# Then dnsmasq won't be providing local DNS, so don't add it to
153# the resolvconf server set.
Simon Kelley343b7b42019-04-08 16:50:13 +0100154 for interface in ${DNSMASQ_EXCEPT}; do
155 [ ${interface} = lo ] && return
156 done
Simon Kelleyc72daea2012-01-05 21:33:27 +0000157
Simon Kelley343b7b42019-04-08 16:50:13 +0100158 # Also skip this if DNS functionality is disabled in /etc/dnsmasq.conf
159 if grep -qs '^port=0' /etc/dnsmasq.conf; then
160 return
161 fi
Floris Bosbc87e602017-04-11 14:19:57 +0100162
Simon Kelley343b7b42019-04-08 16:50:13 +0100163 if [ -x /sbin/resolvconf ] ; then
164 echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.${NAME}${INSTANCE:+.${INSTANCE}}
165 fi
166 return 0
Simon Kelleyc72daea2012-01-05 21:33:27 +0000167}
168
169stop()
170{
Simon Kelley343b7b42019-04-08 16:50:13 +0100171 # Return
172 # 0 if daemon has been stopped
173 # 1 if daemon was already stopped
174 # 2 if daemon could not be stopped
175 # other if a failure occurred
176 start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --name ${NAME}
Simon Kelleyc72daea2012-01-05 21:33:27 +0000177}
178
179stop_resolvconf()
180{
Simon Kelley343b7b42019-04-08 16:50:13 +0100181 if [ -x /sbin/resolvconf ] ; then
182 /sbin/resolvconf -d lo.${NAME}${INSTANCE:+.${INSTANCE}}
183 fi
184 return 0
Simon Kelleyc72daea2012-01-05 21:33:27 +0000185}
186
187status()
188{
Simon Kelley343b7b42019-04-08 16:50:13 +0100189 # Return
190 # 0 if daemon is running
191 # 1 if daemon is dead and pid file exists
192 # 3 if daemon is not running
193 # 4 if daemon status is unknown
194 start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} --test > /dev/null
195 case "${?}" in
196 0) [ -e "/run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid" ] && return 1 ; return 3 ;;
197 1) return 0 ;;
198 *) return 4 ;;
199 esac
Simon Kelleyc72daea2012-01-05 21:33:27 +0000200}
201
Simon Kelley343b7b42019-04-08 16:50:13 +0100202case "${1}" in
Simon Kelleyc72daea2012-01-05 21:33:27 +0000203 start)
Simon Kelley343b7b42019-04-08 16:50:13 +0100204 test "${ENABLED}" != "0" || exit 0
205 log_daemon_msg "Starting ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
206 start
207 case "${?}" in
208 0)
209 log_end_msg 0
210 start_resolvconf
211 exit 0
212 ;;
213 1)
214 log_success_msg "(already running)"
215 exit 0
216 ;;
217 *)
218 log_end_msg 1
219 exit 1
220 ;;
221 esac
222 ;;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000223 stop)
Simon Kelley343b7b42019-04-08 16:50:13 +0100224 stop_resolvconf
225 if [ "${ENABLED}" != "0" ]; then
226 log_daemon_msg "Stopping ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
227 fi
228 stop
229 RETVAL="${?}"
230 if [ "${ENABLED}" = "0" ]; then
231 case "${RETVAL}" in
232 0) log_daemon_msg "Stopping ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"; log_end_msg 0 ;;
233 esac
234 exit 0
235 fi
236 case "${RETVAL}" in
237 0) log_end_msg 0 ; exit 0 ;;
238 1) log_warning_msg "(not running)" ; exit 0 ;;
239 *) log_end_msg 1; exit 1 ;;
240 esac
241 ;;
242 checkconfig)
243 ${DAEMON} --test ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} >/dev/null 2>&1
244 RETVAL="${?}"
245 exit ${RETVAL}
246 ;;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000247 restart|force-reload)
Simon Kelley343b7b42019-04-08 16:50:13 +0100248 test "${ENABLED}" != "0" || exit 1
249 ${DAEMON} --test ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} >/dev/null 2>&1
250 if [ ${?} -ne 0 ]; then
251 NAME="configuration syntax check"
252 RETVAL="2"
253 else
254 stop_resolvconf
255 stop
256 RETVAL="${?}"
257 fi
258 log_daemon_msg "Restarting ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
259 case "${RETVAL}" in
260 0|1)
261 sleep 2
262 start
263 case "${?}" in
264 0)
265 log_end_msg 0
266 start_resolvconf
267 exit 0
268 ;;
269 *)
270 log_end_msg 1
271 exit 1
272 ;;
273 esac
274 ;;
275 *)
276 log_end_msg 1
277 exit 1
278 ;;
279 esac
280 ;;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000281 status)
Simon Kelley343b7b42019-04-08 16:50:13 +0100282 log_daemon_msg "Checking ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
283 status
284 case "${?}" in
285 0) log_success_msg "(running)" ; exit 0 ;;
286 1) log_success_msg "(dead, pid file exists)" ; exit 1 ;;
287 3) log_success_msg "(not running)" ; exit 3 ;;
288 *) log_success_msg "(unknown)" ; exit 4 ;;
289 esac
290 ;;
Simon Kelley760169f2012-03-09 14:27:49 +0000291 dump-stats)
Simon Kelley343b7b42019-04-08 16:50:13 +0100292 kill -s USR1 `cat /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid`
293 ;;
Simon Kelley2cd9a0d2012-06-11 21:56:10 +0100294 systemd-start-resolvconf)
Simon Kelley343b7b42019-04-08 16:50:13 +0100295 start_resolvconf
296 ;;
Simon Kelley2cd9a0d2012-06-11 21:56:10 +0100297 systemd-stop-resolvconf)
Simon Kelley343b7b42019-04-08 16:50:13 +0100298 stop_resolvconf
299 ;;
Simon Kelley2cd9a0d2012-06-11 21:56:10 +0100300 systemd-exec)
Simon Kelley343b7b42019-04-08 16:50:13 +0100301 # /run may be volatile, so we need to ensure that
302 # /run/dnsmasq exists here as well as in postinst
303 if [ ! -d /run/dnsmasq ]; then
304 mkdir /run/dnsmasq || { [ -d /run/dnsmasq ] || return 2 ; }
305 chown dnsmasq:nogroup /run/dnsmasq || return 2
306 fi
307 exec ${DAEMON} -x /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid \
308 ${MAILHOSTNAME:+ -m ${MAILHOSTNAME}} \
309 ${MAILTARGET:+ -t ${MAILTARGET}} \
310 ${DNSMASQ_USER:+ -u ${DNSMASQ_USER}} \
311 ${DNSMASQ_INTERFACES:+ ${DNSMASQ_INTERFACES}} \
312 ${DHCP_LEASE:+ -l ${DHCP_LEASE}} \
313 ${DOMAIN_SUFFIX:+ -s ${DOMAIN_SUFFIX}} \
314 ${RESOLV_CONF:+ -r ${RESOLV_CONF}} \
315 ${CACHESIZE:+ -c ${CACHESIZE}} \
316 ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} \
317 ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}}
318 ;;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000319 *)
Simon Kelley343b7b42019-04-08 16:50:13 +0100320 echo "Usage: /etc/init.d/${NAME} {start|stop|restart|force-reload|dump-stats|status}" >&2
321 exit 3
322 ;;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000323esac
324
325exit 0