• HWIKI

    Build. Break. Explain.

    Deploying Samba AD-DC on Debian 12

    I've wanted a centralized way to manage users and permissions across my network. While Windows Server is the industry standard, I prefer staying in the Open Source ecosystem. Samba AD-DC fits that need while also being significantly lighter on system resources.

    What is Samba AD-DC?

    Samba is not just for simple file sharing. When configured as an Active Directory Domain Controller (AD-DC), it replicates the behavior of a Windows Server—specifically matching functional levels between 2008 R2 and 2012 R2. It provides DNS, Kerberos authentication, and LDAP services.

    In fact, this setup is robust enough that ANSSI (the French National Cybersecurity Agency) has provided security recommendations for it, proving it's a serious alternative for managing identities securely.

    Deployement

    > I decided to run this inside a Virtual Machine (VM) rather than a container. Samba has some historical friction with ZFS, and since my Proxmox containers use ZFS, a VM with a standard ext4 filesystem is much more stable for this use case.

    Installing Dependencies

    The official Debian repositories often carry older versions of Samba. To get the latest features, I download the source directly.

    First, I set the frontend to non-interactive to avoid annoying pop-up prompts, then I grab the massive list of dependencies required for a full AD-DC build:

    bash
    export DEBIAN_FRONTEND=noninteractive
    
    apt update && apt install -y acl apt-utils attr autoconf bind9utils binutils bison build-essential \
    chrpath curl debhelper dnsutils docbook-xml docbook-xsl flex gcc gdb git glusterfs-common \
    gzip heimdal-multidev hostname htop krb5-config krb5-user krb5-kdc lcov libacl1-dev \
    libarchive-dev libattr1-dev libavahi-common-dev libblkid-dev libbsd-dev libcap-dev \
    libcephfs-dev libcups2-dev libdbus-1-dev libglib2.0-dev libgnutls28-dev libgpgme11-dev \
    libicu-dev libjansson-dev libjs-jquery libjson-perl libkrb5-dev libldap2-dev liblmdb-dev \
    libncurses5-dev libpam0g-dev libparse-yapp-perl libpcap-dev libpopt-dev libreadline-dev \
    libsystemd-dev libtasn1-bin libtasn1-dev libunwind-dev lmdb-utils locales lsb-release \
    make mawk mingw-w64 patch perl perl-modules pkg-config procps psmisc python3 python3-dbg \
    python3-dev python3-dnspython python3-gpg python3-iso8601 python3-markdown python3-matplotlib \
    python3-pexpect rng-tools rsync sed tar tree uuid-dev xfslibs-dev xsltproc zlib1g-dev \
    ccache python3-cryptography python3-pyasn1 python3-setproctitle wget libaio-dev \
    libgpgme-dev nettle-dev python3-all-dev
    

    Compiling & Installing Samba

    I download the latest source code and extract it. I then configure the build to follow the Filesystem Hierarchy Standard (FHS) and include systemd support.

    bash
    wget -O samba-latest.tar.gz https://download.samba.org/pub/samba/samba-latest.tar.gz
    tar zxvf samba-latest.tar.gz
    cd samba-*/
    
    ./configure --prefix=/usr --exec-prefix=/usr --enable-fhs \
    --libdir=/usr/lib/x86_64-linux-gnu --sysconfdir=/etc \
    --localstatedir=/var --with-systemd --systemd-install-services \
    --with-systemddir=/etc/systemd/system --systemd-smb-extra=NotifyAccess=all \
    --systemd-nmb-extra=NotifyAccess=all --systemd-winbind-extra=NotifyAccess=all \
    --systemd-samba-extra=NotifyAccess=all --with-lockdir=/var/run/samba \
    --enable-selftest
    
    # Once everything's done : compile and install
    make -j && make -j install
    

    To prevent a future apt update from accidentally overwriting my custom build, I "hold" the package:

    bash
    apt-mark hold samba
    

    Provisioning the Domain

    This is where I initialize the domain. I'm using 8.8.8.8 as a forwarder here, though I usually point it to my AdGuard Home instance later.

    bash
    samba-tool domain provision --server-role=dc --use-rfc2307 \
    --dns-backend=SAMBA_INTERNAL --realm=DOMAIN.LOCAL --domain=DOMAIN \
    --option="dns forwarder=8.8.8.8"
    

    When everything's done, you can set the Administrator password :

    bash
    samba-tool user setpassword administrator
    

    Managing Users

    Adding users and assigning them to the "Domain Admins" group is straightforward with samba-tool:

    bash
    samba-tool user create USER
    samba-tool group addmembers "Domain Admins" USER
    

    Firewall Configuration

    I use ufw to lock everything down except the essential Active Directory ports:

    bash
    # Disable UFW during configuration
    ufw disable
    
    # Default policies
    ufw default deny incoming
    ufw default allow outgoing
    
    # Management
    ufw allow 22/tcp                      # SSH
    
    # Active Directory Services
    ufw allow 53/tcp                      # DNS (TCP)
    ufw allow 53/udp                      # DNS (UDP)
    ufw allow 88/tcp                      # Kerberos Authentication
    ufw allow 88/udp                      # Kerberos Authentication
    ufw allow 135/tcp                     # RPC Endpoint Mapper
    ufw allow 139/tcp                     # NetBIOS Session Service
    ufw allow 389/tcp                     # LDAP
    ufw allow 389/udp                     # CLDAP (Active Directory)
    ufw allow 445/tcp                     # SMB over IP (File sharing & Group Policy)
    ufw allow 464/tcp                     # Kerberos Password Change
    ufw allow 464/udp                     # Kerberos Password Change
    ufw allow 636/tcp                     # LDAP over SSL (LDAPS)
    ufw allow 3268/tcp                    # Global Catalog
    ufw allow 3269/tcp                    # Global Catalog SSL
    
    # Dynamic RPC Ports for AD replication & client connectivity
    ufw allow 49152:65535/tcp
    
    # Enable Firewall
    ufw enable