Main page » DHCP server for Linux AD-DC Ubuntu 18.04. Integration with BIND9

DHCP server for Linux AD-DC Ubuntu 18.04. Integration with BIND9

by Belfigor
19 views
DHCP server for Linux AD-DC Ubuntu 18.04. Integration with BIND9

DHCP server for Linux AD-DC Ubuntu 18.04. Integration with BIND9. The cherry on the cake. It’s great when we have a working Active Directory Domain Controller on Linux, but it’s not enough. Living in a world where in our local DNS zone only IP addresses of devices directly in the domain are automatically updated is not as rosy as it could be. We will try to solve this problem in this article. It is necessary to indicate in advance that our decision will not update the reverse zone (PTR recordings).

All articles in best to study order:

  1. Configuring BIND9 for Linux AD-DC on Ubuntu 18.04 – Part 1

  2. Linux AD-DC on Ubuntu 18.04 – Setting Samba4 – Part 1

  3. Set up BIND9 for Linux AD-DC on Ubuntu 18.04 – Part 2

  4. Linux Samba4 AD-DC on Ubuntu 18.04 – Settings – Part 2

  5. DHCP server for Linux AD-DC Ubuntu 18.04. Integration with BIND9

  6. Domain Controller on Ubuntu 18.04 – Time Synchronization – NTP

  7. Administering the Linux domain controller

 

  1. Ubuntu Domain Controller – Set up DHCP server

    1. To begin with, install a DHCP server
      sudo apt-get install isc-dhcp-server
    2. Then we create a domain user to work with updates
      sudo samba-tool user create dhcpduser --description="Unprivileged user for TSIG-GSSAPI DNS updates via ISC DHCP server" --random-password
    3. We also set a password expiration and add to the group DnsAdmins
      sudo samba-tool user setexpiry dhcpduser --noexpiry
      sudo samba-tool group addmembers DnsAdmins dhcpduser
      AdminGuide.Ru@ag-dc-1:~$ sudo samba-tool user setexpiry dhcpduser --noexpiry
      Expiry for user 'dhcpduser' disabled.
      AdminGuide.Ru@ag-dc-1:~$ sudo samba-tool group addmembers DnsAdmins dhcpduser
      Added members to group DnsAdmins
    4. Now we export the data
      sudo samba-tool domain exportkeytab --principal=dhcpduser@ADMINGUIDE.LAN /etc/dhcpduser.keytab
      sudo chown dhcpd:dhcpd /etc/dhcpduser.keytab
      sudo chmod 400 /etc/dhcpduser.keytab
    5. Creating a script
      sudo nano /usr/local/bin/dhcp-dyndns.sh
      #!/bin/bash
      
      # /usr/local/bin/dhcp-dyndns.sh
      
      # This script is for secure DDNS updates on Samba 4
      # Version: 0.8.9
      
      # 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="dhcpduser@${REALM}"
      # Kerberos keytab
      # /etc/dhcpduser.keytab
      # krbcc ticket cache
      # /tmp/dhcp-dyndns.cc
      TESTUSER="$($WBINFO -u) | grep 'dhcpduser')"
      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 /etc/dhcpduser.keytab ]; then
          echo "Required keytab /etc/dhcpduser.keytab not found, it needs to be created."
          echo "Use the following commands as root"
          echo "samba-tool domain exportkeytab --principal=${SETPRINCIPAL} /etc/dhcpduser.keytab"
          echo "chown XXXX:XXXX /etc/dhcpduser.keytab"
          echo "Replace 'XXXX:XXXX' with the user & group that dhcpd runs as on your distro"
          echo "chmod 400 /etc/dhcpduser.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 /etc/dhcpduser.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=$?
      ;;
      delete)
           _KERBEROS
      
      nsupdate -g ${NSUPDFLAGS} << UPDATE
      server 127.0.0.1
      realm ${REALM}
      update delete ${name}.${domain} 3600 A
      send
      UPDATE
      result1=$?
      ;;
      *)
      echo "Invalid action specified"
      exit 103
      ;;
      esac
      
      result="${result1}"
      
      if [ "${result}" != "0" ]; then
          logger "DHCP-DNS Update failed: ${result}"
      else
          logger "DHCP-DNS Update succeeded"
      fi
      
      exit ${result}

      Set the rights to the script

      sudo chmod 755 /usr/local/bin/dhcp-dyndns.sh
    6. Modifiable file with settings
      Create a bekap and modify the config

      sudo cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf_bak
      sudo nano /etc/dhcp/dhcpd.conf

      Replacing content with the following:

      authoritative;
      ddns-update-style none;
      
      subnet 192.168.1.0 netmask 255.255.255.0 { #Подсеть и маска на которую будет вещать dhcp сервер
        option subnet-mask 255.255.255.0;
        option broadcast-address 192.168.1.255;
        option time-offset 0;
        option routers 192.168.1.1; #Шлюз
        option domain-name "adminguide.lan"; #Имя домена
        option domain-name-servers 192.168.1.100; #ДНС сервера
        option netbios-name-servers 192.168.1.100; #NetBIOS сервера
        option ntp-servers 192.168.1.100; #NTP сервера
        pool { #Пулл адресов
          max-lease-time 1800; # Максимальное время аренды в секундах
          range 192.168.1.110 192.168.1.199; #Диапазон адресов
        }
      }
      
      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("adminguide.ru 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, ClientName);
      }
      
      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");
      }
    7. Edit the rights to launch
      sudo nano /etc/apparmor.d/usr.sbin.dhcpd

      Add to the end of the file before the closing bracket

      /usr/local/bin/dhcp-dyndns.sh rix,
      /dev/tty wr,
      /usr/sbin/samba rix,
      /usr/bin/gawk rix,
      /usr/bin/grep rix,
      /usr/bin/hostname rix,
      /usr/bin/logger rix,
      /usr/bin/wbinfo rix,
      /usr/bin/date rix,
      /usr/bin/klist rix,
      /usr/bin/host rix,
      /proc/** wr,
      /usr/bin/kinit rix,
      /etc/dhcpduser.keytab rk,
      /run/samba/winbindd/pipe wr,
      /etc/dhcpduser.keytab rk,
      /tmp/* wrk,
      /usr/bin/nsupdate rix,

      Restart AppArmor

      sudo /etc/init.d/apparmor stop && sudo /etc/init.d/apparmor start

      Restart DHCP server

      sudo service isc-dhcp-server stop && sudo service isc-dhcp-server start
    8. DHCP server for Linux AD-DC – Check DHCP

      In the network with ad-dc-1 I have another ubuntu server with the name client-lin-1. It’s not in the domain, it’s not configured, it’s just there and it gets network settings on dhcp.
      Trying to kick this client by name, the result is zero.
      I turn on this server, waiting for it to load. After the server is loaded, I try again, the ping goes.
      Teams ping client-lin-1 and ping client-lin-1.adminguide.lan will now successfully ping this machine by name. Like your other devices that are not in the domain and receive addresses on DHCP from the domain controller.
      I release and re-request an IP address fulfilling on the client command:

      sudo dhclient -r && sudo dhclient

      Watching logs as a team

      tail -n 250 /var/log/syslog

      I see an answer similar to:

      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: Release: IP: 192.168.1.114
      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: execute_statement argv[0] = /usr/local/bin/dhcp-dyndns.sh
      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: execute_statement argv[1] = delete
      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: execute_statement argv[2] = 192.168.1.114
      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: execute_statement argv[3] = 00:0c:29:20:ce:d2
      Aug 30 16:56:23 ag-dc-1 named[675]: samba_dlz: starting transaction on zone adminguide.lan
      Aug 30 16:56:23 ag-dc-1 named[675]: samba_dlz: allowing update of signer=dhcpduser@ADMINGUIDE. LAN name=3(NXDOMAIN).adminguide.lan tcpaddr=127.0.0.1 type=A key=3167229815.sig-ag-dc-1.adminguide.lan/160/0
      Aug 30 16:56:23 ag-dc-1 named[675]: client @0x7f1c180b8670 127.0.0.1#58645/key dhcpduser@ADMINGUIDE. LAN: updating zone 'adminguide.lan/NONE': deleting rrset at '3(NXDOMAIN).adminguide.lan' A
      Aug 30 16:56:23 ag-dc-1 name[675]d: samba_dlz: committed transaction on zone adminguide.lan
      Aug 30 16:56:23 ag-dc-1 dhcpd: DHCP-DNS Update succeeded
      Aug 30 16:56:23 ag-dc-1 dhcp[10880]d: DHCPRELEASE of 192.168.1.114 from 00:0c:29:20:ce:d2 (client-lin-1) via ens160 (found)
      Aug 30 16:56:23 ag-dc-1 dhcpd[10880]: DHCPDISCOVER from 00:0c:29:20:ce:d2 via ens160
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: DHCPOFFER on 192.168.1.114 to 00:0c:29:20:ce:d2 (client-lin-1) via ens160
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: adminguide.ru commit: IP: 192.168.1.114 DHCID: 00:0c:29:20:ce:d2 Name: client-lin-1
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: execute_statement argv[0] = /usr/local/bin/dhcp-dyndns.sh
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: execute_statement argv[1] = add
      Aug 30 16:56:24 ag-dc-1 dhcpd:[10880] execute_statement argv [2]= 192.168.1.114
      Aug 30 16:56:24 ag-dc-1 dhcpd:[10880] execute_statement argv [3]= 00:0c:29:20:ce:d2
      Aug 30 16:56:24 ag-dc-1 dhcpd:[10880] execute_statement argv [4]= client-lin-1
      Aug 30 16:56:24 ag-dc-1 named:[675] samba_dlz: starting transaction on zone adminguide.lan
      Aug 30 16:56:24 ag-dc-1 named:[675] samba_dlz: allowing update of signer=dhcpduser@ADMINGUIDE. LAN name=client-lin-1.adminguide.lan tcpaddr=127.0.0.1 type=A key=3775092585.sig-ag-dc-1.adminguide.lan/160/0
      Aug 30 16:56:24 ag-dc-1 named[675]: samba_dlz: allowing update of signer=dhcpduser@ADMINGUIDE. LAN name=client-lin-1.adminguide.lan tcpaddr=127.0.0.1 type=A key=3775092585.sig-ag-dc-1.adminguide.lan/160/0
      Aug 30 16:56:24 ag-dc-1 named[675]: client @0x7f1bf808a7f0 127.0.0.1#60997/key dhcpduser@ADMINGUIDE. LAN: updating zone 'adminguide.lan/NONE': deleting rrset at 'client-lin-1.adminguide.lan' A
      Aug 30 16:56:24 ag-dc-1 name[675]d: samba_dlz: subtracted rdataset client-lin-1.adminguide.lan 'client-lin-1.adminguide.lan.#0113600#011IN#011A#011192.168.1.112'
      Aug 30 16:56:24 ag-dc-1 named[675]: client @0x7f1bf808a7f0 127.0.0.1#60997/key dhcpduser@ADMINGUIDE. LAN: updating zone 'adminguide.lan/NONE': adding an RR at 'client-lin-1.adminguide.lan' A 192.168.1.114
      Aug 30 16:56:24 ag-dc-1 name[675]d: samba_dlz: added rdataset client-lin-1.adminguide.lan 'client-lin-1.adminguide.lan.#0113600#011IN#011A#011192.168.1.114'
      Aug 30 16:56:24 ag-dc-1 name[675]d: samba_dlz: subtracted rdataset adminguide.lan 'adminguide.lan.#0113600#011IN#011SOA#011ag-dc-1.adminguide.lan. hostmaster.adminguide.lan. 48 900 600 86400 3600'
      Aug 30 16:56:24 ag-dc-1 named[675]: samba_dlz: added rdataset adminguide.lan 'adminguide.lan.#0113600#011IN#011SOA#011ag-dc-1.adminguide.lan. hostmaster.adminguide.lan. 49 900 600 86400 3600'
      Aug 30 16:56:24 ag-dc-1 named[675]: samba_dlz: committed transaction on zone adminguide.lan
      Aug 30 16:56:24 ag-dc-1 dhcpd: DHCP-DNS Update succeeded
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: DHCPREQUEST for 192.168.1.114 (192.168.1.100) from 00:0c:29:20:ce:d2 (client-lin-1) via ens160
      Aug 30 16:56:24 ag-dc-1 dhcpd[10880]: DHCPACK on 192.168.1.114 to 00:0c:29:20:ce:d2 (client-lin-1) via ens160
      
  2. DHCP Server for Linux AD-DC – Conclusion

    That’s how we came to an end. Never forget that there is still a lot of room for improvements, but this option will allow the admin to have in a small office licensed Active Directory Domain Controller with DNS and DHCP servers that are able to serve not only computers attached to the domain, but all machines in general. This will allow you to get away from setting up local services to static ip addresses, and switch to using dynamic ip addresses in conjunction with device names dns

P.S. If you have multiple network interfaces configured to receive network settings on DHCP, they’ll all get customized. But the host team <device_name> will return the address of the last interface of the server that appealed to THE DHCP.</device_name>

Text.ru - 100.00%

You may also like

Leave a Comment