Attached an updated patch for IPv6 server support. This cleans up the unnecessary translations that were in my previous patch, fixes some bugs (thanks to C.J. Adams-Collier for one bug fix), and I've rebased against the latest head.
Feedback still sought on the folowing points: * the convention around "true" vs "yes" for values in /etc/default is not clear to me; it seems debconf always goes with true/false for a boolean, but many other scripts in /etc/default seem to use "yes". I just used "true". * Three new debconf values are added, with accompanying documentation; this impacts the translations but I don't see any way around it given the nature of the changes. Any feedback or suggestions welcome. Thanks, Steve
diff --git a/debian/dhcpd6.conf b/debian/dhcpd6.conf new file mode 100644 index 0000000..551a80c --- /dev/null +++ b/debian/dhcpd6.conf @@ -0,0 +1,106 @@ +# +# Sample configuration file for ISC dhcpdv6 for Debian +# +# + +# IPv6 address valid lifetime +# (at the end the address is no longer usable by the client) +# (set to 30 days, the usual IPv6 default) +default-lease-time 2592000; + +# IPv6 address preferred lifetime +# (at the end the address is deprecated, i.e., the client should use +# other addresses for new connections) +# (set to 7 days, the usual IPv6 default) +preferred-lifetime 604800; + +# T1, the delay before Renew +# (default is 1/2 preferred lifetime) +# (set to 1 hour) +option dhcp-renewal-time 3600; + +# T2, the delay before Rebind (if Renews failed) +# (default is 3/4 preferred lifetime) +# (set to 2 hours) +option dhcp-rebinding-time 7200; + +# Enable RFC 5007 support (same than for DHCPv4) +allow leasequery; + +# Global definitions for name server address(es) and domain search list +#option dhcp6.name-servers 3ffe:501:ffff:100:200:ff:fe00:3f3e; +#option dhcp6.domain-search "test.example.com","example.com"; + +# Set preference to 255 (maximum) in order to avoid waiting for +# additional servers when there is only one +##option dhcp6.preference 255; + +# Server side command to enable rapid-commit (2 packet exchange) +##option dhcp6.rapid-commit; + +# The delay before information-request refresh +# (minimum is 10 minutes, maximum one day, default is to not refresh) +# (set to 6 hours) +option dhcp6.info-refresh-time 21600; + +# The path of the lease file +#dhcpv6-lease-file-name "/var/lib/dhcp/dhcpd6.leases"; + +# Static definition (must be global) +#host myclient { +# # The entry is looked up by this +# host-identifier option +# dhcp6.client-id 00:01:00:01:00:04:93:e0:00:00:00:00:a2:a2; + +# # A fixed address +# fixed-address6 3ffe:501:ffff:100::1234; + +# # A fixed prefix +# fixed-prefix6 3ffe:501:ffff:101::/64; + +# # Override of the global definitions, +# # works only when a resource (address or prefix) is assigned +# option dhcp6.name-servers 3ffe:501:ffff:100:200:ff:fe00:4f4e; + +# # For debug (to see when the entry statements are executed) +# # (log "sol" when a matching Solicitation is received) +# ##if packet(0,1) = 1 { log(debug,"sol"); } +#} + +#host otherclient { +# # This host entry is hopefully matched if the client supplies a DUID-LL +# # or DUID-LLT containing this MAC address. +# hardware ethernet 01:00:80:a2:55:67; +# +# fixed-address6 3ffe:501:ffff:100::4321; +#} + +# The subnet where the server is attached +# (i.e., the server has an address in this subnet) +#subnet6 3ffe:501:ffff:100::/64 { +# # Two addresses available to clients +# # (the third client should get NoAddrsAvail) +# range6 3ffe:501:ffff:100::10 3ffe:501:ffff:100::11; +# +# # Use the whole /64 prefix for temporary addresses +# # (i.e., direct application of RFC 4941) +# range6 3ffe:501:ffff:100:: temporary; +# +# # Some /64 prefixes available for Prefix Delegation (RFC 3633) +# prefix6 3ffe:501:ffff:100:: 3ffe:501:ffff:111:: /64; +#} + +# A second subnet behind a relay agent +#subnet6 3ffe:501:ffff:101::/64 { +# range6 3ffe:501:ffff:101::10 3ffe:501:ffff:101::11; +# +# # Override of the global definitions, +# # works only when a resource (address or prefix) is assigned +# option dhcp6.name-servers 3ffe:501:ffff:101:200:ff:fe00:3f3e; +# +#} + +# A third subnet behind a relay agent chain +#subnet6 3ffe:501:ffff:102::/64 { +# range6 3ffe:501:ffff:102::10 3ffe:501:ffff:102::11; +#} diff --git a/debian/isc-dhcp-server.config b/debian/isc-dhcp-server.config index 412c4b3..9bb7894 100644 --- a/debian/isc-dhcp-server.config +++ b/debian/isc-dhcp-server.config @@ -13,12 +13,18 @@ INITCONFFILE=/etc/default/isc-dhcp-server # preserve the configuration. if [ -r ${INITCONFFILE} ]; then . ${INITCONFFILE} + db_set isc-dhcp-server/v4_enabled "${V4_ENABLED:-true}" + db_set isc-dhcp-server/v6_enabled "${V6_ENABLED:-false}" db_set isc-dhcp-server/interfaces "${INTERFACES}" + db_set isc-dhcp-server/interfaces_v6 "${INTERFACES_V6}" fi db_title "DHCP Server" +db_input low isc-dhcp-server/v4_enabled || true +db_input low isc-dhcp-server/v6_enabled || true db_input low isc-dhcp-server/interfaces || true +db_input low isc-dhcp-server/interfaces_v6 || true db_go db_input high isc-dhcp-server/new_auth_behavior || true diff --git a/debian/isc-dhcp-server.init.d b/debian/isc-dhcp-server.init.d index 10e4679..48665fc 100644 --- a/debian/isc-dhcp-server.init.d +++ b/debian/isc-dhcp-server.init.d @@ -35,7 +35,7 @@ fi [ -f "$DHCPD_DEFAULT" ] && . "$DHCPD_DEFAULT" NAME=dhcpd -DESC="ISC DHCP server" +DESC="ISC DHCPv4 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 @@ -44,58 +44,118 @@ if [ -z "$DHCPD_PID" ]; then fi DHCPD_PID="${DHCPD_PID:-/var/run/dhcpd.pid}" +NAME6=dhcpd6 +DESC6="ISC DHCPv6 server" +# fallback to default config file +DHCPD6_CONF=${DHCPD6_CONF:-/etc/dhcp/dhcpd6.conf} +# try to read pid file name from config file, with fallback to /var/run/dhcpd6.pid +if [ -z "$DHCPD6_PID" ]; then + DHCPD6_PID=$(sed -n -e 's/^[ \t]*pid-file-name[ \t]*"(.*)"[ \t]*;.*$/\1/p' < "$DHCPD6_CONF" 2>/dev/null | head -n 1) +fi +DHCPD6_PID="${DHCPD6_PID:-/var/run/dhcpd6.pid}" + +# $1 version -4 or -6 +# $2 config file 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." + if ! /usr/sbin/dhcpd $1 -t $OPTIONS -q -cf "$2" > /dev/null 2>&1; then + echo "dhcpd self-test failed. Please fix $2." echo "The error was: " - /usr/sbin/dhcpd -t $OPTIONS -cf "$DHCPD_CONF" + /usr/sbin/dhcpd $1 -t $OPTIONS -cf "$2" exit 1 fi touch /var/lib/dhcp/dhcpd.leases } -# single arg is -v for messages, -q for none +test_configs() +{ + if [ "$V4_ENABLED" = "true" ]; then + test_config -4 "$DHCPD_CONF" + fi + if [ "$V6_ENABLED" = "true" ]; then + test_config -6 "$DHCPD6_CONF" + fi +} + +# $1 is -v for messages, -q for none +# $2 PID file path +# $3 NAME check_status() { - if [ ! -r "$DHCPD_PID" ]; then - test "$1" != -v || echo "$NAME is not running." + if [ ! -r "$2" ]; then + test "$1" != -v || echo "$3 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." + if read pid < "$2" && ps -p "$pid" > /dev/null 2>&1; then + test "$1" != -v || echo "$3 is running." return 0 else - test "$1" != -v || echo "$NAME is not running but $DHCPD_PID exists." + test "$1" != -v || echo "$3 is not running but $2 exists." return 1 fi } +start_daemon() +{ + local VERSION CONF_FILE PROCESS PIDFILE INTERFACES DESCRIPTION + VERSION=$1 + CONF_FILE=$2 + PROCESS=$3 + PIDFILE=$4 + INTERFACES=$5 + DESCRIPTION=$6 + + log_daemon_msg "Starting $DESCRIPTION" "$PROCESS" + start-stop-daemon --start --quiet --pidfile "$PIDFILE" \ + --exec /usr/sbin/dhcpd -- \ + $VERSION -q $OPTIONS -cf "$CONF_FILE" -pf "$PIDFILE" $INTERFACES + sleep 2 + + if check_status -q $PIDFILE $NAME; then + log_end_msg 0 + else + log_failure_msg "check syslog for diagnostics." + log_end_msg 1 + exit 1 + fi +} + +stop_daemon() +{ + local PROCESS PIDFILE DESCRIPTION + PROCESS=$1 + PIDFILE=$2 + DESCRIPTION=$3 + + log_daemon_msg "Stopping $DESCRIPTION" "$PROCESS" + start-stop-daemon --stop --quiet --pidfile "$PIDFILE" + log_end_msg $? + rm -f "$PIDFILE" +} + 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 + test_configs + if [ "$V4_ENABLED" = "true" ]; then + start_daemon "-4" "$DHCPD_CONF" \ + "$NAME" "$DHCPD_PID" "$INTERFACES" "$DESC" + fi - if check_status -q; then - log_end_msg 0 - else - log_failure_msg "check syslog for diagnostics." - log_end_msg 1 - exit 1 + if [ "$V6_ENABLED" = "true" ]; then + start_daemon "-6" "$DHCPD6_CONF" \ + "$NAME6" "$DHCPD6_PID" "$INTERFACES_V6" "$DESC6" fi ;; stop) - log_daemon_msg "Stopping $DESC" "$NAME" - start-stop-daemon --stop --quiet --pidfile "$DHCPD_PID" - log_end_msg $? - rm -f "$DHCPD_PID" + if [ -f "$DHCPD_PID" ]; then + stop_daemon "$NAME" "$DHCPD_PID" "$DESC" + fi + if [ -f "$DHCPD6_PID" ]; then + stop_daemon "$NAME6" "$DHCPD6_PID" "$DESC6" + fi ;; restart | force-reload) - test_config + test_configs $0 stop sleep 2 $0 start @@ -105,7 +165,9 @@ case "$1" in ;; status) echo -n "Status of $DESC: " - check_status -v + check_status -v "$DHCPD_PID" "$NAME" + echo -n "Status of $DESC6: " + check_status -v "$DHCPD6_PID" "$NAME6" exit "$?" ;; *) diff --git a/debian/isc-dhcp-server.install b/debian/isc-dhcp-server.install index b5b95f0..96ebc7b 100644 --- a/debian/isc-dhcp-server.install +++ b/debian/isc-dhcp-server.install @@ -1,3 +1,4 @@ usr/sbin/dhcpd debian/dhcpd.conf etc/dhcp +debian/dhcpd6.conf etc/dhcp diff --git a/debian/isc-dhcp-server.postinst b/debian/isc-dhcp-server.postinst index ab0b984..ba550f6 100644 --- a/debian/isc-dhcp-server.postinst +++ b/debian/isc-dhcp-server.postinst @@ -42,34 +42,69 @@ umask 022 # This is a POSIX shell fragment # +# you can enable v4 and/or v6 protocols +V4_ENABLED="true" +V6_ENABLED="false" + # Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). #DHCPD_CONF=/etc/dhcp/dhcpd.conf +# Path to dhcpdv6's config file (default: /etc/dhcp/dhcpd6.conf). +#DHCPD6_CONF=/etc/dhcp/dhcpd6.conf + # Path to dhcpd's PID file (default: /var/run/dhcpd.pid). #DHCPD_PID=/var/run/dhcpd.pid +# Path to dhcpdv6's PID file (default: /var/run/dhcpd6.pid). +#DHCPD6_PID=/var/run/dhcpd6.pid + # Additional options to start dhcpd with. -# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +# Don't use options -cf or -pf here; +# use DHCPD_CONF/ DHCPD_PID, DHCPD6_CONF/ DHCPD6_PID instead #OPTIONS="" # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACES="" +INTERFACES_V6="" EOFMAGICNUMBER1234 } +set_default() { + local VARIABLE VALUE TMPFILE + VARIABLE=$1 + VALUE=$2 + + if grep -q "^[[:space:]]*${VARIABLE}=" ${INITCONFFILE}; then + TMPFILE="$(mktemp -q ${INITCONFFILE}.new.XXXXXX)" + sed -e "s,^[[:space:]]*${VARIABLE}=.*,${VARIABLE}=\"${VALUE}\"," \ + <${INITCONFFILE} >${TMPFILE} + + cp ${TMPFILE} ${INITCONFFILE} + rm ${TMPFILE} + else + echo >> ${INITCONFFILE} + echo "${VARIABLE}=\"${VALUE}\"" >> ${INITCONFFILE} + fi +} + # ------------------------- Debconf questions start --------------------- +db_get isc-dhcp-server/v4_enabled || true +V4_ENABLED="${RET}" +set_default V4_ENABLED "${V4_ENABLED}" + +db_get isc-dhcp-server/v6_enabled || true +V6_ENABLED="${RET}" +set_default V6_ENABLED "${V6_ENABLED}" + db_get isc-dhcp-server/interfaces || true INTERFACES="${RET}" +set_default INTERFACES "${INTERFACES}" -if [ -n "$INTERFACES" ]; then - TMPFILE="$(mktemp -q ${INITCONFFILE}.new.XXXXXX)" - sed -e "s,^[[:space:]]*INTERFACES[[:space:]]*=.*,INTERFACES=\"${INTERFACES}\"," \ - <${INITCONFFILE} >${TMPFILE} - cp ${TMPFILE} ${INITCONFFILE} - rm ${TMPFILE} -fi +db_get isc-dhcp-server/interfaces_v6 || true +INTERFACES_V6="${RET}" +set_default INTERFACES_V6 "${INTERFACES_V6}" # ------------------------- Debconf questions end --------------------- db_stop diff --git a/debian/isc-dhcp-server.templates b/debian/isc-dhcp-server.templates index 5d24b58..b7273ab 100644 --- a/debian/isc-dhcp-server.templates +++ b/debian/isc-dhcp-server.templates @@ -7,12 +7,32 @@ # Even minor modifications require translation updates and such # changes should be coordinated with translators and reviewers. +Template: isc-dhcp-server/v4_enabled +Type: boolean +_Description: Should DHCP server listen on IPv4?: + Please enable or disable serving requests for IPv4 addresses. + +Template: isc-dhcp-server/v6_enabled +Type: boolean +_Description: Should DHCP server listen on IPv6?: + Please enable or disable serving requests for IPv6 addresses. + Template: isc-dhcp-server/interfaces Type: string -_Description: Network interfaces on which the DHCP server should listen: - Please specify on which network interface(s) the DHCP server should - listen for DHCP requests. Multiple interface names should be entered - as a space-separated list. +_Description: Network interfaces on which the DHCPv4 server should listen: + Please specify on which network interface(s) the DHCP server + should listen for DHCPv4 requests. Multiple interface names should be + entered as a space-separated list. + . + The interfaces will be automatically detected if this field is left + blank. + +Template: isc-dhcp-server/interfaces_v6 +Type: string +_Description: Network interfaces on which the DHCPv6 server should listen: + Please specify on which network interface(s) the DHCP server + should listen for DHCPv6 requests. Multiple interface names should be + entered as a space-separated list. . The interfaces will be automatically detected if this field is left blank.