GnuDIP Logo

Your Own Domain Name with External DHCP for Slackware on a Gateway

In this scenario we are running Slackware Linux on an Internet gateway, obtaining its dynamic external IP address using DHCP.

Ideally, choose dynamic DNS services that do not themselves have dynamic IP addresses, and whose name server names are inside there own domains. This will give more efficiency, and some resolver programs will choke on two many levels of indirection, despite what the RFC-s say.

Make sure that the gateway will boot (to the point where there is a login prompt on the gateway console) with the DSL or cable modem unplugged! This means named has to be restarted again right after booting, but makes things much simpler and grief free.

Start a script that uses ISC dhlient in background using "&" after everything is up using /etc/rc.d/rc.local:

# /etc/rc.d/rc.local:  Local system initialization script.
# Put any local setup commands in here:

# set up external interface
echo "Attempting to configure eth1 by contacting a DHCP server..."
/bin/touch /tmp/dhclient_at_boot
/usr/local/dhcp/sbin/dhclient eth1 &> /dev/null 2>&1 &

echo Starting fetchmail daemon ...
/etc/rc.d/rc.fetchmail 2>&1 | /usr/bin/logger -t rc.fetchmail -s &

Provide an exit for dhclient - /etc/dhclient-exit-hooks:


# exit hooks for dhclient-script

# restore resolv.conf* (dhclient-script changes it)
rm /etc/resolv.conf     &> /dev/null
rm /etc/resolv.conf.std &> /dev/null
cp /etc/resolv.conf-localdomain /etc/resolv.conf

# call our setup script when needed
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
   [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
  /etc/rc.d/rc.dhclient_exit 2>&1 | /usr/bin/logger -t rc.dhclient_exit &

The exit for dhclient calls /etc/rc.d/rc.dhclient_exit:


# read old IP address
if [ -r /var/log/dhclient-addresses ]
  read zzz old_ip_address < /var/log/dhclient-addresses

# (re)erect firewall if address changed or boot time
if [ "$old_ip_address" != "$new_ip_address" ] ||
   [ -e /tmp/dhclient_at_boot ]
  # ensure kernel had time to set up interface
  #/usr/bin/sleep 1
  # reset firewall
  /bin/echo \(re\)setting firewall ...

# record old and new IP addresses
/bin/echo -n $old_ip_address $new_ip_address &> /var/log/dhclient-addresses

# say whether or not IP address changed
if [ "$old_ip_address" == "$new_ip_address" ]
  /bin/echo IP address has not changed
  /bin/echo IP address has changed from $old_ip_address to

# configure BIND
/bin/echo mail     IN  CNAME mail.$new_domain_name. >  /etc/bind/services
/bin/echo news     IN  CNAME news.$new_domain_name. >> /etc/bind/services
/bin/echo www      IN  CNAME www.$new_domain_name.  >> /etc/bind/services
/bin/echo "@  IN A" $new_ip_address > /etc/bind/IP-address
/bin/echo zone \"$new_domain_name\" { type forward\; forwarders { > /etc/bind/forward
for nameserver in $new_domain_name_servers
  /bin/echo $nameserver\; >> /etc/bind/forward
/bin/echo }\; }\; >>  /etc/bind/forward
/bin/echo BIND has been configured
# IP address changed?
if [ "$old_ip_address" != "$new_ip_address" ]

  # update address in local dynamic zones
  /bin/echo Updating addresses for dynamic zones to $new_ip_address
  /usr/local/bind/bin/nsupdate -v -k
/usr/local/gnudip/etc/Kgnudip-key.+157+41184.private << EOF
server localhost
update delete    A
update add 60 A $new_ip_address

update delete    A
update add 60 A $new_ip_address



# restart affected daemons if address changed or boot time
if [ "$old_ip_address" != "$new_ip_address" ] ||
   [ -e /tmp/dhclient_at_boot ]

  # restart named
  if /bin/ps -C named &> /dev/null
    /bin/echo Stopping named ...
    /bin/killall named
  /bin/echo Starting named ...

  # (re)start ntpd
  if /bin/ps -C ntpd &> /dev/null
    /bin/echo Stopping ntpd ...
    /bin/killall ntpd
    /bin/echo Calling ntpdate ...
    /usr/local/ntp/bin/ntpdate ddd.ddd.ddd.ddd
  /bin/echo Starting ntpd ...

  # (re)start iplog
  if /bin/ps -C iplog &> /dev/null
    /bin/echo Stopping iplog ...
    /bin/killall iplog
  /bin/echo Starting iplog ...


# no longer boot time
/bin/rm /tmp/dhclient_at_boot &> /dev/null

# update dynamic DNS services?

And /etc/rc.d/rc.dhclient_exit calls /etc/rc.d/rc.dyndns:

# rc.dyndns
# update dynamic DNS services if needed

echo Updating IP address at GnuDIP servers ...
/usr/local/gdipc/bin/ -f /etc/gdipc/gdipc.conf

echo Updating IP address at ...

Some daemons have to be restarted when the address changes, because they are listening on specific IP addresses, and will not automatically listen on the new address (use "netstat -ap | less -S" to see which). This applies to named. Also you may want to supply named with information from DHCP which has to go in named.conf. So named has to be restarted. You could make the zones for your internal machines and dynamic, but you may find it more convenient to be able to edit the files (and use $INCLUDE).