Skip to main content

Active Directory with Open Source for SMBs: The Version That Survives Production (Debian 13)

The biggest myth in commercial IT is that a secure and professional network requires thousands of dollars in servers and unaffordable corporate licensing. It is a lie: with Samba 4 on Debian 13, you can build an Active Directory free of CALs or seat licenses, a centralized file server, automated backups, and a VPN for branch offices and remote work—all running on modest hardware.

However, there is a second myth, which is far more dangerous because it comes disguised as a solution: the tutorials circulating online—often automated translations or copied scripts that nobody bridges to audit—build an architecture that survives the demo but falls apart completely in production. This article is both things at once: a deployment guide to build it right, and a brutal audit of the five critical flaws that cause those "NASA-grade" setups to collapse on their own three weeks later. We measure against official documentation, the Samba Wiki, and the actual behavior of underlying protocols, not against forum folklore.

The Honest Architecture, in One Sentence

Separation of concerns: The Domain Controller authenticates and does nothing else; files live on a Member Server; the clock is a cryptographic requirement, not an ornament; backups have versions and a copy outside the network; and nothing hits production without being verified. Everything else is just a detail of that core concept.

From this point forward, every design choice comes accompanied by the typical error it replaces.


Part 1 — The Five Pervasive Errors (And How to Fix Them)

1. The .local Realm is a Textbook Blunder (mDNS)

Using the .local suffix as the Top-Level Domain (TLD) for an Active Directory realm is the most common first-year mistake. The Samba team explicitly warns against using it because .local is strictly reserved for Avahi/mDNS (Multicast DNS) and local network service discovery. Making your AD domain match .local causes routing resolution collisions and intermittent packet drops.

What makes it fatal is that Samba does not support renaming the AD DNS zone or the Kerberos realm once the domain has been provisioned. If you followed the typical tutorial using COMPANY.LOCAL, there is no possible correction without destroying the domain and starting over from scratch.

  • Do it right: Use a subdomain under your operational control (e.g., ad.company.com.ar) or a dedicated private suffix (e.g., company.internal). Choose it once, and choose it forever.

2. File Server on the DC: The Fragile Monolith

Mounting shared folders directly on the AD/DC is the core of almost every automated script out there, and it is exactly what Samba discourages. The AD/DC must be an isolated node dedicated solely to authentication and authorization (Kerberos/LDAP); shared resources belong on Member Servers joined to the domain.

There is a specific technical detail that exposes this monolithic flaw: setting browseable = yes in the DC's shares does absolutely nothing because smbd operating in Active Directory DC mode does not support network browsing. Furthermore, a DC's smb.conf is autogenerated and special-purpose; injecting shares manually makes it highly fragile across package updates.

# The fragile way: Modifying the smb.conf of the DC itself
[sales]
    path = /srv/samba/sales
    browseable = yes   ; <- smbd in DC mode ignores this directive
    writable = yes
  • Do it right: The DC authenticates; a Member Server (which can be another VM on the same physical hardware) serves the files using real domain ACLs. "Step C" of the manual demonstrates this.

3. Omitting Time Synchronization Kills Kerberos

Failing to configure chrony or an NTP daemon in an AD deployment is leaving a ticking bomb active in your infrastructure. Kerberos relies on timestamps to prevent packet replay attacks: if the time drift between the DC and the client workstation exceeds 5 minutes (the default value), authentication will instantly fail. A demo that "worked flawlessly on day one" collapses weeks later due to the natural drift of hardware clocks.

  • Do it right: Run chrony on the DC tied to a reliable pool, while also serving cryptographically signed time to Windows clients. The configuration is included in the manual below.

4. The rsync --delete Mirror is Not an Anti-Ransomware Backup

This is the widest honesty gap in online sysadmin tutorials. It is common to find scripts promising "total immunity to ransomware" using this crontab entry:

# The script that promises immunity but delivers the opposite
rsync -avz --delete /srv/samba/ /mnt/backup/

The --delete flag completely destroys data resilience. If ransomware encrypts your production shared folders and the cron job runs at 2:00 AM, rsync will faithfully mirror the encrypted files to your backup storage and wipe out the clean versions from the day before. Your backup copy ends up exactly as destroyed as your production environment.

Furthermore, leaving the backup inside /mnt/backup on the same machine violates the basic 3-2-1 rule: an offsite, network-isolated repository is non-negotiable. (Minor detail: using -z in an rsync command targeting a local disk only wastes CPU cycles compressing and decompressing data over the internal bus).

  • Do it right: Use versioned, isolated snapshots. Implement tools like BorgBackup or Restic (with encryption and a remote repository), rsync --link-dest with hard-link rotation, or filesystem-level ZFS/Btrfs snapshots. A real backup must allow you to look at yesterday, not just now.

5. Interactive Commands Stuck in a Blind Cron

To automate the backup of the AD database, you often see this:

samba-tool domain backup online --configfile=/etc/samba/smb.conf

This will fail inside an unattended cron environment. The online mode strictly demands specifying the target server (--server) and admin credentials (-U administrator). At 2:00 AM, the process will hang indefinitely waiting for a password input from the keyboard, or abort due to syntax errors.

  • Do it right: For a local backup running on the DC itself, the correct engine is offline. It dumps the database bases (.ldb/.tdb) utilizing the necessary internal locks without requiring interactive authentication and without bringing the live network service down:
samba-tool domain backup offline --targetdir=/var/backups/samba/ad

If you must insist on using the online mode, it must be explicitly pointed to localhost using a credentials file restricted via chmod 600.

The Production Omissions Nobody Tells You About

  • Role-based permissions that aren't actually role-based: Promising that "Sales can only access the Sales folder" by simply executing chown root:"domain admins" + chmod 770 is flat POSIX. It inherits in block and cannot differentiate between distinct domain groups. To map AD groups natively like a Windows server does, you need vfs objects = acl_xattr, map acl inherit = yes, and access control management via setfacl.
  • Single Point of Failure (SPOF): Nothing dependent on a single DC can be labeled "enterprise-grade." You need a minimum of two DCs, keeping in mind that Samba does not replicate the SysVol share (Group Policies/GPOs) automatically; that must be scripted separately.
  • Real Windows 11 Friction: Promising "absolute plug-and-play compatibility" ignores modern security hardening from Microsoft. Modern Windows 11 builds strictly enforce SMB packet signing and LDAP channel binding. It works beautifully, but it requires precise adjustments; it is never transparent out of the box.

Part 2 — Corrected Technical Manual (Debian 13 "Trixie")

Baseline: Debian 13 Stable (Kernel 6.12 LTS), static IP configuration, and a domain realm chosen for the system's lifetime. In these examples, we utilize ad.company.com.ar (Realm in uppercase: AD.COMPANY.COM.AR) and the DC hostname dc1.ad.company.com.ar.

Step A — Provisioning the Domain Controller

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y samba smbclient krb5-user winbind                     libpam-winbind libnss-winbind acl attr chrony

On the Kerberos configuration prompt, enter the Realm strictly in uppercase: AD.COMPANY.COM.AR.

The most silent deployment bug happens right here. Almost everyone clears out /etc/samba/smb.conf before provisioning but completely forgets to audit /etc/hosts. On a DC, the FQDN and the short hostname must resolve directly to the LAN IP, never to a loopback address. Samba registers its SPNs and DNS records against that interface IP; if the FQDN drops into 127.0.0.1, the controller advertises itself incorrectly and breaks client domain joins.

The issue is that a fresh Debian installation leaves a 127.0.1.1 line mapped to the machine's name by default:

# What Debian leaves by default (YOU MUST DELETE the 127.0.1.1 line)
127.0.0.1     localhost
127.0.1.1     dc1.ad.company.com.ar   dc1   # <- Drags the FQDN into loopback

If you leave that line intact, the FQDN resolves to 127.0.1.1, ruining the provision. The DC's /etc/hosts file must look exactly like this, pointing the FQDN to the real LAN IP:

127.0.0.1     localhost
192.168.1.10  dc1.ad.company.com.ar   dc1

Verify this layout before moving forward. These three commands must return your LAN IP and never a 127.0.x.x address:

hostname -f                          # -> dc1.ad.company.com.ar
getent hosts dc1.ad.company.com.ar   # -> 192.168.1.10
getent hosts dc1                     # -> 192.168.1.10

Wiping and provisioning (the smb.conf file will be cleanly generated by Samba):

sudo systemctl disable --now smbd nmbd winbind
sudo rm -f /etc/samba/smb.conf
sudo samba-tool domain provision --use-rfc2307 --interactive
# Realm: AD.COMPANY.COM.AR | Domain: COMPANY | Role: dc
# DNS backend: SAMBA_INTERNAL | Forwarder: 1.1.1.1

sudo ln -sf /var/lib/samba/private/krb5.conf /etc/krb5.conf
sudo systemctl unmask samba-ad-dc
sudo systemctl enable --now samba-ad-dc
kinit administrator@AD.COMPANY.COM.AR && klist

The DC must use itself as its primary DNS resolver. Disable any service that rewrites resolv.conf and point it strictly to nameserver 192.168.1.10.

Step B — Signed Clock (Chrony on the DC)

Without this layer, everything built above will collapse within weeks. Edit /etc/chrony/chrony.conf:

pool 2.debian.pool.ntp.org iburst
ntpsigndsocket /var/lib/samba/ntp_signd
allow 192.168.1.0/24
sudo systemctl restart chrony
# Allow chrony to sign the time packets for domain clients
sudo setfacl -m u:_chrony:rx /var/lib/samba/ntp_signd

Step C — File Server on a Dedicated Member Server (Not on the DC)

On an isolated machine (or a separate VM on the same physical host) joined to the domain running security = ads and winbind. The member server's baseline smb.conf requires:

[global]
    workgroup = COMPANY
    realm = AD.COMPANY.COM.AR
    security = ads
    winbind use default domain = yes
    template shell = /bin/bash
    idmap config * : backend = tdb
    idmap config * : range = 3000-7999
    idmap config COMPANY : backend = rid
    idmap config COMPANY : range = 10000-999999
    vfs objects = acl_xattr
    map acl inherit = yes
    store dos attributes = yes

[sales]
    path = /srv/samba/sales
    read only = no
sudo net ads join -U administrator
sudo systemctl enable --now smbd winbind
# nsswitch.conf: remember to append 'winbind' to passwd and group lines

Now, map actual domain groups using extended POSIX ACLs:

sudo mkdir -p /srv/samba/sales
sudo setfacl -m "g:COMPANY\sales:rwx" /srv/samba/sales
sudo setfacl -m "g:COMPANY\management:rwx" /srv/samba/authorizations

Step D — Versioned, Automated, Offsite Backup Strategy

We split the architecture into two independent backup routines: the AD database base (on the DC via offline mode) and the live shared directories (on the member server using versions). BorgBackup provides compression, deduplication, and encrypted remote transfers out of the box.

#!/bin/bash
# /usr/local/bin/backup_ad.sh (On the DC, chmod 700)
set -euo pipefail
DEST="/var/backups/samba/ad"
mkdir -p "$DEST"
samba-tool domain backup offline --targetdir="$DEST"
# Retention policy: purge files older than 14 days
find "$DEST" -name 'samba-backup-*.tar.bz2' -mtime +14 -delete
#!/bin/bash
# /usr/local/bin/backup_files.sh (On the Member Server, chmod 700)
set -euo pipefail
export BORG_PASSPHRASE='your_secure_passphrase_here' # Better: BORG_PASSCOMMAND pointing to a local secret file
REPO='ssh://backup@offsite.company.com.ar/~/borg-pyme'
borg create --compression zstd "$REPO::{hostname}-{now}" /srv/samba
borg prune "$REPO" --keep-daily=7 --keep-weekly=4 --keep-monthly=6

System Crontab Scheduling (sudo crontab -e):

0 2 * * * /usr/local/bin/backup_ad.sh    >> /var/log/backup_ad.log    2>&1
30 2 * * * /usr/local/bin/backup_files.sh >> /var/log/backup_files.log 2>&1

This strategy withstands ransomware attacks: the Borg repository is offsite, encrypted, and holds historical snapshots. If production files are encrypted on a Friday, you simply restore Thursday's clean snapshot.

Step E — VPN for Remote Work and Branches (WireGuard)

WireGuard is natively integrated into the Debian 13 Linux kernel. On your perimeter gateway node:

# /etc/wireguard/wg0.conf
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>

[Peer]                 # Remote employee or branch node
PublicKey  = <peer_public_key>
AllowedIPs = 10.10.0.2/32
sudo ufw allow 51820/udp
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wg.conf && sudo sysctl --system
sudo systemctl enable --now wg-quick@wg0

Domain access privileges seamlessly follow users across the tunnel: the management share is visible only to management personnel, whether they are working at their office desks or connecting from home. For graphical, user-friendly gateway orchestration, hardware like a MikroTik (running native WireGuard in RouterOS), a UniFi/Omada gateway, or a TP-Link Deco cluster can terminate the exact same tunnel with less overhead.

Step F — Deserving the Title

To truly call a setup enterprise-grade, you must implement a strict firewall configuration (nftables/ufw) on the DC, explicitly disable legacy SMB1 protocols, configure hardware array alerts via smartd and mdadm --monitor, and provision a second DC joined to the domain via samba-tool domain join. Remember to synchronize the SysVol directories manually via an automated tool like csync2 over SSH, as Samba does not replicate it natively.


Realistic Cost Analysis vs. Overblown Marketing

For an environment with 10 to 20 employees, the baseline server can be a refurbished workstation with a high-efficiency power supply, a small SSD for the operating system, and a pair of enterprise HDD drives configured in a mirror array (RAID) for hardware redundancy. This costs less than USD 500 in physical components and absolutely zero in recurring licensing fees.

Let us be completely honest with the wording, though: this is not "NASA-grade certification"; it is solid, reproducible engineering for a local SMB. Magical, indestructible systems do not exist. True infrastructure resilience isn't achieved by copying flashy scripts off internet forums; it is built by separating server roles, enforcing cryptographically signed time protocols, and operating under the assumption that disks will fail and users will make mistakes. A RAID array provides continuity against a dead physical disk—it is not, and never will be, a replacement for a versioned backup system. When an organization scales up, this identical structural design grows predictably by adding managed switches, isolated VLANs, and professional routing.


Conclusion

Deploying Active Directory using open-source software is a highly viable, high-performance corporate solution, but it leaves zero room for superficial configurations. True system uptime isn't proven by flashy setups that shatter on the first package update or security incident; it is proven by reading the documentation, isolating server tasks, locking down fundamental protocols, and planning your backups for the absolute worst-case scenario. The ultimate reward isn't merely "having a server online"—it is keeping your data unified, structured, and entirely safe. Only then do you possess a solid baseline upon which to build, including data analytics or any AI layers you choose to deploy downstream. Control your infrastructure, audit your plain-text configuration files, and never push a single line to production that you haven't verified yourself.

A note on sources: These design choices are verified directly against official Samba upstream documentation (The SambaWiki deployment guides and core FAQs), the Ubuntu Server active directory reference manuals, and the stable release notes of Debian 13. The mapped idmap boundaries, group naming conventions, and file paths used here are illustrative: adapt and verify them against your isolated staging environment before applying them to a live production network.

Comments

Popular posts from this blog

How To Configure Nginx as a Web Server and Reverse Proxy for Apache on One Ubuntu 16.04 Server

Introduction Apache and Nginx are two popular open source web servers often used with PHP. It can be useful to run both of them on the same virtual machine when hosting multiple websites which have varied requirements. The general solution for running two web servers on a single system is to either use multiple IP addresses or different port numbers. Droplets which have both IPv4 and IPv6 addresses can be configured to serve Apache sites on one protocol and Nginx sites on the other, but this isn't currently practical, as IPv6 adoption by ISPs is still not widespread. Having a different port number like 81 or 8080 for the second web server is another solution, but sharing URLs with port numbers (such as http://example.com:81 ) isn't always reasonable or ideal. This tutorial will show you how to configure Nginx as both a web server and as a reverse proxy for Apache – all on one Droplet. Depending on the web application, code changes might be required to keep Apache rev...

How to Tame the Brother 161xNW Over the Network Without Losing Your Mind

  The Definitive Arch Linux/CachyOS Guide Some hardware feels like it was designed to test the patience of Linux users. The Brother DCP-1610NW —and its close relatives in the 161x family— fits perfectly into that category. It is a monochrome laser multifunction printer: cheap to run, physically tough, reliable, and clearly built more like a small office tank than a delicate modern gadget. The problem is not the printer. The problem is making it work cleanly on Arch Linux or CachyOS over the network, especially when we want both sides of the device to behave properly: the printer and the scanner. The traditional instinct is to go straight to Brother’s official Linux drivers, hunt for old .deb or .rpm packages, look for AUR wrappers, and start installing model-specific packages until something works. That path exists. But on my system, it was not the right first move. The cleaner solution was this: CUPS + brlaser for printing. SANE + sane-airscan + Skanlite for scanning. No driver ...

Backups with rclone: Synchronizing Without Making Life Complicated

A simple strategy to avoid losing your work environment One of the most common mistakes in computing is remembering backups only when it is already too late. When the disk fails. When an update breaks something. When we accidentally delete a folder. When a laptop stops booting. When that “temporary” file turns out to be important. In the world of development and system administration, we usually spend a lot of time fine-tuning our environment: configurations, scripts, keys, projects, documents, dotfiles, profiles, tools, notes, and small adjustments that make a machine truly ours. The problem is that, many times, all of that lives in only one place. And if that place fails, we lose much more than files: we lose time. Backup as a habit, not as an event A backup should not be a heroic task we perform once every six months. It should be something simple, repeatable, and easy to run. That is where rclone becomes a very interesting tool. rclone allows you to synchronize files between a lo...