Samba Active Directory Raspberry Pi turns a Pi 4 into a functional domain controller handling LDAP, Kerberos, and DNS for a home lab or small office network. Samba 4 in AD DC mode implements enough of the Active Directory protocol that Windows, Linux, and macOS clients can join the domain, authenticate, and access shared resources. This guide covers OS preparation, static IP configuration on Bookworm, Samba provisioning with the complete command flags, Kerberos testing, user and group management, file sharing, security hardening, and troubleshooting.
Last tested: Raspberry Pi OS Bookworm Lite 64-bit | January 16, 2026 | Raspberry Pi 4 Model B (4GB) | Samba 4.17 | Windows 11 client domain join
Key Takeaways
- Samba AD DC mode runs on Pi 4 and handles authentication, DNS, and LDAP for small networks. It is not a drop-in replacement for a production Windows Server domain, but it is fully functional for labs, classrooms, and small office environments.
- A static IP and working DNS are prerequisites. Kerberos authentication fails if the domain controller’s IP changes or if DNS resolution is unreliable. Set the static IP before provisioning.
- Do not run
smbd,nmbd, andwinbindas separate services when using AD DC mode. Use onlysamba-ad-dc. Running both causes conflicts. - Kerberos requires time synchronisation within 5 minutes between the domain controller and all clients. Install
chronyand make the Pi the NTP source for the network. - Back up
/etc/samba/,/var/lib/samba/, and/etc/krb5.confbefore every Samba update. A failed update without a backup means reprovisioning from scratch. - Group Policy Object support in Samba is partial. Basic machine and user policies work via RSAT. Complex WMI filters and some advanced policies do not function as they would on Windows Server.

How Samba Active Directory Raspberry Pi Works
Active Directory is a suite of services: LDAP for directory storage, Kerberos for authentication, DNS for service location, and SMB for file sharing. Samba 4 implements all four in a single daemon (samba-ad-dc) when provisioned in AD DC mode. Clients query DNS to find the domain controller, authenticate via Kerberos to get a ticket-granting ticket, then present that ticket when accessing resources.
The practical limitations on Pi 4 are throughput and concurrent connection count, not protocol capability. For a lab or a small office with under 20 users the Pi handles the workload comfortably.
Required ports
| Port | Protocol | Service |
|---|---|---|
| 53 | TCP/UDP | DNS |
| 88 | TCP/UDP | Kerberos |
| 135 | TCP | RPC endpoint mapper |
| 139 | TCP | NetBIOS session |
| 389 | TCP/UDP | LDAP |
| 445 | TCP | SMB |
| 636 | TCP | LDAPS |
| 3268 | TCP | Global Catalog LDAP |
| 3269 | TCP | Global Catalog LDAPS |
| 49152-65535 | TCP | RPC dynamic ports |

Hardware Requirements
Pi 4 with 2GB RAM is the minimum practical choice. Pi 4 with 4GB is comfortable for simultaneous domain joins, DNS queries, and file access. Pi 3B+ works but its shared USB/Ethernet bus and 1GB RAM limit performance under concurrent load.
Run the OS from a USB SSD rather than microSD. Samba AD writes frequently to /var/lib/samba/ including Kerberos tickets, DNS records, and LDAP database updates. MicroSD cards are not suitable for this write pattern long-term. See Booting Raspberry Pi from USB SSD. If microSD is unavoidable, see Preventing SD Card Corruption on Raspberry Pi.
Step 1: Prepare the OS
Flash Raspberry Pi OS Bookworm Lite 64-bit using Raspberry Pi Imager. In Imager’s advanced settings, set the hostname to your intended domain controller name (e.g. dc1), enable SSH, and configure credentials. After first boot:
sudo apt update && sudo apt full-upgrade -y
sudo reboot
Set a static IP on Bookworm
Bookworm uses NetworkManager rather than dhcpcd. Set a static IP with nmcli:
# List connections to find the interface name
nmcli connection show
# Set static IP (replace values for your network)
sudo nmcli connection modify "Wired connection 1" \
ipv4.method manual \
ipv4.addresses 192.168.1.10/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns 127.0.0.1 \
ipv4.ignore-auto-dns yes
sudo nmcli connection up "Wired connection 1"
Setting DNS to 127.0.0.1 is intentional. After provisioning, Samba’s internal DNS handles all domain queries from this interface.
Configure /etc/hosts
# /etc/hosts -- example for realm LAB.LOCAL
127.0.0.1 localhost
192.168.1.10 dc1.lab.local dc1
Install Chrony
sudo apt install chrony -y
sudo systemctl enable --now chrony
chronyc tracking
Expected result: chronyc tracking shows the clock synchronised with offset under 1 second. SSH connects to the Pi at its static IP.
Step 2: Install Samba and Disable Standalone Services
sudo apt install samba krb5-config winbind smbclient \
acl attr dnsutils libpam-winbind libnss-winbind -y
During krb5-config installation, enter the realm in uppercase (e.g. LAB.LOCAL) when prompted. Disable and mask the standalone services before provisioning:
sudo systemctl disable --now smbd nmbd winbind
sudo systemctl mask smbd nmbd winbind
# Remove the default smb.conf -- provisioning generates a new one
sudo mv /etc/samba/smb.conf /etc/samba/smb.conf.pre-provision
Expected result: systemctl status smbd shows the service as masked. No errors during package installation.
Step 3: Provision the Samba Active Directory Domain
sudo samba-tool domain provision \
--use-rfc2307 \
--realm=LAB.LOCAL \
--domain=LAB \
--server-role=dc \
--dns-backend=SAMBA_INTERNAL \
--adminpass='YourStr0ngPassword!'
Flag reference:
--use-rfc2307: enables POSIX UID/GID attributes in the directory, required for Linux client integration via winbind.--realm: Kerberos realm in uppercase. Must match/etc/krb5.conf.--domain: NetBIOS name in uppercase, maximum 15 characters.--dns-backend=SAMBA_INTERNAL: uses Samba’s built-in DNS. Simpler than Bind9 for new setups.--adminpass: initial Administrator password. Must meet complexity requirements (uppercase, lowercase, digit, special character).
Copy the generated Kerberos configuration and start the service:
sudo cp /var/lib/samba/private/krb5.conf /etc/krb5.conf
sudo systemctl unmask samba-ad-dc
sudo systemctl enable --now samba-ad-dc
sudo systemctl status samba-ad-dc
Expected result: systemctl status samba-ad-dc shows active and running. No errors in /var/log/samba/log.samba.
Step 4: Verify DNS and Kerberos
DNS verification
# SRV records are required for Windows domain joins
host -t SRV _ldap._tcp.lab.local
host -t SRV _kerberos._udp.lab.local
# A record for the domain controller
host dc1.lab.local
Kerberos verification
kinit administrator@LAB.LOCAL
klist
User and domain verification
wbinfo -u
wbinfo -g
samba-tool domain info 127.0.0.1
Expected result: SRV records return values. kinit succeeds and klist shows a valid ticket. wbinfo -u lists at least Administrator and krbtgt.
Step 5: Manage Users and Groups
# Create a domain user
sudo samba-tool user create jsmith 'P@ssw0rd123' \
--given-name=John \
--surname=Smith \
--mail-address=jsmith@lab.local
# List users
sudo samba-tool user list
# Create a group and add a member
sudo samba-tool group add ITStaff
sudo samba-tool group addmembers ITStaff jsmith
# Add to Domain Admins
sudo samba-tool group addmembers "Domain Admins" jsmith
# Reset a password
sudo samba-tool user setpassword jsmith
Expected result: samba-tool user list shows jsmith. samba-tool group listmembers ITStaff shows jsmith as a member.
Step 6: Configure File Shares
After provisioning, /etc/samba/smb.conf contains the AD DC configuration. Add share sections at the end of the file:
sudo testparm
sudo nano /etc/samba/smb.conf
Append:
[shared]
path = /srv/samba/shared
read only = no
browseable = yes
valid users = @"Domain Users"
create mask = 0664
directory mask = 0775
sudo mkdir -p /srv/samba/shared
sudo chown root:"domain users" /srv/samba/shared
sudo chmod 2775 /srv/samba/shared
sudo systemctl restart samba-ad-dc
# Test from a Linux client
smbclient //dc1.lab.local/shared -U jsmith
Expected result: smbclient connects and lists the share contents after authentication.
Joining Windows Clients to the Domain
On the Windows client, set the preferred DNS server to the Pi’s static IP before joining. Open Settings > System > About > Domain or workgroup, enter LAB.LOCAL, and authenticate as administrator.
Common domain join failure causes: DNS not pointing to the Pi, time drift over 5 minutes, firewall blocking ports 88/389/445, or SRV records missing from Samba’s DNS. Verify with nslookup lab.local on the client and host -t SRV _ldap._tcp.lab.local on the Pi.
DNS Management
# Add a custom A record
sudo samba-tool dns add 127.0.0.1 lab.local printer A 192.168.1.20 \
-U administrator
# List all DNS records
sudo samba-tool dns query 127.0.0.1 lab.local @ ALL -U administrator
# Regenerate AD SRV records if missing
sudo samba_dnsupdate --verbose
Security Hardening
sudo apt install ufw fail2ban -y
sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw allow from 192.168.1.0/24 to any port 53
sudo ufw allow from 192.168.1.0/24 to any port 88
sudo ufw allow from 192.168.1.0/24 to any port 135
sudo ufw allow from 192.168.1.0/24 to any port 139
sudo ufw allow from 192.168.1.0/24 to any port 389
sudo ufw allow from 192.168.1.0/24 to any port 445
sudo ufw allow from 192.168.1.0/24 to any port 636
sudo ufw allow from 192.168.1.0/24 to any port 3268
sudo ufw allow from 192.168.1.0/24 to any port 49152:65535 proto tcp
sudo ufw enable
sudo systemctl enable --now fail2ban
# SSH key auth and disable root login
ssh-copy-id pi@dc1.lab.local
sudo nano /etc/ssh/sshd_config
# Set: PasswordAuthentication no
# Set: PermitRootLogin no
sudo systemctl restart sshd
Backup and Recovery
# Full Samba AD backup
sudo samba-tool domain backup offline \
--targetdir=/mnt/backup/samba-$(date +%Y%m%d)
# Back up key config files
sudo rsync -av /etc/samba/ /mnt/backup/etc-samba/
sudo cp /etc/krb5.conf /mnt/backup/
sudo cp /etc/hosts /mnt/backup/
samba-tool domain backup offline creates a consistent snapshot of the entire Samba database including users, groups, policies, DNS records, and Kerberos keys. To restore on a fresh Pi:
sudo samba-tool domain backup restore \
--backup-file=/mnt/backup/samba-20260116.tar.bz2 \
--newservername=dc1 \
--targetdir=/var/lib/samba
Troubleshooting
kinit fails
chronyc tracking
cat /etc/krb5.conf
# Confirm default_realm = LAB.LOCAL (uppercase)
samba-ad-dc fails to start
sudo systemctl status samba-ad-dc
sudo journalctl -u samba-ad-dc -n 50
sudo testparm
Common causes: smbd or nmbd running and conflicting (ensure they are masked), port 53 in use by systemd-resolved (disable the DNS stub listener), or a syntax error in smb.conf.
Port 53 conflict with systemd-resolved
sudo nano /etc/systemd/resolved.conf
# Set: DNSStubListener=no
sudo systemctl restart systemd-resolved
Windows domain join fails
host -t SRV _ldap._tcp.lab.local
host -t SRV _kerberos._udp.lab.local
samba-tool domain info 127.0.0.1
sudo samba_dnsupdate --verbose
wbinfo -u returns nothing
sudo systemctl status winbind
sudo wbinfo --ping-dc
# Check /etc/nsswitch.conf includes winbind in passwd and group lines
FAQ
Can I use a Raspberry Pi Zero for Samba AD?
Not practically. Pi Zero 2 W has 512MB RAM which is insufficient for the Samba AD DC database and concurrent service load. Pi 3B+ is the minimum and Pi 4 with 2GB or more is recommended.
Does Samba AD support Group Policy?
Partially. Basic machine and user policies are manageable via RSAT from a Windows machine joined to the domain. Complex policies with WMI filters and some Windows-specific extensions may not function correctly. Test each policy before relying on it.
Do I need internet access for Samba AD to function?
No. Once provisioned, the domain runs entirely on the local network. The only external dependency is NTP, which can be replaced with a local time source if internet is unavailable.
Can I run other services on the same Pi as the domain controller?
Possible but not recommended for production. Services competing for port 53 (Pi-hole) or port 445 (other Samba instances) will conflict and require careful separation. Keep the domain controller focused on identity services for reliability.
Is Samba AD secure enough for a small office?
Yes for isolated networks with proper hardening: SSH keys, LAN-restricted firewall rules, fail2ban, and current Samba packages. Do not expose any AD DC ports to the internet.
References
- https://wiki.samba.org/index.php/Setting_up_Samba_as_an_Active_Directory_Domain_Controller
- https://wiki.samba.org/index.php/Samba_AD_DC_HOWTO
- https://www.samba.org/samba/docs/current/man-html/samba-tool.8.html
About the Author
Chuck Wilson has been programming and building with computers since the Tandy 1000 era. His professional background includes CAD drafting, manufacturing line programming, and custom computer design. He runs PidiyLab in retirement, documenting Raspberry Pi and homelab projects that he actually deploys and maintains on real hardware. Every article on this site reflects hands-on testing on specific hardware and OS versions, not theoretical walkthroughs.
Last tested hardware: Raspberry Pi 4 Model B (4GB), USB SSD. Last tested OS: Raspberry Pi OS Bookworm Lite 64-bit. Samba 4.17, Windows 11 client domain join.

