Changeset View
Changeset View
Standalone View
Standalone View
dns/bind99/files/named.in
#!/bin/sh | #!/bin/sh | ||||
# | # | ||||
# $FreeBSD$ | # $FreeBSD$ | ||||
# | # | ||||
# PROVIDE: named | # PROVIDE: named | ||||
# REQUIRE: FILESYSTEMS defaultroute ldconfig | # REQUIRE: FILESYSTEMS defaultroute ldconfig | ||||
# BEFORE: NETWORKING | # BEFORE: NETWORKING | ||||
# KEYWORD: shutdown | # KEYWORD: shutdown | ||||
# | |||||
# Add the following lines to /etc/rc.conf to enable BIND: | |||||
# named_enable (bool): Run named, the DNS server (or NO). | |||||
# named_program (str): Path to named, if you want a different one. | |||||
# named_conf (str): Path to the configuration file | |||||
# named_flags (str): Use this for flags OTHER than -u and -c | |||||
# named_uid (str): User to run named as | |||||
# named_chrootdir (str): Chroot directory (or "" not to auto-chroot it) | |||||
# Historically, was /var/named | |||||
# named_chroot_autoupdate (bool): Automatically install/update chrooted | |||||
# components of named. | |||||
# named_symlink_enable (bool): Symlink the chrooted pid file | |||||
# named_wait (bool): Wait for working name service before exiting | |||||
# named_wait_host (str): Hostname to check if named_wait is enabled | |||||
# named_auto_forward (str): Set up forwarders from /etc/resolv.conf | |||||
# named_auto_forward_only (str): Do "forward only" instead of "forward first" | |||||
# | |||||
. /etc/rc.subr | . /etc/rc.subr | ||||
name=named | name=named | ||||
desc="named BIND startup script" | |||||
rcvar=named_enable | rcvar=named_enable | ||||
load_rc_config $name | load_rc_config ${name} | ||||
extra_commands=reload | extra_commands=reload | ||||
start_precmd=named_prestart | start_precmd=named_prestart | ||||
start_postcmd=named_poststart | start_postcmd=named_poststart | ||||
reload_cmd=named_reload | reload_cmd=named_reload | ||||
stop_cmd=named_stop | stop_cmd=named_stop | ||||
stop_postcmd=named_poststop | |||||
named_enable=${named_enable:-"NO"} # Run named, the DNS server (or NO). | named_enable=${named_enable:-"NO"} | ||||
named_program=${named_program:-"%%PREFIX%%/sbin/named"} # Path to named, if you want a different one. | named_program=${named_program:-"%%PREFIX%%/sbin/named"} | ||||
named_conf=${named_conf:-"%%ETCDIR%%/named.conf"} # Path to the configuration file | named_conf=${named_conf:-"%%ETCDIR%%/named.conf"} | ||||
named_flags=${named_flags:-""} # Use this for flags OTHER than -u and -c | named_flags=${named_flags:-""} | ||||
named_uid=${named_uid:-"bind"} # User to run named as | named_uid=${named_uid:-"bind"} | ||||
named_wait=${named_wait:-"NO"} # Wait for working name service before exiting | named_chrootdir=${named_chrootdir:-""} | ||||
named_wait_host=${named_wait_host:-"localhost"} # Hostname to check if named_wait is enabled | named_chroot_autoupdate=${named_chroot_autoupdate:-"YES"} | ||||
named_auto_forward=${named_auto_forward:-"NO"} # Set up forwarders from /etc/resolv.conf | named_symlink_enable=${named_symlink_enable:-"YES"} | ||||
named_auto_forward_only=${named_auto_forward_only:-"NO"} # Do "forward only" instead of "forward first" | named_wait=${named_wait:-"NO"} | ||||
named_confdir="${named_conf%/*}" # Not a configuration directive but makes rclint happy. | named_wait_host=${named_wait_host:-"localhost"} | ||||
named_auto_forward=${named_auto_forward:-"NO"} | |||||
named_auto_forward_only=${named_auto_forward_only:-"NO"} | |||||
# Not configuration variables but having them here keeps rclint happy | |||||
required_dirs="${named_chrootdir}" | |||||
_named_confdirroot="${named_conf%/*}" | |||||
_named_confdir="${named_chrootdir}${_named_confdirroot}" | |||||
_named_program_root="${named_program%/sbin/named}" | |||||
_openssl_engines="%%LOCALBASE%%/lib/engines" | |||||
# If running in a chroot cage, ensure that the appropriate files | |||||
# exist inside the cage, as well as helper symlinks into the cage | |||||
# from outside. | |||||
# | |||||
# As this is called after the is_running and required_dir checks | |||||
# are made in run_rc_command(), we can safely assume ${named_chrootdir} | |||||
# exists and named isn't running at this point (unless forcestart | |||||
# is used). | |||||
# | |||||
chroot_autoupdate() | |||||
{ | |||||
local file | |||||
# If it's the first time around, fiddle with things and move the | |||||
# current configuration to the chroot. | |||||
if [ -d ${_named_confdirroot} -a ! -d ${_named_confdir} ]; then | |||||
warn "named chroot: Moving current configuration in the chroot!" | |||||
install -d ${_named_confdir%/*} | |||||
mv ${_named_confdirroot} ${_named_confdir} | |||||
fi | |||||
# Create (or update) the chroot directory structure | |||||
# | |||||
if [ -r %%PREFIX%%/etc/mtree/BIND.chroot.dist ]; then | |||||
mtree -deU -f %%PREFIX%%/etc/mtree/BIND.chroot.dist \ | |||||
-p ${named_chrootdir} | |||||
else | |||||
warn "%%PREFIX%%/etc/mtree/BIND.chroot.dist missing," | |||||
warn "${named_chrootdir} directory structure not updated" | |||||
fi | |||||
if [ -r %%PREFIX%%/etc/mtree/BIND.chroot.local.dist ]; then | |||||
mkdir -p ${named_chrootdir}%%PREFIX%% | |||||
mtree -deU -f %%PREFIX%%/etc/mtree/BIND.chroot.local.dist \ | |||||
-p ${named_chrootdir}%%PREFIX%% | |||||
else | |||||
warn "%%PREFIX%%/etc/mtree/BIND.chroot.local.dist missing," | |||||
warn "${named_chrootdir}%%PREFIX%% directory structure not updated" | |||||
fi | |||||
# Create (or update) the configuration directory symlink | |||||
# | |||||
if [ ! -L "${_named_confdirroot}" ]; then | |||||
if [ -d "${_named_confdirroot}" ]; then | |||||
warn "named chroot: ${_named_confdirroot} is a directory!" | |||||
elif [ -e "${_named_confdirroot}" ]; then | |||||
warn "named chroot: ${_named_confdirroot} exists!" | |||||
else | |||||
ln -s ${_named_confdir} ${_named_confdirroot} | |||||
fi | |||||
else | |||||
# Make sure it points to the right place. | |||||
ln -shf ${_named_confdir} ${_named_confdirroot} | |||||
fi | |||||
# Mount a devfs in the chroot directory if needed | |||||
# | |||||
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then | |||||
umount ${named_chrootdir}/dev 2>/dev/null | |||||
devfs_domount ${named_chrootdir}/dev devfsrules_hide_all | |||||
devfs -m ${named_chrootdir}/dev rule apply path null unhide | |||||
devfs -m ${named_chrootdir}/dev rule apply path random unhide | |||||
else | |||||
if [ -c ${named_chrootdir}/dev/null -a \ | |||||
-c ${named_chrootdir}/dev/random ]; then | |||||
info "named chroot: using pre-mounted devfs." | |||||
else | |||||
err 1 "named chroot: devfs cannot be mounted from" \ | |||||
"within a jail. Thus a chrooted named cannot" \ | |||||
"be run from within a jail." \ | |||||
"To run named without chrooting it, set" \ | |||||
"named_chrootdir=\"\" in /etc/rc.conf." | |||||
fi | |||||
fi | |||||
# If OpenSSL from ports, then the engines should be present in the | |||||
# chroot, named loads them after chrooting. | |||||
if [ -d ${_openssl_engines} ]; then | |||||
# FIXME when 8.4 see if security.jail.param.allow.mount.nullfs can be used. | |||||
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 -o `${SYSCTL_N} security.jail.mount_allowed` -eq 1 ]; then | |||||
mkdir -p ${named_chrootdir}${_openssl_engines} | |||||
mount -t nullfs ${_openssl_engines} ${named_chrootdir}${_openssl_engines} | |||||
else | |||||
warn "named chroot: cannot nullfs mount OpenSSL" \ | |||||
"engines into the chroot, will copy the shared" \ | |||||
"libraries instead." | |||||
mkdir -p ${named_chrootdir}${_openssl_engines} | |||||
cp -f ${_openssl_engines}/*.so ${named_chrootdir}${_openssl_engines} | |||||
fi | |||||
fi | |||||
# Copy and/or update key files to the chroot /etc | |||||
# | |||||
for file in localtime protocols services; do | |||||
if [ -r /etc/${file} ] && \ | |||||
! cmp -s /etc/${file} "${named_chrootdir}/etc/${file}"; then | |||||
cp -p /etc/${file} "${named_chrootdir}/etc/${file}" | |||||
fi | |||||
done | |||||
} | |||||
# Make symlinks to the correct pid file | |||||
# | |||||
make_symlinks() | |||||
{ | |||||
checkyesno named_symlink_enable && | |||||
ln -fs "${named_chrootdir}${pidfile}" ${pidfile} | |||||
} | |||||
named_poststart() | named_poststart() | ||||
{ | { | ||||
make_symlinks | |||||
if checkyesno named_wait; then | if checkyesno named_wait; then | ||||
until ${command%/sbin/named}/bin/host $named_wait_host >/dev/null 2>&1; do | until ${_named_program_root}/bin/host ${named_wait_host} >/dev/null 2>&1; do | ||||
echo " Waiting for nameserver to resolve $named_wait_host" | echo " Waiting for nameserver to resolve ${named_wait_host}" | ||||
sleep 1 | sleep 1 | ||||
done | done | ||||
fi | fi | ||||
} | } | ||||
named_reload() | named_reload() | ||||
{ | { | ||||
# This is a one line function, but ${command}!is not defined early | # This is a one line function, but ${named_program}!is not defined early | ||||
# enough to be there when the reload_cmd variable is defined up there. | # enough to be there when the reload_cmd variable is defined up there. | ||||
${command%/named}/rndc reload | ${_named_program_root}/sbin/rndc reload | ||||
} | } | ||||
find_pidfile() | find_pidfile() | ||||
{ | { | ||||
if get_pidfile_from_conf pid-file $named_conf; then | if get_pidfile_from_conf pid-file ${named_conf}; then | ||||
pidfile="$_pidfile_from_conf" | pidfile="${_pidfile_from_conf}" | ||||
else | else | ||||
pidfile="/var/run/named/pid" | pidfile="/var/run/named/pid" | ||||
fi | fi | ||||
} | } | ||||
named_stop() | named_stop() | ||||
{ | { | ||||
find_pidfile | find_pidfile | ||||
# This duplicates an undesirably large amount of code from the stop | # This duplicates an undesirably large amount of code from the stop | ||||
# routine in rc.subr in order to use rndc to shut down the process, | # routine in rc.subr in order to use rndc to shut down the process, | ||||
# and to give it a second chance in case rndc fails. | # and to give it a second chance in case rndc fails. | ||||
rc_pid=$(check_pidfile $pidfile $command) | rc_pid=$(check_pidfile ${pidfile} ${command}) | ||||
if [ -z "$rc_pid" ]; then | if [ -z "${rc_pid}" ]; then | ||||
[ -n "$rc_fast" ] && return 0 | [ -n "${rc_fast}" ] && return 0 | ||||
_run_rc_notrunning | _run_rc_notrunning | ||||
return 1 | return 1 | ||||
fi | fi | ||||
echo 'Stopping named.' | echo 'Stopping named.' | ||||
if ${command%/named}/rndc stop 2>/dev/null; then | if ${_named_program_root}/sbin/rndc stop 2>/dev/null; then | ||||
wait_for_pids $rc_pid | wait_for_pids ${rc_pid} | ||||
else | else | ||||
echo -n 'rndc failed, trying kill: ' | echo -n 'rndc failed, trying kill: ' | ||||
kill -TERM $rc_pid | kill -TERM ${rc_pid} | ||||
wait_for_pids $rc_pid | wait_for_pids ${rc_pid} | ||||
fi | fi | ||||
} | } | ||||
named_poststop() | |||||
{ | |||||
if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then | |||||
# unmount OpenSSL engines, if they were not mounted but only | |||||
# copied, do nothing. | |||||
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 -o `${SYSCTL_N} security.jail.mount_allowed` -eq 1 ]; then | |||||
umount ${named_chrootdir}${_openssl_engines} | |||||
fi | |||||
# unmount /dev | |||||
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then | |||||
umount ${named_chrootdir}/dev 2>/dev/null || true | |||||
else | |||||
warn "named chroot:" \ | |||||
"cannot unmount devfs from inside jail!" | |||||
fi | |||||
fi | |||||
} | |||||
create_file() | create_file() | ||||
{ | { | ||||
if [ -e "$1" ]; then | if [ -e "$1" ]; then | ||||
unlink $1 | unlink $1 | ||||
fi | fi | ||||
install -o root -g wheel -m 0644 /dev/null $1 | install -o root -g wheel -m 0644 /dev/null $1 | ||||
} | } | ||||
named_prestart() | named_prestart() | ||||
{ | { | ||||
find_pidfile | find_pidfile | ||||
if [ -n "$named_pidfile" ]; then | if [ -n "${named_pidfile}" ]; then | ||||
warn 'named_pidfile: now determined from the conf file' | warn 'named_pidfile: now determined from the conf file' | ||||
fi | fi | ||||
piddir=`/usr/bin/dirname ${pidfile}` | piddir=`/usr/bin/dirname ${pidfile}` | ||||
if [ ! -d ${piddir} ]; then | if [ ! -d ${piddir} ]; then | ||||
install -d -o ${named_uid} -g ${named_uid} ${piddir} | install -d -o ${named_uid} -g ${named_uid} ${piddir} | ||||
fi | fi | ||||
command_args="-u ${named_uid:=root} -c $named_conf $command_args" | command_args="-u ${named_uid:=root} -c ${named_conf} ${command_args}" | ||||
local line nsip firstns | local line nsip firstns | ||||
# Is the user using a sandbox? | |||||
# | |||||
if [ -n "${named_chrootdir}" ]; then | |||||
rc_flags="${rc_flags} -t ${named_chrootdir}" | |||||
checkyesno named_chroot_autoupdate && chroot_autoupdate | |||||
else | |||||
named_symlink_enable=NO | |||||
fi | |||||
# Create an rndc.key file for the user if none exists | # Create an rndc.key file for the user if none exists | ||||
# | # | ||||
confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \ | confgen_command="${_named_program_root}/sbin/rndc-confgen -a -b256 -u ${named_uid} \ | ||||
-c ${named_confdir}/rndc.key" | -c ${_named_confdir}/rndc.key" | ||||
if [ -s "${named_confdir}/rndc.conf" ]; then | if [ -s "${_named_confdir}/rndc.conf" ]; then | ||||
unset confgen_command | unset confgen_command | ||||
fi | fi | ||||
if [ -s "${named_confdir}/rndc.key" ]; then | if [ -s "${_named_confdir}/rndc.key" ]; then | ||||
case `stat -f%Su ${named_confdir}/rndc.key` in | case `stat -f%Su ${_named_confdir}/rndc.key` in | ||||
root|$named_uid) ;; | root|${named_uid}) ;; | ||||
*) $confgen_command ;; | *) ${confgen_command} ;; | ||||
esac | esac | ||||
else | else | ||||
$confgen_command | ${confgen_command} | ||||
fi | fi | ||||
local checkconf | local checkconf | ||||
checkconf="${command%/named}/named-checkconf" | checkconf="${_named_program_root}/sbin/named-checkconf" | ||||
if ! checkyesno named_chroot_autoupdate && [ -n "${named_chrootdir}" ]; then | |||||
checkconf="${checkconf} -t ${named_chrootdir}" | |||||
fi | |||||
# Create a forwarder configuration based on /etc/resolv.conf | # Create a forwarder configuration based on /etc/resolv.conf | ||||
if checkyesno named_auto_forward; then | if checkyesno named_auto_forward; then | ||||
if [ ! -s /etc/resolv.conf ]; then | if [ ! -s /etc/resolv.conf ]; then | ||||
warn "named_auto_forward enabled, but no /etc/resolv.conf" | warn "named_auto_forward enabled, but no /etc/resolv.conf" | ||||
# Empty the file in case it is included in named.conf | # Empty the file in case it is included in named.conf | ||||
[ -s "${named_confdir}/auto_forward.conf" ] && | [ -s "${_named_confdir}/auto_forward.conf" ] && | ||||
create_file ${named_confdir}/auto_forward.conf | create_file ${_named_confdir}/auto_forward.conf | ||||
$checkconf $named_conf || | ${checkconf} ${named_conf} || | ||||
err 3 'named-checkconf for $named_conf failed' | err 3 'named-checkconf for ${named_conf} failed' | ||||
return | return | ||||
fi | fi | ||||
create_file /var/run/naf-resolv.conf | create_file /var/run/naf-resolv.conf | ||||
create_file /var/run/auto_forward.conf | create_file /var/run/auto_forward.conf | ||||
echo ' forwarders {' > /var/run/auto_forward.conf | echo ' forwarders {' > /var/run/auto_forward.conf | ||||
while read line; do | while read line; do | ||||
case "$line" in | case "${line}" in | ||||
'nameserver '*|'nameserver '*) | 'nameserver '*|'nameserver '*) | ||||
nsip=${line##nameserver[ ]} | nsip=${line##nameserver[ ]} | ||||
if [ -z "$firstns" ]; then | if [ -z "${firstns}" ]; then | ||||
if [ ! "$nsip" = '127.0.0.1' ]; then | if [ ! "${nsip}" = '127.0.0.1' ]; then | ||||
echo 'nameserver 127.0.0.1' | echo 'nameserver 127.0.0.1' | ||||
echo " ${nsip};" >> /var/run/auto_forward.conf | echo " ${nsip};" >> /var/run/auto_forward.conf | ||||
fi | fi | ||||
firstns=1 | firstns=1 | ||||
else | else | ||||
[ "$nsip" = '127.0.0.1' ] && continue | [ "${nsip}" = '127.0.0.1' ] && continue | ||||
echo " ${nsip};" >> /var/run/auto_forward.conf | echo " ${nsip};" >> /var/run/auto_forward.conf | ||||
fi | fi | ||||
;; | ;; | ||||
esac | esac | ||||
echo $line | echo ${line} | ||||
done < /etc/resolv.conf > /var/run/naf-resolv.conf | done < /etc/resolv.conf > /var/run/naf-resolv.conf | ||||
echo ' };' >> /var/run/auto_forward.conf | echo ' };' >> /var/run/auto_forward.conf | ||||
echo '' >> /var/run/auto_forward.conf | echo '' >> /var/run/auto_forward.conf | ||||
if checkyesno named_auto_forward_only; then | if checkyesno named_auto_forward_only; then | ||||
echo " forward only;" >> /var/run/auto_forward.conf | echo " forward only;" >> /var/run/auto_forward.conf | ||||
else | else | ||||
echo " forward first;" >> /var/run/auto_forward.conf | echo " forward first;" >> /var/run/auto_forward.conf | ||||
fi | fi | ||||
if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then | if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then | ||||
unlink /var/run/naf-resolv.conf | unlink /var/run/naf-resolv.conf | ||||
else | else | ||||
[ -e /etc/resolv.conf ] && unlink /etc/resolv.conf | [ -e /etc/resolv.conf ] && unlink /etc/resolv.conf | ||||
mv /var/run/naf-resolv.conf /etc/resolv.conf | mv /var/run/naf-resolv.conf /etc/resolv.conf | ||||
fi | fi | ||||
if cmp -s ${named_confdir}/auto_forward.conf \ | if cmp -s ${_named_confdir}/auto_forward.conf \ | ||||
/var/run/auto_forward.conf; then | /var/run/auto_forward.conf; then | ||||
unlink /var/run/auto_forward.conf | unlink /var/run/auto_forward.conf | ||||
else | else | ||||
[ -e "${named_confdir}/auto_forward.conf" ] && | [ -e "${_named_confdir}/auto_forward.conf" ] && | ||||
unlink ${named_confdir}/auto_forward.conf | unlink ${_named_confdir}/auto_forward.conf | ||||
mv /var/run/auto_forward.conf \ | mv /var/run/auto_forward.conf \ | ||||
${named_confdir}/auto_forward.conf | ${_named_confdir}/auto_forward.conf | ||||
fi | fi | ||||
else | else | ||||
# Empty the file in case it is included in named.conf | # Empty the file in case it is included in named.conf | ||||
[ -s "${named_confdir}/auto_forward.conf" ] && | [ -s "${_named_confdir}/auto_forward.conf" ] && | ||||
create_file ${named_confdir}/auto_forward.conf | create_file ${_named_confdir}/auto_forward.conf | ||||
fi | fi | ||||
$checkconf $named_conf || err 3 'named-checkconf for $named_conf failed' | ${checkconf} ${named_conf} || err 3 "named-checkconf for ${named_conf} failed" | ||||
} | } | ||||
run_rc_command "$1" | run_rc_command "$1" |