LoginSignup
2
2

More than 3 years have passed since last update.

NanoPI上でdeadwoodを動かす

Last updated at Posted at 2018-08-15

摘要

介绍用于嵌入式使用的MaraDNS-deadwood。

  • 用C,C ++编写
  • 尺寸小于800 KiB
  • 很轻
  • 设置简单

它具有的特点

はじめに

インターネットで外部ホストと通信するとき普通は「名前」からIP Addressを参照するDNS (Domain Name System)を使います。
RouterやServerのBINDに接続するパターンが多いでしょう。DHCP Serverから提供される情報に、DNS ServerのAdderssが含まれるので、これを使うのが一般的です。

IoTの事情

一般のClient Machineの話をしましたが、IoT機器の場合、

  • DHCP Serverがない
  • DNS Serverがない
  • DNS Serverを使用する権限がない
  • 自分自身がサーバーである

と言った事情でDNS Serverを参照できない場合があります。

自前で名前を解決する

こうした場合サーバーを自前で立ち上げるのですが、おなじみのBIND9は

  • 多くのマシンからリクエストを受けるのを前提としている
  • でかい
  • 重い
  • コーディングが汚い
  • バグが多い

すみません。終わりの2つは愚痴です。

コンパクトで軽いDNS Server

そこで、組み込み用に書かれたMaraDNS-deadwoodをご紹介します。

  • C, C++でコーデングされている
  • 800KiBに満たない大きさ
  • 大変に軽い
  • セッティングが簡単

という特長を持っています。

では早速Installしてみましょう。
NanoPI Noe2 Armbian (Debian)を前提にしてます。

apt update
apt upgrade
apt install maradns-deadwood
mkdir -p /etc/maradns/deadwood
mkdir /etc/deadwood

vi /etc/maradns/deadwood/dwood3rcで

# This is an example deadwood rc file
# Note that comments are started by the hash symbol

bind_address="192.168.254.40, 127.0.0.1"

# The following line is disabled by being commented out
# bind_address="::1" # We have optional IPv6 support

chroot_dir = "/etc/deadwood" # Directory we run program from (not used in Win32)

# The following upstream DNS servers are Google's newly-announced (as of
# December, 2009) public DNS servers.  For more information, see
# the page at http://code.google.com/speed/public-dns/
#
# These IPs can be changed to the IPs of any recursive DNS servers that
# can be reached from the computer running Deadwood.
#
# These are commented out; if upstream_servers is not set, Deadwood will
# act as a recursive DNS server
#
# Please note that each upstream_servers entry takes up space in Deadwood's
# cache and that maximum_cache_elements will need to be increased to store
# a large number of these entries.
#upstream_servers = {}
#upstream_servers["."]="8.8.8.8, 8.8.4.4" # Servers we connect to

# It is also possible to use other root servers or to blacklist
# a phising website.  However, to do this, root_servers needs to be
# defined.  For example, to blacklist the domain "phish.example.com":
# ICANN DNS root servers (Deadwood default if both root_servers and
# upstream_servers are not defined)
root_servers = {}
root_servers["."]="198.41.0.4, 199.9.14.201, 192.33.4.12, 199.7.91.13,"
root_servers["."]+="192.203.230.10, 192.5.5.241, 192.112.36.4, "
root_servers["."]+="198.97.190.53, 192.36.148.17, 192.58.128.30, "
root_servers["."]+="193.0.14.129, 199.7.83.42, 202.12.27.33"
#root_servers["phish.example.com."]="10.254.254.254"
# Please note that each root_servers entry takes up space in Deadwood's
# cache and that maximum_cache_elements will need to be increased to store
# a large number of these entries.
# Who is allowed to use the cache
recursive_acl = "192.168.0.0/16, 127.0.0.1/8"

maxprocs = 2048 # Maximum number of pending requests
handle_overload = 1 # Send SERVER FAIL when overloaded

maradns_uid = 99 # UID Deadwood runs as
maradns_gid = 99 # GID Deadwood runs as

maximum_cache_elements = 60000

# If you want to read and write the cache from disk, make sure chroot_dir
# above is readable and writable by the maradns_uid/gid above, and
# uncomment the following line
cache_file = "dw_cache"

# The following line tells deadwood to fetch an expired record if it's
# impossible to connect to any nameservers
resurrections = 1
filter_rfc1918=1

次の起動ファイルを作ります。
vi /etc/init.d/deadwood

cat /etc/init.d/deadwood
#! /bin/sh
### BEGIN INIT INFO
# Provides:          deadwood
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop deadwood
# Description:       deadwood is a Domain Name Server (DNS)
#       which translates IP addresses to and from internet names
### END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="domain name server"
NAME=deadwood
DAEMON=/usr/sbin/$NAME
DUENDE=/usr/sbin/duende
SCRIPTNAME=/etc/init.d/$NAME
WORKING_DIR=/run/$NAME
OUR_UID=`id --user maradns`
OUR_GID=`id --group maradns`

# It is possible to have more than one maradns server
# running on the same machine so long as they bind to different IP
# addresses. You specify multiple config files in the
# SERVERS variable in /etc/default/maradns.
# This goes back to #176066.

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{

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

        # Now start the actual maradns process
        PIDFILE="$WORKING_DIR/$SERVERNAME.pid"
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
        start-stop-daemon --start --quiet --background --pidfile $PIDFILE --startas $DUENDE -- --pid $PIDFILE --uid $OUR_UID --gid $OUR_GID --ident $SERVERNAME -- $DAEMON -f $rcfile
        sleep 3
        if ! pidofproc -p $PIDFILE $DAEMON > /dev/null
        then
            rm -rf $PIDFILE
            return 2
        fi
}

#
# Function that stops the daemon/service
#
do_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
        PIDFILE="$WORKING_DIR/$SERVERNAME.pid"
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name duende
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -f $PIDFILE
        return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
        #
        # If the daemon can reload its configuration without
        # restarting (for example, when it is sent a SIGHUP),
        # then implement that here.
        #
        PIDFILE="$WORKING_DIR/$SERVERNAME.pid"
        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name duende
        return 0
}

if [ -z "$SERVERS" ]
then
    log_action_msg "No maradns servers configured"
    exit 0
fi

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC..."

        # dir can go away on reboots
        mkdir -p $WORKING_DIR
        chmod 775 $WORKING_DIR
        chown maradns:root $WORKING_DIR >/dev/null 2>&1 || true

        for rcfile in $SERVERS
        do
            SERVERNAME=`echo $rcfile | sed 's/\//_/g;s/^_*//;' | awk -F. '{print $NF}'`
            do_start
            case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_progress_msg "$SERVERNAME" ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1
                exit 1
                ;;
            esac
        done
        [ "$VERBOSE" != no ] && log_end_msg 0
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC"
        for rcfile in $SERVERS
        do
            SERVERNAME=`echo $rcfile | sed 's/\//_/g;s/^_*//;' | awk -F. '{print $NF}'`
            do_stop
            case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_progress_msg "$SERVERNAME" ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1
                exit 1
                ;;
            esac
        done
        [ "$VERBOSE" != no ] && log_end_msg 0
        ;;
  status)
        for rcfile in $SERVERS
        do
            SERVERNAME=`echo $rcfile | sed 's/\//_/g;s/^_*//;' | awk -F. '{print $NF}'`
            status_of_proc -p "$WORKING_DIR/$SERVERNAME.pid" $DAEMON $SERVERNAME || exit $?
        done
        exit 0
        ;;
  reload|force-reload)
        for rcfile in $SERVERS
        do
            SERVERNAME=`echo $rcfile | sed 's/\//_/g;s/^_*//;' | awk -F. '{print $NF}'`
            log_daemon_msg "Reloading $DESC" "$NAME"
            do_reload
            case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_progress_msg "$SERVERNAME" ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1
                exit 1
                ;;
            esac
        done
        log_end_msg 0
        ;;
  restart)
        $0 stop
        [ "$?" = "0" ] || exit "$?"
        sleep 3
        $0 start
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2
        exit 3
        ;;
esac

BIND9を使っていたなら、止めます。
deadwoodを起動して設定変更を有効にします。

systemctl stop bind9
chmod +x /etc/init.d/deadwood
/lib/systemd/systemd-sysv-install enable deadwood
mkdir /var/deadwood
cp /dev/null /var/deadwood/dw_chache
chown -R maradns.maradns /var/deadwood

systemctl restart deadwood

deadwoodを使う設定か確かめ、なってなければ直します。
vi /etc/network/interfaces

iface eth0 inet static
        address 192.168.254.31
        gateway 192.168.254.31
        dns-servers 127.0.0.1

試験します。

apt install dnsutils
dig www.microsoft.com

BIND9を消してdeadwoodを自動起動にします。

apt remove bind9
update-rc.d deadwood enable

結論

MaraDNS-deadwoodは組み込みに適した小型軽量のDNS Serverです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2