https://wiki.archlinux.org/api.php?action=feedcontributions&user=Falcor84&feedformat=atomArchWiki - User contributions [en]2024-03-29T08:37:04ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Samba/Active_Directory_domain_controller&diff=302920Samba/Active Directory domain controller2014-03-02T14:09:40Z<p>Falcor84: /* Provisioning */ typo s/sever/server/</p>
<hr />
<div>[[Category:Networking]]<br />
{{Related articles start}}<br />
{{Related|OpenChange Server}}<br />
{{Related|Active Directory Integration}}<br />
{{Related|Samba/Tips and tricks}}<br />
{{Related|Samba/Advanced file sharing with KDE4}}<br />
{{Related|Samba}}<br />
{{Related|Samba Domain Controller}}<br />
{{Related articles end}}<br />
<br />
This article explains how to setup a new Active Directory Domain Controller. It is assumed that all configuration files are in their unmodified, post-installation state. This article was written and tested on a fresh installation, with no modifications other than setting up a staic IPv4 network connection, assigning a hostname, and adding openssh and vim (which should have no effect on the Samba configuration). Finally, most of the commands below will require elevated privileges. Despite conventional wisdom, it may be easier to run these short few commands from a root session as opposed to obtaining rights on an as needed basis.<br />
<br />
==Installation==<br />
<br />
A fully functional samba 4 DC requires several programs beyond those included with the Samba distribution. Install all needed packages with the following command:<br />
<br />
pacman -S dnsutils krb5 ntp openldap samba<br />
<br />
Additionally, Samba contains its own fully functional DNS server, but many admins prefer to use the ISC BIND package. If you need to maintain DNS zones for external domains, you are strongly encouraged to use BIND. If you would like to use BIND, issue the following command:<br />
<br />
pacman -S bind<br />
<br />
If you need to share printers, you will also need CUPS:<br />
<br />
pacman -S cups<br />
<br />
==Provisioning==<br />
<br />
The first step to creating an Active Directory domain is provisioning. If this is the first domain controller in a new domain (as this guide assumes), this involves setting up the internal LDAP, Kerberos, and DNS servers and performing all of the basic configuration needed for the directory. If you have set up a directory server before, you are undoubtedly aware of the potential for errors in making these individual components work together as a single unit. The difficulty in doing so is the very reason that the Samba developers chose not to use the MIT or Heimdal Kerberos server or OpenLDAP server, instead opting for internal versions of these programs. The server packages above were installed only for the client utilities. Provisioning is quite a bit easier with Samba 4. Just issue the following command:<br />
<br />
samba-tool domain provision --use-rfc2307 --interactive --use-xattrs=yes<br />
<br />
===Argument Explanations===<br />
;--use-rfc2307<br />
:this argument adds POSIX attributes (UID/GID) to the AD Schema. This will be necessary if you intend to authenticate Linux, BSD, or OS X clients (including the local machine) in addition to Microsoft Windows.<br />
<br />
;--use-xattrs=yes<br />
:this argument enables the use of unix extended attributes (ACLs) for files hosted on this server. If you intend not have file shares on the domain controller, you can omit this switch (but this is not recommended). You should also ensure that any filesystems that will host Samba shares are mounted with support for ACLs.<br />
<br />
;--interactive<br />
:this parameter forces the provision script to run interactively. Alternately, you can review the help for the provision step by running '''samba-tool domain provision --help'''.<br />
<br />
===Interactive Provision Explanations===<br />
;Realm<br />
:'''INTERNAL.DOMAIN.COM''' - This should be the same as the DNS domain in all caps. It is common to use an internal-only sub-domain to separate your internal domain from your external DNS domains, but it is not required.<br />
<br />
;Domain<br />
:'''INTERNAL''' - This will be the NetBIOS domain name, usually the leftmost DNS sub-domain but can be anything you like. For example, the name INTERNAL would not be very descriptive. Perhaps company name or initials would be appropriate. This should be entered in all caps, and should have a 15 character maximum length for compatibility with older clients.<br />
<br />
;Server Role<br />
:'''dc''' - This article assumes that your are installing the first DC in a new domain. If you select anything different, the rest of this article will likely be useless to you.<br />
<br />
;DNS Backend<br />
:'''BIND9_DLZ''' or '''SAMBA_INTERNAL''' - This is down to personal preference of the server admin. Again, if you are hosting DNS for external domains, you are strongly encouraged to use the '''BIND9_DLZ''' backend so that flat zone files can continue to be used and existing transfer rules can co-exist with the internal DNS server. If unsure, use the '''BIND9_DLZ''' backend.<br />
<br />
;Administrator password<br />
:'''xxxxxxxx''' - You must select a ''strong'' password for the administrator account. The minimum requirements are one upper case letter, one number, and at least eight characters. If you attempt to use a password that does not meet the complexity requirements, provisioning will fail.<br />
<br />
==Configuring Daemons==<br />
<br />
===NTPD===<br />
<br />
Use the following commands to create a suitable NTP configuration for your network time server. See [[Ntpd]] for explanations of, and additional configuration options:<br />
<br />
mv /etc/ntp.conf{,.default}<br />
cat > /etc/ntp.conf << "EOF"<br />
# Begin /etc/ntp.conf<br />
<br />
# Associate to the public NTP pool servers<br />
server 0.pool.ntp.org<br />
server 1.pool.ntp.org<br />
server 2.pool.ntp.org<br />
<br />
# Location of drift file<br />
driftfile /var/lib/ntp/ntp.drift<br />
<br />
# Location of the log file<br />
logfile /var/log/ntp<br />
<br />
# Location of the update directory<br />
ntpsigndsocket /var/lib/samba/ntp_signd/<br />
<br />
# Restrictions<br />
restrict default kod nomodify notrap nopeer mssntp<br />
restrict 127.0.0.1<br />
restrict 0.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery<br />
restrict 1.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery<br />
restrict 2.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery<br />
<br />
# End /etc/ntp.conf<br />
EOF<br />
install -d /var/lib/samba/ntp_signd<br />
chown root:ntp /var/lib/samba/ntp_signd<br />
chmod 0750 /var/lib/samba/ntp_signd<br />
systemctl enable ntpd.service<br />
systemctl start ntpd<br />
<br />
===BIND===<br />
<br />
If you elected to use the '''BIND9_DLZ''' DNS backend, execute the following commands to create a suitable BIND configuration. See [[Bind]] for explanations of, and additional configuration options. Be sure to replace the '''x''' characters with suitable values:<br />
<br />
mv /etc/named.conf{,.default}<br />
cat > /etc/named.conf << "EOF"<br />
//Begin /etc/named.conf<br />
<br />
// Global options<br />
options {<br />
auth-nxdomain yes;<br />
datasize default;<br />
directory "/var/named";<br />
empty-zones-enable no;<br />
pid-file "/run/named/named.pid";<br />
tkey-gssapi-keytab "/var/lib/samba/private/dns.keytab";<br />
forwarders { '''xxx.xxx.xxx.xxx'''; '''xxx.xxx.xxx.xxx'''; };<br />
// Uncomment the next line to enable IPv6<br />
// listen-on-v6 { any; };<br />
notify no;<br />
// Add any subnets or hosts you want to allow to use this DNS server (use "; " delimiter)<br />
allow-query { '''xxx.xxx.xxx.xxx/xx'''; };<br />
// Add any subnets or hosts you want to allow to use recursive queries<br />
allow-recursion { '''xxx.xxx.xxx.xxx/xx'''; };<br />
// Add any subnets or hosts you want to allow dynamic updates from<br />
allow-update { '''xxx.xxx.xxx.xxx/xx'''; };<br />
version none;<br />
hostname none;<br />
server-id none;<br />
};<br />
<br />
//Root servers (required zone for recursive queries)<br />
zone "." IN {<br />
type hint;<br />
file "root.hint";<br />
};<br />
<br />
//Required localhost forward-/reverse zones<br />
zone "localhost" IN {<br />
type master;<br />
file "localhost.zone";<br />
allow-transfer { any; };<br />
};<br />
zone "0.0.127.in-addr.arpa" IN {<br />
type master;<br />
file "127.0.0.zone";<br />
allow-transfer { any; };<br />
};<br />
<br />
//Required zone for AD<br />
dlz "AD DNS Zone" {<br />
database "dlopen /usr/lib/samba/bind9/dlz_bind9_9.so";<br />
};<br />
<br />
//Log settings<br />
logging {<br />
channel xfer-log {<br />
file "/var/log/named.log";<br />
print-category yes;<br />
print-severity yes;<br />
print-time yes;<br />
severity info;<br />
};<br />
category xfer-in { xfer-log; };<br />
category xfer-out { xfer-log; };<br />
category notify { xfer-log; };<br />
};<br />
<br />
//End /etc/named.conf<br />
EOF<br />
chgrp named /var/lib/samba/private/dns.keytab<br />
chmod g+r /var/lib/samba/private/dns.keytab<br />
systemctl enable named.service<br />
systemctl start named<br />
<br />
Good values for forwarders are your ISP's DNS servers. Google (8.8.8.8 and 8.8.4.4) and OpenDNS (208.67.222.222 and 208.67.220.220) provide suitable public DNS servers free of charge. Appropriate values for subnets are specific to your network.<br />
<br />
<br />
You will need to begin using the local DNS server now. Execute the following commands substituting your server's IP address(es), and '''internal.domain.tld''' with your internal domain:<br />
<br />
cp /etc/resolv.conf{,.bak}<br />
cat > /etc/resolv.conf << "EOF"<br />
# Begin /etc/resolv.conf<br />
<br />
search '''internal.domain.tld'''<br />
nameserver '''xxx.xxx.xxx.xxx'''<br />
<br />
# End /etc/resolv.conf<br />
EOF<br />
<br />
Uncomment local DNS<br />
<br />
/etc/resolvconf.conf<br />
name_server = 127.0.0.1<br />
<br />
And regenerate new conf file<br />
resolvconf -u<br />
<br />
===Kerberos Client Utilities===<br />
<br />
The provisioning step above created a perfectly valid krb5.conf file for use with a Samba 4 DC. Install it with the following commands:<br />
<br />
mv /etc/krb5.conf{,.default}<br />
cp /var/lib/samba/private/krb5.conf /etc<br />
<br />
===Samba===<br />
<br />
Finally, enable and start Samba. The NTP update directory created earlier must be removed or samba will fail to run. Execute the following commands to start the Samba services:<br />
<br />
rm -rf /var/lib/samba/ntp_signd<br />
systemctl enable samba.service<br />
systemctl start samba<br />
<br />
You will also need to fix permissions on the newly created NTP update directory and restart NTPD:<br />
<br />
chgrp ntp /var/lib/samba/ntp_signd<br />
systemctl restart ntpd<br />
<br />
Finally, if you intend to use the LDB utilities, you will need to set the '''LDB_MODULES_PATH'''<br />
<br />
echo "export LDB_MODULES_PATH=\"\${LDB_MODULES_PATH}:/usr/lib/samba/ldb\"" > /etc/profile.d/sambaldb.sh<br />
chmod 0755 /etc/profile.d/sambaldb.sh<br />
<br />
==Testing the Installation==<br />
<br />
===DNS===<br />
First, verify that DNS is working as expected. Execute the following commands substituting appropriate values for '''internal.domain.com''' and '''server''':<br />
<br />
host -t SRV _ldap._tcp.'''internal.domain.com'''.<br />
host -t SRV _kerberos._udp.'''internal.domain.com'''.<br />
host -t A '''server'''.'''internal.domain.com'''.<br />
<br />
You should receive output similar to the following:<br />
<br />
<pre style="background: #E5E4E2">_ldap._tcp.internal.domain.com has SRV record 0 100 389 server.internal.domain.com.<br />
_kerberos._udp.internal.domain.com has SRV record 0 100 88 server.internal.domain.com.<br />
server.internal.domain.com has address xxx.xxx.xxx.xxx</pre><br />
<br />
===NT Authentication===<br />
<br />
Next, verify that password authentication is working as expected:<br />
<br />
smbclient //localhost/netlogon -U Administrator -c 'ls'<br />
<br />
You will be prompted for a password (the one you selected earlier), and will get a directory listing like the following:<br />
<br />
<pre style="background: #E5E4E2">Domain=[INTERNAL] OS=[Unix] Server=[Samba 4.1.2]<br />
. D 0 Wed Nov 27 23:59:07 2013<br />
.. D 0 Wed Nov 27 23:59:12 2013<br />
<br />
50332 blocks of size 2097152. 47185 blocks available</pre><br />
<br />
===Kerberos===<br />
<br />
Now verify that the KDC is working as expected. Be sure to replace '''INTERNAL.DOMAIN.COM''' and use upper case letters:<br />
<br />
kinit administrator@'''INTERNAL.DOMAIN.COM'''<br />
<br />
You should be prompted for a password and get output similar to the following:<br />
<br />
<pre style="background: #E5E4E2">Warning: Your password will expire in 41 days on Wed 08 Jan 2014 11:59:11 PM CST</pre> <br />
<br />
Verify that you actually got a ticket:<br />
<br />
klist<br />
<br />
You should get output similar to below:<br />
<br />
<pre style="background: #E5E4E2">Ticket cache: FILE:/tmp/krb5cc_0<br />
Default principal: administrator@INTERNAL.DOMAIN.COM<br />
<br />
Valid starting Expires Service principal<br />
11/28/2013 00:22:17 11/28/2013 10:22:17 krbtgt/INTERNAL.DOMAIN.COM@INTERNAL.DOMAIN.COM<br />
renew until 11/29/2013 00:22:14</pre><br />
<br />
As a final test, use smbclient with your recently acquired ticket. Replace '''server''' with the correct server name:<br />
<br />
smbclient //'''server'''/netlogon -k -c 'ls'<br />
<br />
The output should be the same as when testing password authentication above.<br />
<br />
==Additional Configuration ==<br />
<br />
=== DNS ===<br />
<br />
You will also need to create a reverse lookup zone for each subnet in your environment in DNS. It is important that this is kept in Samba's DNS as opposed to BIND to allow for dynamic updates by cleints. For each subnet, create a reverse lookup zone with the following commands. Replace '''server'''.'''internal'''.'''domain'''.'''tld''' and '''xxx'''.'''xxx'''.'''xxx''' with appropriate values. For '''xxx'''.'''xxx'''.'''xxx''', use the first three octets of the subnet in reverse order (for example: 192.168.0.0/24 becomes 0.168.192):<br />
<br />
samba-tool dns zonecreate '''server'''.'''internal'''.'''domain'''.'''tld''' '''xxx'''.'''xxx'''.'''xxx'''.in-addr.arpa<br />
<br />
Now, add a record for you server (if your server is multi-homed, add for each subnet) again substituting appropriate values as above. '''zzz''' will be replaced by the fourth octet of the IP for the server:<br />
<br />
samba-tool dns add '''server'''.'''internal'''.'''domain'''.'''tld'''' '''xxx'''.'''xxx'''.'''xxx'''.in-addr.arpa '''zzz''' PTR '''server'''.'''internal'''.'''domain'''.'''tld''''<br />
<br />
Finally, restart Bind and test the lookup. Replace '''xxx'''.'''xxx'''.'''xxx'''.'''xxx''' with the IP of your server:<br />
<br />
systemctl restart named<br />
host -t PTR '''xxx'''.'''xxx'''.'''xxx'''.'''xxx'''<br />
<br />
You should get output similar to the following:<br />
<br />
<pre style="background: #E5E4E2">xxx.xxx.xxx.xxx.in-addr.arpa domain name pointer server.internal.domain.tld.</pre><br />
<br />
===DHCP===<br />
<br />
It should be noted that using this method will affect functionality of windows clients, as they will still attempt to update DNS on their own and will be denied permission to do so as the record will be owned by the dhcp user. You should create a GPO to overcome this, but unfortunately, Samba 4 does not yet have a command line utility to modify GPOs, so you'll need a Windows PC with the RSAT tools installed. Simply create a dedicated GPO with the Group Policy Editor, apply only to OUs that contain workstations (so that servers can still update using 'ipconfig /registerdns') and configure the following settings:<br />
<br />
<pre style="background: #E5E4E2">Computer Configuration<br />
Policies<br />
Administrative Templates<br />
Network<br />
DNS Client<br />
Dynamic Update = Disabled<br />
Register PTR Records = Disabled</pre><br />
<br />
Install ISC DHCPd:<br />
<br />
pacman -S dhcpd<br />
<br />
Create an unprivileged user in AD for performing the updates. When prompted for password, use a secure password. 63 random, mixed case, alpha-numeric characters is sufficient. Optionally samba-tool also takes a random argument:<br />
<br />
samba-tool user create dhcp --description="Unprivileged user for DNS updates via DHCP server"<br />
<br />
Give the user privelges to administer DNS:<br />
samba-tool group addmembers DnsAdmins dhcp<br />
<br />
Export the users credentials to a private keytab:<br />
samba-tool domain exportkeytab --principal=dhcp@'''INTERNAL'''.'''DOMAIN'''.'''TLD''' dhcpd.keytab<br />
install -vdm 755 /etc/dhcpd<br />
mv dhcpd.keytab /etc/dhcpd<br />
chown root:root /etc/dhdpd.keytab<br />
chmod 400 /etc/dhcpd/dhcpd.keytab<br />
<br />
Now that the user is created, add this script to perform the updates:<br />
<br />
cat > /usr/sbin/samba-dnsupdate.sh << "EOF"<br />
#!/bin/bash<br />
# Begin samba-dnsupdate.sh<br />
# Author: DJ Lucas <dj_AT_linuxfromscratch_DOT_org><br />
# kerberos_creds() courtesy of Sergey Urushkin<br />
# http://www.kuron-germany.de/michael/blog/wp-content/uploads/2012/03/dhcpdns-sergey2.txt<br />
<br />
# DHCP server should be authoritative for its own records, sleep for 5 seconds<br />
# to allow unconfigured Windows hosts to create their own DNS records<br />
# In order to use this script you should disable dynamic updates by hosts that<br />
# will receive addresses from this DHCP server. Instructions are found here:<br />
# https://wiki.archlinux.org/index.php/Samba_4_Active_Directory_Domain_Controller#DHCP<br />
sleep 5<br />
<br />
checkvalues()<br />
{<br />
[ -z "${2}" ] && echo "Error: argument '${1}' requires a parameter." && exit 1<br />
<br />
case ${2} in<br />
<br />
-*)<br />
echo "Error: Invalid parameter '${2}' passed to ${1}."<br />
exit 1<br />
;;<br />
<br />
*)<br />
return 0<br />
;;<br />
esac<br />
}<br />
<br />
showhelp()<br />
{<br />
echo -e "\n"`basename ${0}` "uses samba-tool to update DNS records in Samba 4's DNS"<br />
echo "server when using INTERNAL DNS or BIND9 DLZ plugin."<br />
echo ""<br />
echo " Command line options (and variables):"<br />
echo ""<br />
echo " -a | --action Action for this script to perform"<br />
echo " ACTION={add|delete}"<br />
echo " -c | --krb5cc Path of the krb5 credential cache (optional)"<br />
echo " Default: KRB5CC=/run/dhcpd.krb5cc"<br />
echo " -d | --domain The DNS domain/zone to be updated"<br />
echo " DOMAIN={domain.tld}"<br />
echo " -h | --help Show this help message and exit"<br />
echo " -H | --hostname Hostname of the record to be updated"<br />
echo " HNAME={hostname}"<br />
echo " -i | --ip IP address of the host to be updated"<br />
echo " IP={0.0.0.0}"<br />
echo " -k | --keytab Krb5 keytab to be used for authorization (optional)"<br />
echo " Default: KEYTAB=/etc/dhcp/dhcpd.keytab"<br />
echo " -m | --mitkrb5 Use MIT krb5 client utilities"<br />
echo " MITKRB5={YES|NO}"<br />
echo " -n | --nameserver DNS server to be updated (must use FQDN, not IP)"<br />
echo " NAMESERVER={server.internal.domain.tld}"<br />
echo " -p | --principal Principal used for DNS updates"<br />
echo " PRINCIPAL={user@domain.tld}"<br />
echo " -r | --realm Authentication realm"<br />
echo " REALM={DOMAIN.TLD}"<br />
echo " -z | --zone Then name of the zone to be updated in AD.<br />
echo " ZONE={zonename}<br />
echo ""<br />
echo "Example: $(basename $0) -d domain.tld -i 192.168.0.x -n 192.168.0.x \\"<br />
echo " -r DOMAIN.TLD -p user@domain.tld -H HOSTNAME -m"<br />
echo ""<br />
}<br />
<br />
# Process arguments<br />
[ -z "$1" ] && showhelp && exit 1<br />
while [ -n "$1" ]; do<br />
case $1 in<br />
<br />
-a | --action)<br />
checkvalues ${1} ${2}<br />
ACTION=${2}<br />
shift 2<br />
;;<br />
<br />
-c | --krb5cc)<br />
checkvalues ${1} ${2}<br />
KRB5CC=${2}<br />
shift 2<br />
;;<br />
<br />
-d | --domain)<br />
checkvalues ${1} ${2}<br />
DOMAIN=${2}<br />
shift 2<br />
;;<br />
<br />
-h | --help)<br />
showhelp<br />
exit 0<br />
;;<br />
<br />
-H | --hostname)<br />
checkvalues ${1} ${2}<br />
HNAME=${2%%.*}<br />
shift 2<br />
;;<br />
<br />
-i | --ip)<br />
checkvalues ${1} ${2}<br />
IP=${2}<br />
shift 2<br />
;;<br />
<br />
-k | --keytab)<br />
checkvalues ${1} ${2}<br />
KEYTAB=${2}<br />
shift 2<br />
;;<br />
<br />
-m | --mitkrb5)<br />
KRB5MIT=YES<br />
shift 1<br />
;;<br />
<br />
-n | --nameserver)<br />
checkvalues ${1} ${2}<br />
NAMESERVER=${2}<br />
shift 2<br />
;;<br />
<br />
-p | --principal)<br />
checkvalues ${1} ${2}<br />
PRINCIPAL=${2}<br />
shift 2<br />
;;<br />
<br />
-r | --realm)<br />
checkvalues ${1} ${2}<br />
REALM=${2}<br />
shift 2<br />
;;<br />
<br />
-z | --zone)<br />
checkvalues ${1} ${2}<br />
ZONE=${2}<br />
shift 2<br />
;;<br />
<br />
*)<br />
echo "Error!!! Unknown command line opion!"<br />
echo "Try" `basename $0` "--help."<br />
exit 1<br />
;;<br />
esac<br />
done<br />
<br />
# Sanity checking<br />
[ -z "$ACTION" ] && echo "Error: action not set." && exit 2<br />
case "$ACTION" in<br />
add | Add | ADD)<br />
ACTION=ADD<br />
;;<br />
del | delete | Delete | DEL | DELETE)<br />
ACTION=DEL<br />
;;<br />
*)<br />
echo "Error: invalid action \"$ACTION\"." && exit 3<br />
;;<br />
esac<br />
[ -z "$KRB5CC" ] && KRB5CC=/run/dhcpd.krb5cc<br />
[ -z "$DOMAIN" ] && echo "Error: invalid domain." && exit 4<br />
[ -z "$HNAME" ] && [ "$ACTION" == "ADD" ] && \<br />
echo "Error: hostname not set." && exit 5<br />
[ -z "$IP" ] && echo "Error: IP address not set." && exit 6<br />
[ -z "$KEYTAB" ] && KEYTAB=/etc/dhcp/dhcpd.keytab<br />
[ -z "$NAMESERVER" ] && echo "Error: nameservers not set." && exit 7<br />
[ -z "$PRINCIPAL" ] && echo "Error: principal not set." && exit 8<br />
[ -z "$REALM" ] && echo "Error: realm not set." && exit 9<br />
[ -z "$ZONE" ] && echo "Error: zone not set." && exit 10<br />
<br />
# Disassemble IP for reverse lookups<br />
OCT1=$(echo $IP | cut -d . -f 1)<br />
OCT2=$(echo $IP | cut -d . -f 2)<br />
OCT3=$(echo $IP | cut -d . -f 3)<br />
OCT4=$(echo $IP | cut -d . -f 4)<br />
RZONE="$OCT3.$OCT2.$OCT1.in-addr.arpa"<br />
<br />
kerberos_creds() {<br />
export KRB5_KTNAME="$KEYTAB"<br />
export KRB5CCNAME="$KRB5CC"<br />
<br />
if [ "$KRB5MIT" = "YES" ]; then<br />
KLISTARG="-s"<br />
else<br />
KLISTARG="-t"<br />
fi<br />
<br />
klist $KLISTARG || kinit -k -t "$KEYTAB" -c "$KRB5CC" "$PRINCIPAL" || { logger -s -p daemon.error -t dhcpd kinit for dynamic DNS failed; exit 11; }<br />
}<br />
<br />
<br />
add_host(){<br />
logger -s -p daemon.info -t dhcpd Adding A record for host $HNAME with IP $IP to zone $ZONE on server $NAMESERVER<br />
samba-tool dns add $NAMESERVER $ZONE $HNAME A $IP -k yes<br />
}<br />
<br />
<br />
delete_host(){<br />
logger -s -p daemon.info -t dhcpd Removing A record for host $HNAME with IP $IP from zone $ZONE on server $NAMESERVER<br />
samba-tool dns delete $NAMESERVER $ZONE $HNAME A $IP -k yes<br />
}<br />
<br />
<br />
update_host(){<br />
CURIP=$(host -t A $HNAME | cut -d " " -f 4)<br />
logger -s -p daemon.info -t dhcpd Removing A record for host $HNAME with IP $CURIP from zone $ZONE on server $NAMESERVER<br />
samba-tool dns delete $NAMESERVER $ZONE $HNAME A $CURIP -k yes<br />
add_host<br />
}<br />
<br />
<br />
add_ptr(){<br />
logger -s -p daemon.info -t dhcpd Adding PTR record $OCT4 with hostname $HNAME to zone $RZONE on server $NAMESERVER<br />
samba-tool dns add $NAMESERVER $RZONE $OCT4 PTR $HNAME.$DOMAIN -k yes<br />
}<br />
<br />
<br />
delete_ptr(){<br />
logger -s -p daemon.info -t dhcpd Removing PTR record $OCT4 with hostname $HNAME from zone $RZONE on server $NAMESERVER<br />
samba-tool dns delete $NAMESERVER $RZONE $OCT4 PTR $HNAME.$DOMAIN -k yes<br />
}<br />
<br />
<br />
update_ptr(){<br />
CURHNAME=$(host -t PTR $OCT4 | cut -d " " -f 5)<br />
logger -s -p daemon.info -t dhcpd Removing PTR record $OCT4 with hostname $CURHNAME from zone $RZONE on server $NAMESERVER<br />
samba-tool dns delete $NAMESERVER $RZONE $OCT4 PTR $CURHNAME -k yes<br />
add_ptr<br />
}<br />
<br />
<br />
case "$ACTION" in<br />
ADD)<br />
kerberos_creds<br />
host -t A $HNAME.$DOMAIN > /dev/null<br />
if [ "${?}" == 0 ]; then<br />
update_host<br />
else<br />
add_host<br />
fi<br />
<br />
host -t PTR $IP > /dev/null<br />
if [ "${?}" == 0 ]; then<br />
update_ptr<br />
else<br />
add_ptr<br />
fi<br />
;;<br />
<br />
DEL)<br />
kerberos_creds<br />
host -t A $HNAME.$DOMAIN > /dev/null<br />
if [ "${?}" == 0 ]; then<br />
delete_host<br />
fi<br />
<br />
host -t PTR $IP > /dev/null<br />
if [ "${?}" == 0 ]; then<br />
delete_ptr<br />
fi<br />
;;<br />
<br />
*)<br />
echo "Error: Invalid action '$ACTION'!" && exit 12<br />
;;<br />
<br />
esac<br />
<br />
# End samba-dnsupdate.sh<br />
EOF<br />
chmod 750 /usr/sbin/samba-dnsupdate.sh<br />
<br />
The dhcpd service will need to use a fast exiting wrapper script to avoid locking issues and delays. Create the script with the following commands (substituting correct values for '''server''', '''internal'''.'''domain'''.'''tld''', and '''INTERNAL'''.'''DOMAIN'''.'''TLD'''):<br />
<br />
cat > /etc/dhcpd/update.sh << "EOF"<br />
#!/bin/bash<br />
# Begin /etc/dhcpd/update.sh<br />
<br />
# Variables<br />
KRB5CC="/run/dhcpd4.krb5cc"<br />
KEYTAB="/etc/dhcpd/dhcpd.keytab"<br />
DOMAIN="'''internal'''.'''domain'''.'''tld'''"<br />
REALM="'''INTERNAL'''.'''DOMAIN'''.'''TLD'''"<br />
PRINCIPAL="dhcp@${REALM}"<br />
NAMESERVER="'''server'''.${DOMAIN}"<br />
ZONE="${DOMAIN}"<br />
<br />
ACTION=$1<br />
IP=$2<br />
HNAME=$3<br />
<br />
export KRB5CC KEYTAB DOMAIN REALM PRINCIPAL NAMESERVER ZONE ACTION IP HNAME<br />
<br />
/usr/sbin/samba-dnsupdate.sh -m &<br />
<br />
# End /etc/dhcpd/update.sh<br />
EOF<br />
chmod 750 /etc/dhcpd/update.sh<br />
<br />
Configure the dhcpd server following the [[dhcpd]] article and add the following to all subnet declarations in /etc/dhcpd.conf that provide DHCP service:<br />
<br />
<pre style="background: #E5E4E2"> on commit {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "add", ClientIP, ClientName);<br />
}<br />
<br />
on release {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "delete", ClientIP, ClientName);<br />
}<br />
<br />
on expiry {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "delete", ClientIP, ClientName);</pre><br />
<br />
Here is a complete example /etc/dhcpd.conf for reference:<br />
<br />
<pre style="background: #E5E4E2"># Begin /etc/dhcpd.conf<br />
<br />
# No DHCP service in the DMZ.<br />
subnet 192.168.2.0 netmask 255.255.255.0 {<br />
}<br />
<br />
# Internal subnet<br />
subnet 192.168.1.0 netmask 255.255.255.0 {<br />
range 192.168.1.100 192.168.1.199;<br />
option subnet-mask 255.255.255.0;<br />
option routers 192.168.1.254;<br />
option domain-name "internal.domain.tld";<br />
option domain-name-servers 192.168.1.1;<br />
option broadcast-address 192.168.1.255;<br />
default-lease-time 28800;<br />
max-lease-time 43200;<br />
authoritative;<br />
<br />
on commit {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "add", ClientIP, ClientName);<br />
}<br />
<br />
on release {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "delete", ClientIP, ClientName);<br />
}<br />
<br />
on expiry {<br />
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);<br />
set ClientName = pick-first-value(option host-name, host-decl-name);<br />
execute("/etc/dhcpd/update.sh", "delete", ClientIP, ClientName);<br />
}<br />
}<br />
<br />
# End /etc/dhcpd.conf</pre><br />
<br />
Finally, start (or restart) the dhcpd4 service:<br />
<br />
systemctl restart dhcpd4<br />
<br />
==What to do Next==<br />
<br />
If you have made it this far without any unexpected output from the tests above, you are good to go. Congrats!<br />
<br />
Related topics (need additional authors):<br />
<br />
[[OpenChange Server|OpenChange Server]] - The OpenChange project provides a Microsoft Exchange compatible mail server using only open source software.<br />
<br />
Place holder: Samba4_Client_Configuration (including this DC) - Most of the LinuxPAM info in [[Active_Directory_Integration|this article]] can be reused or modified for this purpose.</div>Falcor84