Installing Samba4 As An Active Directory Domain Controller On CentOS 6
— ny_wk
Setting up a Samba4 Active Directory Domain Controller lets a Linux server provide the same domain logon, group policy, and authentication services as a Windows Server, with full interoperability against real Microsoft Active Directory. This guide walks through provisioning a Samba AD DC end to end, choosing the right DNS backend, wiring up Kerberos and NTP, opening the firewall, and verifying the domain actually works.
Samba 4 introduced a single master daemon that coordinates everything an AD domain needs: an LDAP directory, a Kerberos KDC, dynamic DNS, and the RPC services Windows clients expect. When the box runs as a domain controller you start one binary (samba) rather than the old smbd, nmbd, and winbindd trio, and you administer the whole domain with samba-tool.
The Problem: A Windows-Compatible Domain on Linux
Plenty of small networks need real Active Directory features - centralized user accounts, Kerberos single sign-on, machine join, and a proper DNS namespace - but cannot or will not pay for Windows Server Datacenter licenses. A Samba4 Active Directory Domain Controller solves this by speaking the native AD protocols, so Windows 10/11 and Windows Server members join it exactly as they would a Microsoft DC, and you can manage it with the standard Remote Server Administration Tools (RSAT).
The catch is that AD is not one service - it is a tightly coupled stack of LDAP, Kerberos, DNS, NTP, and RPC. Get any one of them wrong and clients fail to join, time skew breaks Kerberos tickets, or dynamic DNS records never appear. The rest of this guide builds that stack in the correct order.
A note on versions before you start
The original procedure targeted CentOS 6 and a hand-compiled samba-4.1.0 tarball. CentOS 6 reached end of life on 30 November 2020 and should never run a production directory today. The concepts below are identical on modern systems, but on current platforms you should:
- Use AlmaLinux 9 / Rocky Linux 9, RHEL 9, Debian 12, or Ubuntu 22.04+ instead of CentOS 6.
- Install Samba from the distribution packages (
dnf install samba samba-dc samba-client krb5-workstation bind9 bind9-utilson RHEL-family;apt install samba smbclient krb5-config winbindon Debian/Ubuntu) rather than compiling, so security updates arrive through the package manager. - Manage the firewall with firewalld (
firewall-cmd) or ufw rather than rawiptables, and manage services with systemd (systemctl) rather thanservice/chkconfig. - Use chrony for time sync on modern releases; classic
ntpdstill works but chrony is the default.
The provisioning logic - samba-tool domain provision, the DNS backend choice, the Kerberos config, the port list - has not changed in spirit since Samba 4.1, so this remains an accurate mental model even when you run a current release.
Prerequisites for the Samba4 AD Domain Controller
Before provisioning, lock down a few host basics. A clean, static, well-named host prevents 90% of join failures.
- Static IP address. A domain controller must never use DHCP. In this guide the server is
192.168.1.100. - A fully qualified hostname. Set the host to something like
ad.orange.comand make surehostname -freturns it. The DNS domain used here is orange.com with NetBIOS name ORANGE. - SELinux relaxed or properly policy-tuned. The classic shortcut is to disable it; on production you are better off keeping it enforcing and applying the correct booleans, but disabling removes a whole class of confusing failures while you learn.
- No conflicting DNS or Samba already running. Stop any existing
smbd/nmbd; the DC uses the singlesambadaemon instead.
To disable SELinux (CentOS/RHEL family), edit the config and reboot:
vi /etc/selinux/config → set SELINUX=disabled
Install the dependency stack. On the legacy CentOS 6 build this was a compile toolchain plus Kerberos, BIND, and NTP:
yum -y install gcc make wget python-devel gnutls-devel openssl-devel libacl-devel krb5-server krb5-libs krb5-workstation bind bind-libs bind-utils ntp
On a modern RHEL 9 / AlmaLinux 9 host, skip the compiler and install the packaged daemon instead:
dnf -y install samba samba-dc samba-client krb5-workstation bind bind-utils chrony
Step-by-Step: Provisioning the Samba4 Domain Controller
Work through these in order. The numbering matters because Kerberos depends on time, DNS depends on the provision, and clients depend on all of it.
- Configure time synchronization (NTP). Active Directory will reject Kerberos tickets if the client and DC clocks differ by more than five minutes, so accurate time is mandatory. With classic
ntpd, edit/etc/ntp.confand enable the local clock as a fallback stratum:server 127.127.1.0 # local clockfudge 127.127.1.0 stratum 10
On modern systems use chrony and let it sync to upstream pool servers; the DC then serves time to domain members on UDP 123. - (Legacy only) Download and compile Samba 4. The original walkthrough pulled the source tarball and built it under
/usr/local/samba:wget https://download.samba.org/pub/samba/stable/samba-4.1.0.tar.gztar -xvzf samba-4.1.0.tar.gz && cd samba-4.1.0./configure --enable-selftest --enable-debugmake && make install
On any current distribution this whole step is replaced by the singlednf/aptinstall above, and the binaries live in/usr/bininstead of/usr/local/samba/bin. Use the packaged paths going forward. - Provision the domain with samba-tool. This is the heart of the process. It builds the LDAP database (sam.ldb), the Kerberos realm, the schema, the well-known security principals, and the DNS partitions in one pass:
samba-tool domain provision --use-rfc2307 --interactive
Answer the prompts:
| Prompt | Value used here |
| Realm | ORANGE.COM (all caps) |
| Domain | ORANGE |
| Server Role | dc |
| DNS backend | BIND9_DLZ (or SAMBA_INTERNAL) |
| DNS forwarder IP | your upstream resolver, or none |
| Administrator password | a strong, complex password |
The Administrator password must meet AD complexity rules (length plus mixed case, digits, or symbols) or the provision aborts. On success, samba-tool prints a summary block confirming the server role is active directory domain controller along with the DNS domain, NetBIOS name, and a generated DOMAIN SID. It also writes a ready-to-use Kerberos config to /usr/local/samba/private/krb5.conf (packaged builds use /var/lib/samba/private/krb5.conf).
Choosing your DNS backend: SAMBA_INTERNAL vs BIND9_DLZ
The provisioner asks which DNS backend to use, and this is the single most consequential choice in the build.
- SAMBA_INTERNAL - Samba's own built-in DNS server. Zero extra configuration, perfect for labs and small domains. This is the recommended default for most deployments today.
- BIND9_DLZ - real ISC BIND acting as the DNS server, reading AD zone data live from Samba through the Dynamically Loadable Zone module. Choose this when you need BIND's advanced features (views, complex forwarding, DNSSEC). BIND must be installed on the same host as Samba.
If you pick BIND9_DLZ, finish the DNS wiring. Generate an rndc key and point named.conf at Samba's DLZ include and the DNS keytab created during provisioning:
rndc-confgen -a -r /dev/urandom (writes /etc/rndc.key)
Then add to the options { } block of /etc/named.conf:
listen-on port 53 { 192.168.1.100; };allow-query { any; };tkey-gssapi-keytab "/usr/local/samba/private/dns.keytab";
And include Samba's generated zone config plus the key file:
include "/usr/local/samba/private/named.conf";include "/etc/rndc.key";
On packaged installs the include path is typically /var/lib/samba/bind-dns/named.conf; check the exact path your samba-tool reported.
Wiring Up Resolver, Kerberos, and Permissions
The domain controller must resolve its own DNS. Point the resolver at the local Samba/BIND service so AD records (SRV records for Kerberos and LDAP especially) resolve correctly.
Edit /etc/resolv.conf:
domain orange.comnameserver 192.168.1.100
Install the Kerberos client config that provisioning generated, so kinit and Windows clients use the right realm and KDC discovery:
cp /usr/local/samba/private/krb5.conf /etc/krb5.conf
Confirm the key directives in /etc/krb5.conf:
default_realm = ORANGE.COM(all caps - realms are case sensitive)dns_lookup_realm = falsedns_lookup_kdc = true
When using BIND9_DLZ, the named user needs read access to the DNS keytab and the krb5 config, otherwise dynamic DNS updates silently fail:
chgrp named /etc/krb5.confchown named:named /usr/local/samba/private/dnschown named:named /usr/local/samba/private/dns.keytabchmod 775 /usr/local/samba/private/dns
Starting the Samba4 AD DC Services
On a hand-compiled CentOS 6 box you wrote a SysV init script in /etc/init.d/samba4 that simply launched /usr/local/samba/sbin/samba on start and ran killall samba on stop, then made it executable with chmod 755 /etc/init.d/samba4 and registered it with chkconfig.
On any modern packaged install you do not write init scripts at all - systemd already ships the units. Enable and start everything:
- SAMBA_INTERNAL DNS:
systemctl enable --now samba(the unit is sometimes namedsamba-ad-dc) - BIND9_DLZ DNS: also
systemctl enable --now named - Time:
systemctl enable --now chronyd(orntpdon legacy)
If your distribution masks the AD DC unit by default (Debian/Ubuntu do this so the smbd stack does not clash), unmask it first: systemctl unmask samba-ad-dc, and make sure smbd, nmbd, and winbind are disabled because the DC daemon includes them.
For reference, the legacy commands were chkconfig samba4 on / chkconfig named on / chkconfig ntpd on followed by service samba4 start. Note the original post's service named on / service samba4 on lines were typos - the correct verb is start.
Opening the Firewall for Active Directory
Active Directory uses a wide spread of ports. If the firewall is active and these are closed, domain join and authentication fail in ways that look like DNS problems. The modern way is firewalld:
firewall-cmd --permanent --add-service={dns,kerberos,kpasswd,ldap,ldaps,samba,samba-dc} && firewall-cmd --reload
The classic iptables approach opened each port explicitly, scoped to the LAN subnet. Here are the ports an AD DC needs and what each one does:
| Port | Proto | Service |
| 53 | TCP/UDP | DNS (Domain Name System) |
| 88 | TCP/UDP | Kerberos authentication |
| 123 | UDP | NTP time sync |
| 135 | TCP | RPC endpoint mapper |
| 137-139 | TCP/UDP | NetBIOS name, datagram, session |
| 389 | TCP/UDP | LDAP |
| 445 | TCP | SMB / CIFS |
| 464 | TCP/UDP | Kerberos password change (kpasswd) |
| 636 | TCP | LDAPS (LDAP over SSL) |
| 3268-3269 | TCP | LDAP Global Catalog (and GC over SSL) |
| 1024-5000 | TCP | Dynamic RPC port range |
One correction from the legacy guide: port 3269 is TCP (Global Catalog over SSL), not UDP, and Kerberos (88) and kpasswd (464) need both TCP and UDP. After editing iptables on a legacy box you would persist the rules with service iptables save; with firewalld the --permanent flag handles persistence.
Verification: Confirm the Domain Controller Actually Works
Never trust a DC until you have tested authentication, DNS, and Kerberos. Run these checks before joining a single client.
- Check the Samba version and build.
samba --versionconfirms the daemon runs. The legacy init script usedsamba --show-buildfor the same purpose. - Validate AD DNS records. The SRV record for Kerberos must resolve:
host -t SRV _kerberos._udp.orange.comhost -t SRV _ldap._tcp.orange.comhost -t A ad.orange.com
All three must return answers pointing at your DC. - Test Kerberos. Request a ticket as the domain administrator:
kinit administrator@ORANGE.COM
thenklistto confirm a valid TGT was issued. The realm must be uppercase. - Test SMB and the directory.
smbclient -L localhost -U administratorshould list the netlogon and sysvol shares - their presence proves the DC provisioned correctly. - List directory objects.
samba-tool user listandsamba-tool group listconfirm the SAM database is populated and queryable.
Raise the domain and forest functional level
By default the provision targets an older functional level. To unlock newer features you can raise it (2008 R2 was the common target on Samba 4.1; modern Samba supports higher):
samba-tool domain level raise --domain-level 2008_R2 --forest-level 2008_R2
Verify the result with samba-tool domain level show, which prints the forest level, domain level, and the lowest level of any DC in the domain.
Common Pitfalls When Building a Samba4 Domain Controller
These are the failures that consume the most troubleshooting time. Watch for them.
- Clock skew. Kerberos breaks the moment client and DC drift more than five minutes apart. Verify chrony/ntpd is actually synced (
chronyc tracking) - this masquerades as a password or DNS error. - resolv.conf pointing elsewhere. If the DC resolves DNS through your router or a public resolver instead of itself, AD SRV records never resolve and clients cannot find the domain. Point it at the DC's own IP, and on systemd-managed hosts protect the file from being overwritten by NetworkManager.
- Weak Administrator password. The provision silently refuses passwords that miss AD complexity rules. Use length plus mixed character classes.
- Running smbd/nmbd alongside the DC. The AD DC daemon is self-contained. Leaving the file-server daemons enabled causes port conflicts on 139/445 - disable them.
- Wrong DNS keytab permissions (BIND9_DLZ). If
namedcannot readdns.keytab, dynamic updates fail. Run the troubleshooter:samba_dnsupdate --verbose --all-namesto see exactly which record updates error out. - Firewall closed on a single AD port. Missing 464 or 3268 breaks password changes or Global Catalog lookups while everything else seems fine. Open the full port set.
Joining a Windows Client to the Samba4 Domain
Once verification passes, joining a Windows PC is straightforward. On the client, set its primary DNS server to the Samba DC's IP (192.168.1.100), then go to System > Domain or workgroup > Change, select Domain, and enter orange.com. Authenticate with administrator and the password you set during provisioning, then reboot. Manage users, groups, and group policy afterwards with the Windows RSAT tools pointed at the DC, exactly as you would with a Microsoft domain controller.
Key Takeaways
- A Samba4 Active Directory Domain Controller delivers native AD logon, Kerberos, LDAP, and DNS on Linux with full Windows interoperability, driven by the single
sambadaemon and managed withsamba-tool. - The build order matters: time sync, then
samba-tool domain provision, then DNS backend, then Kerberos and resolver config, then services and firewall. - Pick SAMBA_INTERNAL DNS for simplicity or BIND9_DLZ when you need full BIND features; BIND must run on the same host and needs keytab permissions set.
- CentOS 6 and hand-compiled Samba are obsolete - use AlmaLinux/Rocky/RHEL 9, Debian 12, or Ubuntu 22.04+, packaged Samba, systemd, and firewalld.
- Always verify with
kinit, SRV record lookups, andsmbclient -Lbefore joining clients; most failures trace back to clock skew, resolv.conf, or a closed firewall port.
Frequently Asked Questions
Can Samba4 fully replace a Windows Server domain controller?
For most use cases, yes. A Samba4 AD DC provides domain join, Kerberos single sign-on, LDAP, group policy, and dynamic DNS, and Windows clients treat it like a native DC. The main gaps are around very recent AD schema features and some Microsoft-specific tooling, so mixed environments often run Samba alongside at least one Windows DC.
Should I use SAMBA_INTERNAL or BIND9_DLZ for DNS?
Use SAMBA_INTERNAL for labs and small or medium domains - it needs zero extra setup and handles AD dynamic DNS automatically. Choose BIND9_DLZ only when you need BIND's advanced capabilities such as views, complex forwarding, or DNSSEC, and remember BIND must be installed on the same server with the DNS keytab readable by the named user.
Why does my Windows client fail to join the Samba domain?
The three usual causes are: the client's DNS is not pointed at the DC (so it cannot find AD SRV records), clock skew greater than five minutes breaking Kerberos, or a firewall blocking a required port like 88, 389, 445, or 464. Verify DNS resolution of _ldap._tcp.<domain>, check time sync on both ends, and confirm the full AD port set is open.
Is it safe to disable SELinux on a Samba domain controller?
Disabling SELinux removes a class of confusing permission errors while learning, which is why many guides suggest it. For production, keep SELinux enforcing and apply the correct Samba booleans and contexts instead, since a domain controller is high-value infrastructure that benefits from mandatory access control.
If you found this build guide useful, subscribe to our YouTube channel @explorenystream for more hands-on Linux and sysadmin walkthroughs.