Installation on Debian 13
Samba 4 AD Domain Controller on Debian 13
This expects a freshly installed Debian 13 (trixie) VM. Not an LXC container. Debian 13 ships Samba 4.22, which supports AD functional level 2016.
What you need
Decide on hostname, domain and IP before you start. Changing any of them after provisioning means starting over.
This guide uses:
| Item | Value |
|---|---|
| Hostname | srv-dc01 |
| DNS domain (realm) | samba-test.lan |
| NetBIOS domain | SAMBA-TEST |
| IP / prefix | 10.0.0.5/20 |
| Gateway | 10.0.0.254 |
| Upstream DNS | 10.0.0.254 |
NetBIOS domain names are limited to 15 characters. Hyphens are allowed.
1. Preparation
Updates
apt update
apt full-upgrade -y
Core dependencies
apt install -y chrony vim ethtool
Hostname
hostnamectl set-hostname srv-dc01
Configure /etc/hosts. Remove the Debian default 127.0.1.1 line — the FQDN
must resolve to the real IP:
127.0.0.1 localhost
10.0.0.5 srv-dc01.samba-test.lan srv-dc01
Verify:
hostname -f
Must return srv-dc01.samba-test.lan. If it does not, provisioning will fail.
Network
Modify /etc/network/interfaces.
Interface
ens18might be named differently for you.
auto ens18
iface ens18 inet static
address 10.0.0.5/20
gateway 10.0.0.254
Time synchronisation
systemctl enable --now chrony
chronyc tracking
Kerberos tolerates a clock skew of ±5 minutes. Aim for an offset well under 5 seconds — anything larger means chrony has not converged yet.
Signed NTP for Windows clients is configured later (section 7), because the socket directory does not exist until after provisioning.
Disable systemd-resolved
Samba's internal DNS server needs port 53.
systemctl disable --now systemd-resolved
rm -f /etc/resolv.conf
Create /etc/resolv.conf:
For provisioning, point
nameserverat your router or firewall soaptkeeps working. It is switched to the DC itself in section 5.
nameserver 10.0.0.254
search samba-test.lan
Ensure nothing is listening on port 53:
ss -tlnp | grep :53
This must return nothing.
2. Install Samba
apt install -y acl attr samba winbind libpam-winbind libnss-winbind \
krb5-config krb5-user dnsutils python3-setproctitle samba-ad-dc
krb5-config prompts during installation:
- Default Kerberos version 5 realm:
SAMBA-TEST.LAN(uppercase) - Kerberos servers for your realm:
srv-dc01.samba-test.lan - Administrative server for your realm:
srv-dc01.samba-test.lan
These values are transient — /etc/krb5.conf is replaced in section 5.
Verify the AD DC modules are present:
dpkg -l samba-dsdb-modules samba-vfs-modules
samba -V
Without samba-dsdb-modules the DC will not start.
Mask conflicting services
Debian starts smbd, nmbd and winbind as standalone services immediately
after installation. On an AD DC these must not run — the samba process
provides its own internal file server and winbind. Leaving them active causes
samba-dcerpcd to crash-loop and NSS lookups to hang.
systemctl disable --now smbd nmbd winbind
systemctl mask smbd nmbd winbind
3. Domain provisioning
Remove the packaged configuration file:
rm -f /etc/samba/smb.conf
Choose one of the two variants below.
Variant A — default functional level (2008 R2)
Conservative, fully supported, matches most existing Samba deployments.
samba-tool domain provision --use-rfc2307 --realm=SAMBA-TEST.LAN \
--domain=SAMBA-TEST --server-role=dc --dns-backend=SAMBA_INTERNAL \
--adminpass='ChangeMe123!'
Variant B — functional level 2016
Required if the domain this DC will eventually replace runs at FL 2012 R2 or 2016, and needed for Kerberos claims, authentication policies and authentication silos.
samba-tool domain provision --use-rfc2307 --realm=SAMBA-TEST.LAN \
--domain=SAMBA-TEST --server-role=dc --dns-backend=SAMBA_INTERNAL \
--adminpass='ChangeMe123!' \
--function-level=2016 \
--option="ad dc functional level = 2016"
The --option only applies during provisioning. It must also be written
permanently into smb.conf (section 5) — on every DC in the domain.
Caveats for FL 2016. Samba's implementation is partial and not enabled by default. Samba reads and writes claims and populates them into the PAC, but does not yet use them for access control decisions. Microsoft's PowerShell based AD tools are not expected to work. Functional levels cannot be lowered again.
If you omit
--adminpass, a random password is generated and printed to the console in cleartext, where it lands in your scrollback and terminal logs.
4. Deploy Kerberos configuration
cp /var/lib/samba/private/krb5.conf /etc/krb5.conf
Copy the file — do not symlink it.
5. Configure DNS and smb.conf
Point the resolver at the DC itself. Rewrite /etc/resolv.conf:
nameserver 10.0.0.5
search samba-test.lan
Add the following to the existing [global] section of
/etc/samba/smb.conf — do not create a second [global] block:
dns forwarder = 10.0.0.254
# Variant B only — must be present on every DC
ad dc functional level = 2016
On first startup, ad dc functional level updates the server's own AD entry
with the configured level.
Check the file parses:
testparm -s
6. Start Samba
systemctl unmask samba-ad-dc
systemctl enable --now samba-ad-dc
systemctl status samba-ad-dc
If the service fails to start, the two usual causes are a port 53 conflict
(check ss -tlnp | grep :53) and server role not being set to
active directory domain controller in smb.conf.
7. Post-provisioning tasks
Set the domain administrator password
samba-tool user setpassword Administrator
Review the password policy
samba-tool domain passwordsettings show
Samba defaults to a maximum password age of 43 days. In a lab this will expire on you at the worst possible moment:
samba-tool domain passwordsettings set --max-pwd-age=0
Do not do this in production — use the policy your organisation requires.
Verify sysvol ACLs
samba-tool ntacl sysvolcheck
If it reports errors:
samba-tool ntacl sysvolreset
Create the reverse DNS zone
Provisioning does not create one.
samba-tool dns zonecreate srv-dc01 0.0.10.in-addr.arpa -U Administrator
A
/20network spans10.0.0.xthrough10.0.15.x. Either create all 16 zones or use10.in-addr.arpainstead.
Signed NTP for Windows clients
The socket directory exists only after provisioning:
chgrp _chrony /var/lib/samba/ntp_signd
chmod 750 /var/lib/samba/ntp_signd
Add to /etc/chrony/chrony.conf:
ntpsigndsocket /var/lib/samba/ntp_signd
allow 10.0.0.0/20
systemctl restart chrony
Take a snapshot
Snapshot the VM here — freshly provisioned, no clients joined. Domain join tests can then be repeated from a known state.
8. Verification
Services and listeners
ss -tlnp | grep -E ':(53|88|389|445|464|636)\b'
smbclient -L localhost -N
Expected listeners: 53 (DNS), 88 (Kerberos), 389 (LDAP), 445 (SMB),
464 (kpasswd), 636 (LDAPS). smbclient must show the netlogon and sysvol
shares.
DNS records
host -t SRV _ldap._tcp.samba-test.lan localhost
host -t SRV _kerberos._udp.samba-test.lan localhost
host -t A srv-dc01.samba-test.lan localhost
Repeat from another host on the network — this is what clients actually do:
host -t SRV _ldap._tcp.samba-test.lan 10.0.0.5
Kerberos
kinit administrator@SAMBA-TEST.LAN
klist
The ticket must show realm SAMBA-TEST.LAN.
Directory consistency
samba-tool dbcheck --cross-ncs
getent passwd administrator
getent proves NSS resolution through the internal winbind works.
Functional level
samba-tool domain level show
Variant A reports (Windows) 2008 R2, Variant B reports (Windows) 2016.
9. Raising an existing domain from 2008 R2 to 2016
Only needed if you provisioned with Variant A and now need a higher level.
Functional levels cannot be lowered. Take a backup and verify it before starting.
Back up first
samba-tool domain backup offline --targetdir=/srv/backup
samba-tool dbcheck --cross-ncs
Enable the feature
Add to the [global] section of /etc/samba/smb.conf on every DC:
ad dc functional level = 2016
Restart Samba on every DC:
systemctl restart samba-ad-dc
Upgrade schema and raise the level
samba-tool domain schemaupgrade --schema=2019
samba-tool domain functionalprep --function-level=2016
samba-tool domain level raise --domain-level=2016 --forest-level=2016
Verify
samba-tool domain level show
samba-tool dbcheck --cross-ncs
10. Domain join test
On the Windows client, set the DC as the only DNS server — not the router, not a public resolver. This is the cause of most "domain could not be contacted" errors.
After joining, confirm from the DC:
samba-tool computer list
samba-tool user list
11. Before going to production
- Backups.
samba-tool domain backup offlineon a schedule, plus a tested restore. A DC without a verified restore path is not a DC you can rely on. - Second DC. Join a second controller and verify replication with
samba-tool drs showrepl. - sysvol replication. Samba does not replicate sysvol between DCs. This has to be built separately with rsync or osync. This surprises people migrating from Windows AD with DFS-R.
- Monitoring. Add LDAP, Kerberos and DNS service checks plus
samba-tool drs showreplto your monitoring. - FSMO roles. When replacing an existing DC, transfer the roles with
samba-tool fsmo transferbefore demoting the old one.