isc_dhcp_server start error : `dhcpd: Can't create PID file /run/dhcp-server/dhcpd.pid: Permission denied.`
dhcpd: Can't create PID file /run/dhcp-server/dhcpd.pid: Permission denied.
in /var/log/syslog when starting isc_dhcp_server service isc-dhcp-server start
on Ubuntu 15.10 bug report here version of package is 4.3.1-5ubuntu3
Process command is dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf eth0
comming from /etc/init.d/isc-dhcp-server
file
user@host: /$ cat /etc/init.d/isc-dhcp-server
#!/bin/sh
#
#
### BEGIN INIT INFO
# Provides: isc-dhcp-server
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Should-Start: $local_fs slapd $named
# Should-Stop: $local_fs slapd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: DHCP server
# Description: Dynamic Host Configuration Protocol Server
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
test -f /usr/sbin/dhcpd || exit 0
DHCPD_DEFAULT="${DHCPD_DEFAULT:-/etc/default/isc-dhcp-server}"
# It is not safe to start if we don't have a default configuration...
if [ ! -f "$DHCPD_DEFAULT" ]; then
echo "$DHCPD_DEFAULT does not exist! - Aborting..."
if [ "$DHCPD_DEFAULT" = "/etc/default/isc-dhcp-server" ]; then
echo "Run 'dpkg-reconfigure isc-dhcp-server' to fix the problem."
fi
exit 0
fi
. /lib/lsb/init-functions
# Read init script configuration
[ -f "$DHCPD_DEFAULT" ] && . "$DHCPD_DEFAULT"
NAME=dhcpd
DESC="ISC DHCP server"
# fallback to default config file
DHCPD_CONF=${DHCPD_CONF:-/etc/dhcp/dhcpd.conf}
# try to read pid file name from config file, with fallback to /var/run/dhcpd.pid
if [ -z "$DHCPD_PID" ]; then
DHCPD_PID=$(sed -n -e 's/^[ \t]*pid-file-name[ \t]*"(.*)"[ \t]*;.*$/\1/p' < "$DHCPD_CONF" 2>/dev/null | head -n 1)
fi
DHCPD_PID="${DHCPD_PID:-/var/run/dhcpd.pid}"
test_config()
{
if ! /usr/sbin/dhcpd -t $OPTIONS -q -cf "$DHCPD_CONF" > /dev/null 2>&1; then
echo "dhcpd self-test failed. Please fix $DHCPD_CONF."
echo "The error was: "
/usr/sbin/dhcpd -t $OPTIONS -cf "$DHCPD_CONF"
exit 1
fi
touch /var/lib/dhcp/dhcpd.leases
}
# single arg is -v for messages, -q for none
check_status()
{
if [ ! -r "$DHCPD_PID" ]; then
test "$1" != -v || echo "$NAME is not running."
return 3
fi
if read pid < "$DHCPD_PID" && ps -p "$pid" > /dev/null 2>&1; then
test "$1" != -v || echo "$NAME is running."
return 0
else
test "$1" != -v || echo "$NAME is not running but $DHCPD_PID exists."
return 1
fi
}
case "$1" in
start)
test_config
log_daemon_msg "Starting $DESC" "$NAME"
start-stop-daemon --start --quiet --pidfile "$DHCPD_PID" \
--exec /usr/sbin/dhcpd -- \
-q $OPTIONS -cf "$DHCPD_CONF" -pf "$DHCPD_PID" $INTERFACES
sleep 2
if check_status -q; then
log_end_msg 0
else
log_failure_msg "check syslog for diagnostics."
log_end_msg 1
exit 1
fi
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
start-stop-daemon --stop --quiet --pidfile "$DHCPD_PID"
log_end_msg $?
rm -f "$DHCPD_PID"
;;
restart | force-reload)
test_config
$0 stop
sleep 2
$0 start
if [ "$?" != "0" ]; then
exit 1
fi
;;
status)
echo -n "Status of $DESC: "
check_status -v
exit "$?"
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload|status}"
exit 1
esac
exit 0
Solution 1:
I responded in the actual ticket as well, but in 15.10...
It looks like the line in /lib/systemd/system/isc-dhcp-server.service:
exec dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf $CONFIG_FILE $INTERFACES'
is hardcoded and ignores the DHCPD_PID variable from /etc/default/isc-dhcp-server.
I think it should be:
exec dhcpd -user dhcpd -group dhcpd -f -4 -pf $DHCPD_PID -cf $CONFIG_FILE $INTERFACES'
After changing that, you have to run
systemctl daemon-reload
Then you have to set the value in /etc/default/isc-dhcp-server, because if you don't, no default is given and the service fails to start.
DHCPD_PID=/var/run/dhcp-server/dhcpd.pid
Then there are other issues with the file, like it always tries to run:
ExecStartPre=/bin/chown dhcpd:dhcpd /run/dhcp-server
regardless of the specified path. I'm not sure what the intended behavior was, but those two changes solved it for me.
BUT THEN
AppArmor was blocking the file from being written. I'm not very familiar with it, but I added
capability dac_override,
to /etc/apparmor.d/usr.sbin.dhcpd near the other capabilities, restarted the service, and now I have a PID file.
It seems this package has a few issues.
Solution 2:
I had the same issue on Ubuntu Vivid 15.04, without systemd.
audit: type=1400 audit(1453391318.882:44): apparmor="DENIED" operation="capable" profile="/usr/sbin/dhcpd" pid=15957 comm="dhcpd" capability=1 capname="dac_override" audit: type=1400 audit(1453391318.882:45): apparmor="DENIED" operation="capable" profile="/usr/sbin/dhcpd" pid=15957 comm="dhcpd" capability=2 capname="dac_read_search"
I added these two lines to /etc/apparmor.d/usr.sbin.dhcpd
capability dac_override,
capability dac_read_search,
Under the capability setuid,
line.
Then apparmor_parser -r /etc/apparmor.d/usr.sbin.dhcpd
Then stop isc-dhcp-server; start isc-dhcp-server