Author Topic: [SOLVED] Configuring DNS updates for all DHCP leases (not just domain members)?  (Read 5649 times)

opensesame

  • Zen Apprentice
  • *
  • Posts: 3
  • Karma: +2/-0
    • View Profile
Context: Zentyal 5.0, with the following roles selected during installation:-
 - Domain Controller and File Sharing
 - DNS Server
 - DHCP Server

I have Zentyal running as a domain controller and I am happy with the configuration with the exception that I would like all hosts obtaining an IP address from the DHCP server to trigger a DNS update.

I should note that I have enabled Dynamic DNS and the 'Dynamic domain' and 'Static domain' settings have been configured.

However, it seems that only hosts that have joined the domain are able to trigger a DNS update. Furthermore, it is the host itself that is updating the DNS entries, rather than the DHCP server.

Example of a failed update (representative of both Windows, Linux, Android, other hosts):
Code: [Select]
Aug  8 16:51:29 dc1 dhcpd[1335]: DHCPACK on 192.168.1.10 to aa:bb:cc:dd:ee:ff via eth0
Aug  8 16:51:29 dc1 named[1474]: samba_dlz: starting transaction on zone internal.example.com
Aug  8 16:51:29 dc1 named[1474]: samba_dlz: spnego update failed
Aug  8 16:51:29 dc1 named[1474]: client 127.0.0.1#31281/key internal.example.com: updating zone 'internal.example.com/NONE': update failed: rejected by secure update (REFUSED)
Aug  8 16:51:29 dc1 named[1474]: samba_dlz: cancelling transaction on zone internal.example.com
Aug  8 16:51:29 dc1 dhcpd[1335]: Unable to add forward map from tst-linux.internal.example.com. to 192.168.1.10: REFUSED

Example of a successful update after the Windows host has joined the domain (note that the DHCP server is still trying to perform updates and these are still failing):
Code: [Select]
Aug  8 18:54:26 dc1 named[1474]: client 127.0.0.1#31281/key internal.example.com: updating zone '1.168.192.in-addr.arpa/IN': deleting rrset at '110.1.168.192.in-addr.arpa' PTR
Aug  8 18:54:26 dc1 named[1474]: client 127.0.0.1#31281/key internal.example.com: updating zone '1.168.192.in-addr.arpa/IN': adding an RR at '110.1.168.192.in-addr.arpa' PTR wintst.internal.example.com.
Aug  8 18:54:26 dc1 dhcpd[1335]: DHCPREQUEST for 192.168.1.110 from 11:22:33:44:55:66 (wintst) via eth0
Aug  8 18:54:26 dc1 dhcpd[1335]: DHCPACK on 192.168.1.110 to 11:22:33:44:55:66 (wintst) via eth0
Aug  8 18:54:26 dc1 dhcpd[1335]: Added reverse map from 110.1.168.192.in-addr.arpa. to wintst.internal.example.com
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: starting transaction on zone internal.example.com
Aug  8 18:54:35 dc1 named[1474]: client 192.168.1.110#59072: update 'internal.example.com/IN' denied
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: cancelling transaction on zone internal.example.com
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: starting transaction on zone internal.example.com
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: allowing update of signer=WINTST\$\@INTERNAL.EXAMPLE.COM name=wintst.internal.example.com tcpaddr= type=AAAA key=892-ms-7.1-608e.11111111-2222-3333-4444-555555555555/160/0
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: allowing update of signer=WINTST\$\@INTERNAL.EXAMPLE.COM name=wintst.internal.example.com tcpaddr= type=A key=892-ms-7.1-608e.11111111-2222-3333-4444-555555555555/160/0
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: allowing update of signer=WINTST\$\@INTERNAL.EXAMPLE.COM name=wintst.internal.example.com tcpaddr= type=A key=892-ms-7.1-608e.11111111-2222-3333-4444-555555555555/160/0
Aug  8 18:54:35 dc1 named[1474]: client 192.168.1.110#57633/key WINTST\$\@INTERNAL.EXAMPLE.COM: updating zone 'internal.example.com/NONE': deleting rrset at 'wintst.internal.example.com' AAAA
Aug  8 18:54:35 dc1 named[1474]: client 192.168.1.110#57633/key WINTST\$\@INTERNAL.EXAMPLE.COM: updating zone 'internal.example.com/NONE': deleting rrset at 'wintst.internal.example.com' A
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: subtracted rdataset wintst.internal.example.com 'wintst.internal.example.com.#0111200#011IN#011A#011192.168.1.110'
Aug  8 18:54:35 dc1 named[1474]: client 192.168.1.110#57633/key WINTST\$\@INTERNAL.EXAMPLE.COM: updating zone 'internal.example.com/NONE': adding an RR at 'wintst.internal.example.com' A 192.168.1.110
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: added rdataset wintst.internal.example.com 'wintst.internal.example.com.#0111200#011IN#011A#011192.168.1.110'
Aug  8 18:54:35 dc1 named[1474]: samba_dlz: committed transaction on zone internal.example.com

Is there a recommended way to have this work with Zentyal?

I have come across the approach described in the following link, which is probably worth investigating further. But I would like to avoid fighting against Zentyal too much if I can avoid it.
https://wiki.samba.org/index.php/Configure_DHCP_to_update_DNS_records_with_BIND9
« Last Edit: August 11, 2017, 07:33:19 am by opensesame »

opensesame

  • Zen Apprentice
  • *
  • Posts: 3
  • Karma: +2/-0
    • View Profile
Re: Configuring DNS updates for all DHCP leases (not just domain members)?
« Reply #1 on: August 11, 2017, 07:32:20 am »
Using the link referenced above I have been able to get this working. I think it should operate without clashing with Zentyal for the most part.

Prepare the user and keytab:
Code: [Select]
$ sudo samba-tool user create dhcpduser --description="Unprivileged user for TSIG-GSSAPI DNS updates via ISC DHCP server" --random-password
$ sudo samba-tool user setexpiry dhcpduser --noexpiry
$ sudo samba-tool group addmembers DnsAdmins dhcpduser

$ sudo samba-tool domain exportkeytab --principal=dhcpduser@INTERNAL.EXAMPLE.COM /etc/dhcp/dhcpduser.keytab
$ sudo chown dhcpd:dhcpd /etc/dhcp/dhcpduser.keytab
$ sudo chmod 400 /etc/dhcp/dhcpduser.keytab

Create the update script:
Code: [Select]
$ sudo mkdir -p /etc/dhcp/bin
$ sudo vi /etc/dhcp/bin/dhcp-dyndns.sh
[REFER TO ATTACHED FILE]
$ sudo chmod 755 /etc/dhcp/bin/dhcp-dyndns.sh

Zentyal recreates configuration files when modules are restarted. To make modifications to these files we need to create a hook script.
This script adds event statements to the dhcpd.conf that will call our update script, as well as AppArmor rules to give the dhcpd process access to everything the update script requires (note: I do not have much experience with AppArmor so these rules are very much just created with a view to just getting things working, and I welcome any suggestions for improvement).
Code: [Select]
$ sudo cp /etc/zentyal/hooks/template.postsetconf /etc/zentyal/hooks/dhcp.postsetconf
$ sudo vi /etc/zentyal/hooks/dhcp.postsetconf
[REFER TO ATTACHED FILE]

Restart the DHCP module from the dashboard.

Forward mapping was working successfully at this point but the adding of reverse map entries was still failing. Example:
Code: [Select]
Aug 10 18:16:51 dc1 named[15482]: client 127.0.0.1#60469/key dhcpduser\@INTERNAL.EXAMPLE.COM: updating zone '1.168.192.in-addr.arpa/IN': update failed: rejected by secure update (REFUSED)
Aug 10 18:16:51 dc1 sh[1307]: update failed: REFUSED
Aug 10 18:16:51 dc1 dhcpd: DHCP-DNS Update failed: 02
Aug 10 18:16:51 dc1 dhcpd[1307]: execute: /etc/dhcp/bin/dhcp-dyndns.sh exit status 512

Add the reverse zone to Samba (it is currently defined in named.conf.local but the named.conf.local.mas file checks if it is in Samba already before adding the definition):
Code: [Select]
$ sudo samba-tool dns zonecreate dc1 1.168.192.in-addr.arpa -k yes

Restart the DNS module from the dashboard.

The dashboard reports that the module restart failed and suggests checking /var/log/zentyal/zentyal.log. However, PTR records are now successfully being created.

From /var/log/zentyal/zentyal.log:
Code: [Select]
2017/08/10 18:20:17 ERROR> RestartService.pm:61 EBox::SysInfo::CGI::RestartService::_process - Restart of DNS from dashboard failed: root command nsupdate -l -t 10 /var/lib/zentyal/tmp/yPKISOiEcj failed.
Error output: update failed: REFUSED

It is failing when trying to create PTR records for the static host entries defined in the DNS section of the web interface (eg. for dc1 itself).

This change is a bit of a hack and is likely to be overwritten by Zentyal at some point.
Code: [Select]
$ sudo cp -a /usr/share/perl5/EBox/DNS.pm /usr/share/perl5/EBox/DNS.pm.orig
$ sudo vi /usr/share/perl5/EBox/DNS.pm
$ diff -u /usr/share/perl5/EBox/DNS.pm.orig /usr/share/perl5/EBox/DNS.pm
--- /usr/share/perl5/EBox/DNS.pm.orig   2017-07-21 21:06:40.000000000 +1000
+++ /usr/share/perl5/EBox/DNS.pm        2017-08-11 14:15:33.022140698 +1000
@@ -1520,7 +1520,7 @@
     my ($self, $fh, $reverse) = @_;

     my $auth = $reverse ? '-l' : '-g';
-    my $cmd = NS_UPDATE_CMD . " $auth -t 10 " . $fh->filename();
+    my $cmd = NS_UPDATE_CMD . " -g -t 10 " . $fh->filename();
     $self->{nsupdateCmds} = [] unless exists $self->{nsupdateCmds};
     push (@{$self->{nsupdateCmds}}, $cmd);
     $fh->unlink_on_destroy(0);

Restarting the DNS module from the dashboard continues to fail, but it works after restarting the server. Reverse lookups for static DNS entries will now work.

TODO: the /var/log/zentyal/zentyal.log file is full of parser warnings from where it encounters the dhcpd event statements while looking for dhcp lease definitions.

halsbox

  • Zen Apprentice
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Thank you so much, opensesame!

Had same problem on fresh install of 5.0.10. Solved it with your instructions except for not creating a new "dhcpduser", but using the already present "dns-{MYDC_HOSTNAME}" user. Also did not have problems with restarting the DNS module from the dashboard (and no errors in log), thus no need to apply DNS.pm patch.

Here is a quick dirty patch for /usr/share/perl5/Text/DHCPLeases/Object.pm to get rid of dhcp leases file parsing warnings in log:
Code: [Select]
--- /usr/share/perl5/Text/DHCPLeases/Object.pm.orig 2012-12-07 22:35:44.000000000 +0400
+++ //usr/share/perl5/Text/DHCPLeases/Object.pm 2017-12-04 03:04:38.702611203 +0300
@@ -156,9 +156,14 @@
 sub parse{
     my ($self, $lines) = @_;
     my %obj;
+    my $event_block = 0;
     for ( @$lines ){
  $_ =~ s/^\s+//o;
  $_ =~ s/\s+$//o;
+ if ($event_block){
+     $event_block = 0 if ( /\}/);
+     next;
+ }
  next if ( /^#|^$|\}$/o );
  if ( /^lease ($IPV4) /o ){
      $obj{type} = 'lease';
@@ -211,13 +216,11 @@
      $obj{'option_agent_remote_id'} = $1;
  }elsif ( /set (\w+) = (.*);/o ){
      $obj{set}{$1} = $2;
- }elsif ( /on (.*) \{(.*)\};/o ){
+ }elsif ( /on\s+(.*)\s+\{/ ){
      my $events     = $1;
      my @events = split /\|/, $events;
-     my $statements = $2;
-     my @statements = split /\n;/, $statements;
      $obj{on}{events}     = @events;
-     $obj{on}{statements} = @statements;
+     $event_block = 1;
  }elsif ( /bootp;/o ){
      $obj{bootp} = 1;
  }elsif ( /reserved;/o ){
@@ -238,6 +241,8 @@
      $obj{ddns_fwd_name} = $1;
  }elsif (/set ddns-txt = \"(.*)\";/o){
      $obj{ddns_txt} = $1;
+ }elsif (/set vendor-class-identifier = \"(.*)\";/){
+            $obj{ddns_txt} = $1;
  }else{
      carp "Text::DHCPLeases::Object::parse Error: Statement not recognized: '$_'\n";
  }

BerT666

  • Zen Warrior
  • ***
  • Posts: 215
  • Karma: +7/-0
    • View Profile
INFO for Zentyal 6.0:

I tested it and it works under 6.0, too ;-)

Regards

Thomas

Neustradamus

  • Zen Monk
  • **
  • Posts: 63
  • Karma: +0/-3
    • View Profile
It is possible to add this directly in the module?

xgonc

  • Zen Apprentice
  • *
  • Posts: 2
  • Karma: +1/-0
    • View Profile
Hi,

I've tested this workaround in Zentyal 6, and it doesn't seem to work. It looks like the user dhcpd doesn't have permissions to run the dhcp-dyndns.sh script:

Code: [Select]
Jan 13 14:42:52 zen dhcpd[29771]: DHCPREQUEST for 192.168.1.106 from 00:0e:08:d4:4f:0d (teles) via enp7s0
Jan 13 14:42:52 zen dhcpd[29771]: DHCPACK on 192.168.1.106 to 00:0e:08:d4:4f:0d (teles) via enp7s0
Jan 13 14:43:02 zen dhcpd[29771]: Commit: IP: 192.168.1.115 DHCID: 1:0:e:8:d4:4f:14 Name: telcv
Jan 13 14:43:02 zen dhcpd[29771]: execute_statement argv[0] = /etc/dhcp/bin/dhcp-dyndns.sh
Jan 13 14:43:02 zen dhcpd[29771]: execute_statement argv[1] = add
Jan 13 14:43:02 zen dhcpd[29771]: execute_statement argv[2] = 192.168.1.115
Jan 13 14:43:02 zen dhcpd[29771]: execute_statement argv[3] = 1:0:e:8:d4:4f:14
Jan 13 14:43:02 zen dhcpd[29771]: execute_statement argv[4] = telcv
Jan 13 14:43:02 zen sh[29771]: /etc/dhcp/bin/dhcp-dyndns.sh: line 108: /usr/bin/awk: Permission denied
Jan 13 14:43:02 zen dhcpd[22977]: 13-01-19 14:43:02 [dyndns] : Running check for valid kerberos ticket
Jan 13 14:43:02 zen dhcpd[22979]: 13-01-19 14:43:02 [dyndns] : Getting new ticket, old one has expired
Jan 13 14:43:02 zen sh[29771]: kinit: krb5_init_creds_set_keytab: Failed to find dhcpduser@IDEIAO.LAN in keytab FILE:/etc/dhcp/dhcpduser.keytab (unknown enctype)
Jan 13 14:43:02 zen dhcpd[22981]: 13-01-19 14:43:02 [dyndns] : dhcpd kinit for dynamic DNS failed
Jan 13 14:43:02 zen dhcpd[29771]: execute: /etc/dhcp/bin/dhcp-dyndns.sh exit status 256

However if I run manually as user dhcpd, the script adds the host correctly, and no error messages are printed:

Code: [Select]
sudo -u dhcpd /etc/dhcp/bin/dhcp-dyndns.sh add 192.168.1.115 1:0:e:8:d4:4f:14 telcv
sudo -u dhcpd kinit -F -k -t /etc/dhcp/dhcpduser.keytab -c /tmp/dhcp-dyndns.cc "dhcpduser@IDEIAO.LAN"

I've tried to whoami to know what user is running the script, but there's no permission also.

Any thoughts?


Thanks

Belfigor

  • Zen Apprentice
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Zentyal 6.0.1 same problem, the way that used in 2nd post dont work at all :(
syslog after all manipulations
Code: [Select]
Feb  9 20:50:32 x-dc1 dhcpd[2254]: DHCPREQUEST for 192.168.1.14 from bc:c3:42:13:e3:1c (KX-TGP600RU) via eth0
Feb  9 20:50:32 x-dc1 dhcpd[2254]: DHCPACK on 192.168.1.14 to bc:c3:42:13:e3:1c (KX-TGP600RU) via eth0
Feb  9 20:50:32 x-dc1 named[1333]: samba_dlz: starting transaction on zone x.lan
Feb  9 20:50:32 x-dc1 named[1333]: samba_dlz: spnego update failed
Feb  9 20:50:32 x-dc1 named[1333]: client @0x7f995800b8b0 127.0.0.1#33377/key x.lan: updating zone 'x.lan/NONE': update failed: rejected by secure update (REFUSED)
Feb  9 20:50:32 x-dc1 named[1333]: samba_dlz: cancelling transaction on zone x.lan
Feb  9 20:50:32 x-dc1 dhcpd[2254]: Unable to add forward map from KX-TGP600RU.x.lan. to 192.168.1.14: REFUSED

Singman

  • Zen Apprentice
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
That topic is not solved anymore and is a real pain.

This is a very basic feature of a system like Zentyal, to register DHCP leases into the DNS. If it's broken, you can't claim to have DNS and DHCP sync'ed.
Tested with 6.0 (not modded):
Code: [Select]
Apr 13 17:31:03 tech01 dhcpd[9630]: DHCPREQUEST for 192.168.0.50 from 3e:d9:4b:7a:08:3b (centreon) via eth0
Apr 13 17:31:03 tech01 dhcpd[9630]: DHCPACK on 192.168.0.50 to 3e:d9:4b:7a:08:3b (centreon) via eth0
Apr 13 17:31:03 tech01 named[9312]: samba_dlz: starting transaction on zone domain.lan
Apr 13 17:31:03 tech01 named[9312]: samba_dlz: spnego update failed
Apr 13 17:31:03 tech01 named[9312]: client @0x7f05e86caa20 127.0.0.1#49095/key domain.lan: updating zone 'domain.lan/NONE': update failed: rejected by secure update (REFUSED)
Apr 13 17:31:03 tech01 named[9312]: samba_dlz: cancelling transaction on zone domain.lan
Apr 13 17:31:03 tech01 dhcpd[9630]: Unable to add forward map from centreon.domain.lan. to 192.168.0.50: REFUSED
Apr 13 17:32:20 tech01 named[9312]: resolver priming query complete

sangamc

  • Zen Monk
  • **
  • Posts: 53
  • Karma: +2/-0
    • View Profile
How do I use the: "dns-{MYDC_HOSTNAME}" properly instead of creating the dhcpd user?


INFO for Zentyal 6.0:

I tested it and it works under 6.0, too ;-)

Regards

Thomas

StreetPiet

  • Zen Apprentice
  • *
  • Posts: 2
  • Karma: +1/-0
    • View Profile

I tried it with Zentyal 6.0 and it works so far. This was my Approach:

Login to your Zentyal Server via SSH.

First create the file "/usr/local/bin/dhcp-dyndns.sh" with

Code: [Select]
sudo nano /usr/local/bin/dhcp-dyndns.sh   
copy, paste (and save) the following script into it:

Code: [Select]
#!/bin/bash

# /usr/local/bin/dhcp-dyndns.sh

# This script is for secure DDNS updates on Samba 4
# Version: 0.8.9

# Use a valid Zentyal Domainuser here, like the DNS Service Account
DOMUSER=dns-dc01
KEYTAB=/etc/dhcpduser.keytab

# Uncomment the next line if using a self compiled Samba and adjust for your PREFIX
#PATH="/usr/local/samba/bin:/usr/local/samba/sbin:$PATH"
BINDIR=$(samba -b | grep 'BINDIR' | grep -v 'SBINDIR' | awk '{print $NF}')
WBINFO="$BINDIR/wbinfo"

# DNS domain
domain=$(hostname -d)
if [ -z ${domain} ]; then
    logger "Cannot obtain domain name, is DNS set up correctly?"
    logger "Cannot continue... Exiting."
    exit 1
fi

# Samba 4 realm
REALM=$(echo ${domain^^})

# Additional nsupdate flags (-g already applied), e.g. "-d" for debug
NSUPDFLAGS="-d"

# krbcc ticket cache
export KRB5CCNAME="/tmp/dhcp-dyndns.cc"

# Kerberos principal
SETPRINCIPAL="${DOMUSER}@${REALM}"
# Kerberos keytab
# /etc/dhcpduser.keytab
# krbcc ticket cache
# /tmp/dhcp-dyndns.cc
TESTUSER="$($WBINFO -u) | grep '${DOMUSER}')"
if [ -z "${TESTUSER}" ]; then
    logger "No AD dhcp user exists, need to create it first.. exiting."
    logger "you can do this by typing the following commands"
    logger "kinit Administrator@${REALM}"
    logger "samba-tool user create dhcpduser --random-password --description=\"Unprivileged user for DNS updates via ISC DHCP server\""
    logger "samba-tool user setexpiry dhcpduser --noexpiry"
    logger "samba-tool group addmembers DnsAdmins dhcpduser"
    exit 1
fi

# Check for Kerberos keytab
if [ ! -f ${KEYTAB} ]; then
    echo "Required keytab ${KEYTAB} not found, it needs to be created."
    echo "Use the following commands as root"
    echo "samba-tool domain exportkeytab --principal=${SETPRINCIPAL} ${KEYTAB}"
    echo "chown XXXX:XXXX ${KEYTAB}"
    echo "Replace 'XXXX:XXXX' with the user & group that dhcpd runs as on your distro"
    echo "chmod 400 ${KEYTAB}"
    exit 1
fi

# Variables supplied by dhcpd.conf
action=$1
ip=$2
DHCID=$3
name=${4%%.*}

usage()
{
echo "USAGE:"
echo "  $(basename $0) add ip-address dhcid|mac-address hostname"
echo "  $(basename $0) delete ip-address dhcid|mac-address"
}

_KERBEROS () {
# get current time as a number
test=$(date +%d'-'%m'-'%y' '%H':'%M':'%S)
# Note: there have been problems with this
# check that 'date' returns something like
# 04-09-15 09:38:14

# Check for valid kerberos ticket
#logger "${test} [dyndns] : Running check for valid kerberos ticket"
klist -c /tmp/dhcp-dyndns.cc -s
if [ "$?" != "0" ]; then
    logger "${test} [dyndns] : Getting new ticket, old one has expired"
    kinit -F -k -t ${KEYTAB} -c /tmp/dhcp-dyndns.cc "${SETPRINCIPAL}"
    if [ "$?" != "0" ]; then
        logger "${test} [dyndns] : dhcpd kinit for dynamic DNS failed"
        exit 1;
    fi
fi

}

# Exit if no ip address or mac-address
if [ -z "${ip}" ] || [ -z "${DHCID}" ]; then
    usage
    exit 1
fi

# Exit if no computer name supplied, unless the action is 'delete'
if [ "${name}" = "" ]; then
    if [ "${action}" = "delete" ]; then
        name=$(host -t PTR "${ip}" | awk '{print $NF}' | awk -F '.' '{print $1}')
    else
        usage
        exit 1;
    fi
fi

# Set PTR address
ptr=$(echo ${ip} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}')

## nsupdate ##
case "${action}" in
add)
    _KERBEROS

nsupdate -g ${NSUPDFLAGS} << UPDATE
server 127.0.0.1
realm ${REALM}
update delete ${name}.${domain} 3600 A
update add ${name}.${domain} 3600 A ${ip}
send
UPDATE
result1=$?

nsupdate -g ${NSUPDFLAGS} << UPDATE
server 127.0.0.1
realm ${REALM}
update delete ${ptr} 3600 PTR
update add ${ptr} 3600 PTR ${name}.${domain}
send
UPDATE
result2=$?
;;
delete)
     _KERBEROS

nsupdate -g ${NSUPDFLAGS} << UPDATE
server 127.0.0.1
realm ${REALM}
update delete ${name}.${domain} 3600 A
send
UPDATE
result1=$?

nsupdate -g ${NSUPDFLAGS} << UPDATE
server 127.0.0.1
realm ${REALM}
update delete ${ptr} 3600 PTR
send
UPDATE
result2=$?
;;
*)
echo "Invalid action specified"
exit 103
;;
esac

result="${result1}${result2}"

if [ "${result}" != "00" ]; then
    logger "DHCP-DNS Update failed: ${result}"
else
    logger "DHCP-DNS Update succeeded"
fi

exit ${result}

Edit the script to your needs and insert a valid domainuser into variable DOMUSER at the top of the script.
To find a suitable domainuser use the following command:

   
Code: [Select]
sudo samba-tool user list | grep dns
this command should give you the username of the Zentyal "DNS Service Account"-User.
In my case the hostname was "dc01" so the DNS-User was "dns-dc01".

save the script and make the script executable:

   
Code: [Select]
sudo chmod a+x /usr/local/bin/dhcp-dyndns.sh
Now we generate the keytab file and change ownership and accessrights.
Fill the placeholders ([yourDomainUser]@[yourDomain]) like: dns-dc01@mydomain.local :

Code: [Select]
sudo samba-tool domain exportkeytab --principal=[yourDomainUser]@[yourDomain] > /etc/dhcpduser.keytab
sudo chown dhcpd:dhcpd /etc/dhcpduser.keytab
sudo chmod 400 /etc/dhcpduser.keytab
   
Ok! So far so good. Now we test the new script:

Log in to your Zentyal Server Webfrontend and look up a ip adress from a dhcp-client that was not properly registered.
Then use the following command on the Zentyal Server SSH Session:

Code: [Select]
sudo /usr/local/bin/dhcp-dyndns.sh add 192.168.1.100 dhcid testhost   
the Output should contain someting like this:

Code: [Select]
Reply from SOA query:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id:   5818
;; flags: qr aa ra; QUESTION: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;testhost.mydomain.tld.           IN      SOA

;; AUTHORITY SECTION:
mydomain.tld.            0       IN      SOA     dc01.mydomain.tld. hostmaster.mydomain.tld. 82 900 600 86400 3600

Found zone name: mydomain.tld
The master is: dc01.mydomain.tld
start_gssrequest
send_gssrequest
Outgoing update query:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:   5813
;; flags:; QUESTION: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;1989803804.sig-dc01.mydomain.tld. ANY   TKEY

if there are errors about the file /tmp/dhcp-dyndns.cc like this one:
   
   klist: krb5_cc_get_principal: Refuses to open cache files not own by myself FILE:/tmp/dhcp-dyndns.cc (owned by 113)
   
simply delete the file and try again. in fact - just run the follwoing command NOW! ;-)

Code: [Select]
sudo rm /tmp/dhcp-dyndns.cc   
Ok! Now we have to modify the dhcpd Configuration. Zentyal builds all of its configuration files from templates,
so i made one with the needed changes. create the following file:

Code: [Select]
sudo nano /usr/share/zentyal/stubs/dhcp/dhcp-dyndns.mas
...and copy/paste the following part:

Code: [Select]
                on commit {
                        set noname = concat("dhcp-", binary-to-ascii(10, 8, "-", leased-address));
                        set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
                        set ClientDHCID = concat (
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
                        );
                        set ClientName = pick-first-value(option host-name, config-option-host-name, client-name, noname);
                        log(concat("Commit: IP: ", ClientIP, " DHCID: ", ClientDHCID, " Name: ", ClientName));
                        execute("/usr/local/bin/dhcp-dyndns.sh", "add", ClientIP, ClientDHCID, ClientName);
                }

                on release {
                        set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
                        set ClientDHCID = concat (
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
                        suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
                        );
                        log(concat("Release: IP: ", ClientIP));
                        execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, ClientDHCID);
                }

                on expiry {
                        set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
                        # cannot get a ClientMac here, apparently this only works when actually receiving a packet
                        log(concat("Expired: IP: ", ClientIP));
                        # cannot get a ClientName here, for some reason that always fails
                        execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "", "0");
                }

save the file.
now open the file /usr/share/zentyal/stubs/dhcp/shared-network.mas:

Code: [Select]
sudo nano /usr/share/zentyal/stubs/dhcp/shared-network.mas
add the line "<& dhcp-dyndns.mas &>" right after the line with "<& subnet.mas" like this:   

Code: [Select]
<%args>
        $iface
        %ifaces
</%args>
shared-network <% $iface %> {
<& includes.mas, iface => $iface &>
<& subnet.mas, info => $ifaces{$iface} &>
<& dhcp-dyndns.mas &>
}

save the file.
Now log into the Zentyal Webfrontend, go to DHCP and toggle the "activated" checkbox twice.
Zentyal will offer you to save the "changes". If you klick the red "Save" Button, Zentyal will
rebuild the /etc/dhcp/dhcpd.conf file. You can check the success if you browse the /etc/dhcp/dhcpd.conf and
search for the same lines we saved in cat /usr/share/zentyal/stubs/dhcp/dhcp-dyndns.mas

Code: [Select]
sudo less /usr/share/zentyal/stubs/dhcp/dhcp-dyndns.masand
Code: [Select]
sudo less /etc/dhcp/dhcpd.conf   
Ok! Finished! You can watch what's going on with

Code: [Select]
sudo tail -f /var/log/syslog   
if you get errors like:
   
   klist: krb5_cc_get_principal: get-principal open(/tmp/dhcp-dyndns.cc): Permission denied

just delete the file:

Code: [Select]
sudo rm /tmp/dhcp-dyndns.cc
Have Fun!

sangamc

  • Zen Monk
  • **
  • Posts: 53
  • Karma: +2/-0
    • View Profile
Thanks for digging into this more! I am starting to see a path to success with most of my servers. On one I get stuck when testing the script and get an error about the finding the users in the keytab file.

Code: [Select]
root@fs10:~# /etc/dhcp/bin/dhcp-dyndns.sh add 10.8.15.3 dhcid testhost
kinit: krb5_init_creds_set_keytab: Failed to find dns-fs10@EXAMPLE.NET in keytab FILE:/etc/dhcpduser.keytab (unknown enctype)

Where am I going wrong on this specific server. The steps worked on two others I tried so I'm stumped.
Thanks again1

StreetPiet

  • Zen Apprentice
  • *
  • Posts: 2
  • Karma: +1/-0
    • View Profile
@sangamc: I had a similar error. In my case i had to correct the file access rights. The error message (unknown enctype) is a bit misleading as it also appears when the user is not allowed to read the file.

On Zentyal it is the "dhcpd" user and the "dhcpd" group. Maybe on your server another user is used?
Also try to generate the dhcpduser.keytab file again, maybe its corrupted?

Code: [Select]
sudo chown [user].[group] /etc/dhcpduser.keytab
sudo chmod 400 /etc/dhcpduser.keytab

« Last Edit: August 29, 2019, 10:23:54 pm by StreetPiet »

sangamc

  • Zen Monk
  • **
  • Posts: 53
  • Karma: +2/-0
    • View Profile
unknown enctype has really sent me on a wild goose chase. It appears a handful of my 40 odd zentyal servers do not like the above steps if they have been upgraded from older versions. (I've had some that upgraded from zentyal2 all the way to v5 over the last 9 or so years).

I think it has something to do with my dns-fs10 user password expiring, but still trying to confirm

The newer deployments that started out as version 5 and a couple v6 are able to get through the steps.

i'l keep digging to find out more.
Thanks!

doncamilo

  • Zen Warrior
  • ***
  • Posts: 206
  • Karma: +41/-0
    • View Profile
 :)

Great! It's one of the most useful threads in this forum!

Thank you!