On 2018-12-02 01:01, M. Buecher wrote:
I spent some time on how to keep backward compatibility for current
configurations.

The simplest solution would be to provide 2 systemd unit files:
1. An updated dnsmasq.service file for the main/default/standard
"instance", that reflects the fix for checking the configuration (see
attached file).
2. The new dnsmasq@.service file from the previous post for additional
instances.

This way nothing would change for people running just a single dnsmasq
instance. No need to rename or sym-link /etc/default/dnsmasq to
dnsmasq.main (or similar).
Still people could easily create extra instances with the new
dnsmasq@.service file and a corresponding
/etc/default/dnsmasq.<instance> file.

Got some time to look at the upstream repo.
Updated init.d script to current state plus renamed files for upstream repo.
# This file has six functions:
# 1) to completely disable starting this dnsmasq instance
# 2) to set DOMAIN_SUFFIX by running `dnsdomainname`
# 3) to select an alternative config file
#    by setting DNSMASQ_OPTS to --conf-file=<file>
# 4) to tell dnsmasq to read the files in /etc/dnsmasq.d for
#    more configuration variables.
# 5) to stop the resolvconf package from controlling dnsmasq's
#    idea of which upstream nameservers to use.
# 6) to avoid using this dnsmasq instance as the system's default resolver
#    by setting DNSMASQ_EXCEPT="lo"
# For upgraders from very old versions, all the shell variables set
# here in previous versions are still honored by the init script
# so if you just keep your old version of this file nothing will break.

#DOMAIN_SUFFIX=`dnsdomainname`
#DNSMASQ_OPTS="--conf-file=/etc/dnsmasq.alt"

# Whether or not to run the dnsmasq daemon; set to 0 to disable.
ENABLED=1

# By default search this drop directory for configuration options.
# Libvirt leaves a file here to make the system dnsmasq play nice.
# Comment out this line if you don't want this. The dpkg-* are file
# endings which cause dnsmasq to skip that file. This avoids pulling
# in backups made by dpkg.
CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new

# If the resolvconf package is installed, dnsmasq will use its output
# rather than the contents of /etc/resolv.conf to find upstream
# nameservers. Uncommenting this line inhibits this behaviour.
# Note that including a "resolv-file=<filename>" line in
# /etc/dnsmasq.conf is not enough to override resolvconf if it is
# installed: the line below must be uncommented.
#IGNORE_RESOLVCONF=yes

# If the resolvconf package is installed, dnsmasq will tell resolvconf
# to use dnsmasq under 127.0.0.1 as the system's default resolver.
# Uncommenting this line inhibits this behaviour.
#DNSMASQ_EXCEPT="lo"
#!/bin/sh
### BEGIN INIT INFO
# Provides:       dnsmasq
# Required-Start: $network $remote_fs $syslog
# Required-Stop:  $network $remote_fs $syslog
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Description:    DHCP and DNS server
### END INIT INFO

# Don't exit on error status
set +e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/dnsmasq
NAME=dnsmasq
DESC="DNS forwarder and DHCP server"
INSTANCE="${2}"

# Most configuration options in /etc/default/dnsmasq are deprecated
# but still honoured.
ENABLED=1
if [ -r /etc/default/${NAME}${INSTANCE:+.${INSTANCE}} ]; then
    . /etc/default/${NAME}${INSTANCE:+.${INSTANCE}}
fi

# Get the system locale, so that messages are in the correct language, and the
# charset for IDN is correct
if [ -r /etc/default/locale ]; then
    . /etc/default/locale
    export LANG
fi

# The following test ensures the dnsmasq service is not started, when the
# package 'dnsmasq' is removed but not purged, even if the dnsmasq-base
# package is still in place.
test -e /usr/share/dnsmasq/installed-marker || exit 0

test -x ${DAEMON} || exit 0

# Provide skeleton LSB log functions for backports which don't have LSB functions.
if [ -f /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    log_warning_msg () {
        echo "${@}."
    }

    log_success_msg () {
        echo "${@}."
    }

    log_daemon_msg () {
        echo -n "${1}: ${2}"
    }

    log_end_msg () {
        if [ "${1}" -eq 0 ]; then
            echo "."
        elif [ "${1}" -eq 255 ]; then
            /bin/echo -e " (warning)."
        else
            /bin/echo -e " failed!"
        fi
    }
fi

# RESOLV_CONF:
# If the resolvconf package is installed then use the resolv conf file
# that it provides as the default.  Otherwise use /etc/resolv.conf as
# the default.
#
# If IGNORE_RESOLVCONF is set in /etc/default/dnsmasq or an explicit
# filename is set there then this inhibits the use of the resolvconf-provided
# information.
#
# Note that if the resolvconf package is installed it is not possible to
# override it just by configuration in /etc/dnsmasq.conf, it is necessary
# to set IGNORE_RESOLVCONF=yes in /etc/default/dnsmasq.

if [ ! "${RESOLV_CONF}" ] &&
   [ "${IGNORE_RESOLVCONF}" != "yes" ] &&
   [ -x /sbin/resolvconf ]
then
    RESOLV_CONF=/run/dnsmasq/resolv.conf
fi

for INTERFACE in ${DNSMASQ_INTERFACE}; do
    DNSMASQ_INTERFACES="${DNSMASQ_INTERFACES} -i ${INTERFACE}"
done

for INTERFACE in ${DNSMASQ_EXCEPT}; do
    DNSMASQ_INTERFACES="${DNSMASQ_INTERFACES} -I ${INTERFACE}"
done

if [ ! "${DNSMASQ_USER}" ]; then
   DNSMASQ_USER="dnsmasq"
fi

# This tells dnsmasq to ignore DNS requests that don't come from a local network.
# It's automatically ignored if --interface --except-interface, --listen-address
# or --auth-server exist in the configuration, so for most installations, it will
# have no effect, but for otherwise-unconfigured installations, it stops dnsmasq
# from being vulnerable to DNS-reflection attacks.

DNSMASQ_OPTS="${DNSMASQ_OPTS} --local-service"

# If the dns-root-data package is installed, then the trust anchors will be
# available in ROOT_DS, in BIND zone-file format. Reformat as dnsmasq
# --trust-anchor options.

ROOT_DS="/usr/share/dns/root.ds"

if [ -f ${ROOT_DS} ]; then
    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' ' '`"
fi

start()
{
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started

    # /run may be volatile, so we need to ensure that
    # /run/dnsmasq exists here as well as in postinst
    if [ ! -d /run/dnsmasq ]; then
        mkdir /run/dnsmasq || { [ -d /run/dnsmasq ] || return 2 ; }
        chown dnsmasq:nogroup /run/dnsmasq || return 2
    fi
    [ -x /sbin/restorecon ] && /sbin/restorecon /run/dnsmasq

    start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} --test > /dev/null || return 1
    start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} -- \
        -x /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid \
        ${MAILHOSTNAME:+ -m ${MAILHOSTNAME}} \
        ${MAILTARGET:+ -t ${MAILTARGET}} \
        ${DNSMASQ_USER:+ -u ${DNSMASQ_USER}} \
        ${DNSMASQ_INTERFACES:+ ${DNSMASQ_INTERFACES}} \
        ${DHCP_LEASE:+ -l ${DHCP_LEASE}} \
        ${DOMAIN_SUFFIX:+ -s ${DOMAIN_SUFFIX}} \
        ${RESOLV_CONF:+ -r ${RESOLV_CONF}} \
        ${CACHESIZE:+ -c ${CACHESIZE}} \
        ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} \
        ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} \
        || return 2
}

start_resolvconf()
{
# If interface "lo" is explicitly disabled in /etc/default/dnsmasq
# Then dnsmasq won't be providing local DNS, so don't add it to
# the resolvconf server set.
    for interface in ${DNSMASQ_EXCEPT}; do
        [ ${interface} = lo ] && return
    done

    # Also skip this if DNS functionality is disabled in /etc/dnsmasq.conf
    if grep -qs '^port=0' /etc/dnsmasq.conf; then
        return
    fi

    if [ -x /sbin/resolvconf ] ; then
        echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.${NAME}${INSTANCE:+.${INSTANCE}}
    fi
    return 0
}

stop()
{
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --name ${NAME}
}

stop_resolvconf()
{
    if [ -x /sbin/resolvconf ] ; then
        /sbin/resolvconf -d lo.${NAME}${INSTANCE:+.${INSTANCE}}
    fi
    return 0
}

status()
{
    # Return
    #   0 if daemon is running
    #   1 if daemon is dead and pid file exists
    #   3 if daemon is not running
    #   4 if daemon status is unknown
    start-stop-daemon --start --quiet --pidfile /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid --exec ${DAEMON} --test > /dev/null
    case "${?}" in
      0) [ -e "/run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid" ] && return 1 ; return 3 ;;
      1) return 0 ;;
      *) return 4 ;;
    esac
}

case "${1}" in
  start)
    test "${ENABLED}" != "0" || exit 0
    log_daemon_msg "Starting ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
    start
    case "${?}" in
      0)
        log_end_msg 0
        start_resolvconf
        exit 0
        ;;
      1)
        log_success_msg "(already running)"
        exit 0
        ;;
      *)
        log_end_msg 1
        exit 1
        ;;
    esac
    ;;
  stop)
    stop_resolvconf
    if [ "${ENABLED}" != "0" ]; then
        log_daemon_msg "Stopping ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
    fi
    stop
    RETVAL="${?}"
    if [ "${ENABLED}" = "0" ]; then
        case "${RETVAL}" in
          0) log_daemon_msg "Stopping ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"; log_end_msg 0 ;;
        esac
        exit 0
    fi
    case "${RETVAL}" in
      0) log_end_msg 0 ; exit 0 ;;
      1) log_warning_msg "(not running)" ; exit 0 ;;
      *) log_end_msg 1; exit 1 ;;
    esac
    ;;
  checkconfig)
    ${DAEMON} --test ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} >/dev/null 2>&1
    RETVAL="${?}"
    exit ${RETVAL}
    ;;
  restart|force-reload)
    test "${ENABLED}" != "0" || exit 1
    ${DAEMON} --test ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}} >/dev/null 2>&1
    if [ ${?} -ne 0 ]; then
        NAME="configuration syntax check"
        RETVAL="2"
    else
        stop_resolvconf
        stop
        RETVAL="${?}"
    fi
    log_daemon_msg "Restarting ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
    case "${RETVAL}" in
      0|1)
        sleep 2
        start
        case "${?}" in
          0)
            log_end_msg 0
            start_resolvconf
            exit 0
            ;;
          *)
            log_end_msg 1
            exit 1
            ;;
        esac
        ;;
      *)
        log_end_msg 1
        exit 1
        ;;
    esac
    ;;
  status)
    log_daemon_msg "Checking ${DESC}" "${NAME}${INSTANCE:+.${INSTANCE}}"
    status
    case "${?}" in
      0) log_success_msg "(running)" ; exit 0 ;;
      1) log_success_msg "(dead, pid file exists)" ; exit 1 ;;
      3) log_success_msg "(not running)" ; exit 3 ;;
      *) log_success_msg "(unknown)" ; exit 4 ;;
    esac
    ;;
  dump-stats)
    kill -s USR1 `cat /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid`
    ;;
  systemd-start-resolvconf)
    start_resolvconf
    ;;
  systemd-stop-resolvconf)
    stop_resolvconf
    ;;
  systemd-exec)
    # /run may be volatile, so we need to ensure that
    # /run/dnsmasq exists here as well as in postinst
    if [ ! -d /run/dnsmasq ]; then
        mkdir /run/dnsmasq || { [ -d /run/dnsmasq ] || return 2 ; }
        chown dnsmasq:nogroup /run/dnsmasq || return 2
    fi
    exec ${DAEMON} -x /run/dnsmasq/${NAME}${INSTANCE:+.${INSTANCE}}.pid \
        ${MAILHOSTNAME:+ -m ${MAILHOSTNAME}} \
        ${MAILTARGET:+ -t ${MAILTARGET}} \
        ${DNSMASQ_USER:+ -u ${DNSMASQ_USER}} \
        ${DNSMASQ_INTERFACES:+ ${DNSMASQ_INTERFACES}} \
        ${DHCP_LEASE:+ -l ${DHCP_LEASE}} \
        ${DOMAIN_SUFFIX:+ -s ${DOMAIN_SUFFIX}} \
        ${RESOLV_CONF:+ -r ${RESOLV_CONF}} \
        ${CACHESIZE:+ -c ${CACHESIZE}} \
        ${CONFIG_DIR:+ -7 ${CONFIG_DIR}} \
        ${DNSMASQ_OPTS:+ ${DNSMASQ_OPTS}}
    ;;
  *)
    echo "Usage: /etc/init.d/${NAME} {start|stop|restart|force-reload|dump-stats|status}" >&2
    exit 3
    ;;
esac

exit 0
[Unit]
Description=dnsmasq - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
After=network.target

[Service]
Type=forking
PIDFile=/run/dnsmasq/dnsmasq.pid

# Test the config file and refuse starting if it is not valid.
ExecStartPre=/etc/init.d/dnsmasq checkconfig

# We run dnsmasq via the /etc/init.d/dnsmasq script which acts as a
# wrapper picking up extra configuration files and then execs dnsmasq
# itself, when called with the "systemd-exec" function.
ExecStart=/etc/init.d/dnsmasq systemd-exec

# The systemd-*-resolvconf functions configure (and deconfigure)
# resolvconf to work with the dnsmasq DNS server. They're called like
# this to get correct error handling (ie don't start-resolvconf if the
# dnsmasq daemon fails to start).
ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf
ExecStop=/etc/init.d/dnsmasq systemd-stop-resolvconf


ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
[Unit]
Description=dnsmasq (%i) - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
After=network.target

[Service]
Type=forking
PIDFile=/run/dnsmasq/dnsmasq.%i.pid

# Test the config file and refuse starting if it is not valid.
ExecStartPre=/etc/init.d/dnsmasq checkconfig "%i"

# We run dnsmasq via the /etc/init.d/dnsmasq script which acts as a
# wrapper picking up extra configuration files and then execs dnsmasq
# itself, when called with the "systemd-exec" function.
ExecStart=/etc/init.d/dnsmasq systemd-exec "%i"

# The systemd-*-resolvconf functions configure (and deconfigure)
# resolvconf to work with the dnsmasq DNS server. They're called like
# this to get correct error handling (ie don't start-resolvconf if the
# dnsmasq daemon fails to start).
ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf "%i"
ExecStop=/etc/init.d/dnsmasq systemd-stop-resolvconf "%i"


ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss

Reply via email to