Switching from Active Directory to Samba4

Active Directory is solid, secure, and stable platform for user, group, and computer management. I would go as far and say that it is probably the backbone of 99.9% of all organizations world wide. So why would anyone want to switch away from Active Directory? The answer to that question is varied, but the most common reason why are:

  • Reduce licensing costs (per user/device cals)
  • Reduce Windows foot print
  • Advanced features of AD are not needed
  • Less than 5,000 users
  • Because <insert_favorite_software> is greater than <insert_hated_software>

Let us get started on switching to a Samba4 backend.

This guide assumes the following:

  • You already have a domain environment
  • The forest functional level is 2003 or greater
  • The domain functional level is not greater than 2008 R2
  • You are running CentOS/RedHat 7 as your Samba4 host and it is a vanilla minimal install with no added repositories (i.e. you just installed it)
  • Your domain is: AD.ANDREWWIPPLER.COM and your NETBIOS is AD.

Installing Samba4

The samba version that ships with CentOS is compiled in legacy NT4 emulation mode. In order to get the AD emulation, we will need to compile Samba4 (Don’t worry, it is very easy and compiles under 20 minutes with a 2 core processor.)

cd /usr/src/
wget https://download.samba.org/pub/samba/stable/samba-4.3.2.tar.gz
sudo tar xf samba-4.3.2.tar.gz
cd samba-4.3.2/

Now we need to install the build tools. (The most updated list is located here)

sudo yum install perl gcc attr libacl-devel libblkid-devel \
    gnutls-devel readline-devel python-devel gdb pkgconfig \
    krb5-workstation zlib-devel setroubleshoot-server libaio-devel \
    setroubleshoot-plugins policycoreutils-python \
    libsemanage-python perl-ExtUtils-MakeMaker perl-Parse-Yapp \
    perl-Test-Base popt-devel libxml2-devel libattr-devel \
    keyutils-libs-devel cups-devel bind-utils libxslt \
    docbook-style-xsl openldap-devel autoconf python-crypto

The next step is to compile and run:

./configure
make -j 2
# The number 2 should be relative to the number of cores on your machine
sudo make install

This process should take less than 20 minutes. After it is done compiling, it will install to /usr/local/samba/. To make it easier to run the new commands, let us add the paths to our global path:

sudo cat << EOF > /etc/profile.d/samba.sh
##add samba to PATH
export PATH=/usr/local/samba/bin/:/usr/local/samba/sbin/:$PATH
EOF
sudo chmod 0644 /etc/profile.d/samba.sh
. /etc/profile

Preparing the system to join AD

Now that Samba is installed, we need to configure our system to interact with Active Directory as well and set up BIND9.

Network related

A static IP as well as DNS must be configured properly for this to work. Ensure the appropriate settings are in /etc/sysconfig/network-scripts/ifcfg-(iface-name). The DNS servers must be an Active Directory domain controller and you should be able to ping it. If modification is done to this file, you will need to restart NetworkManager for changes to take effect. The desired result is to have /etc/resolv.conf appear like the following:

# Generated by NetworkManager
search ad.andrewwippler.com
nameserver 192.168.1.201

In my lab, 192.168.1.201 is a Windows 2008 R2 server named DC1.

Hostname related

If you have not named your CentOS install, it is best to do it now. You will also need to verify that pinging your hostname works and it returns with the ip of the interface you set and not the loopback interface.

sudo hostname dc2.ad.andrewwippler.com
sudo echo 'dc2.ad.andrewwippler.com' > /etc/hostname
echo '192.168.1.202 dc2 dc2.ad.andrewwippler.com' >> /etc/hosts

Kerberos related

Ensure /etc/krb5.conf has the following. The domain needs to be in all caps.

...
[libdefaults]
    ...
    dns_lookup_realm = false
    dns_lookup_kdc = true
    default_realm = AD.ANDREWWIPPLER.COM
...

Testing

We can now test our DNS and Kerberos settings with two simple commands.

kinit administrator

This should ask you for the domain administrator’s password. Once entered you can verify everything is working with klist.

Joining Active Directory

At this point, we have not started Samba, nor do we need to until the very end. We can now issue the join command (with BIND9 support)

sudo samba-tool domain join ad.andrewwippler.com DC -Uadministrator --realm=AD.ANDREWWIPPLER.COM --dns-backend=BIND9_DLZ

Now we will have to configure bind. For convenience sake, I have included my /etc/named.conf

//
// named.conf
//

options {
	listen-on port 53 { any; };
	listen-on-v6 port 53 { any; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	allow-query     { any; };
	recursion yes;
	dnssec-enable yes;
	dnssec-validation yes;
	dnssec-lookaside auto;
	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.iscdlv.key";
	managed-keys-directory "/var/named/dynamic";
	pid-file "/run/named/named.pid";
	session-keyfile "/run/named/session.key";

        //samba
        tkey-gssapi-keytab "/usr/local/samba/private/dns.keytab";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
	type hint;
	file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
//samba
include "/usr/local/samba/private/named.conf";

Allowing access

Now that we have a functioning samba server (even though it hasn’t started yet), we need to allow it through SELinux and the firewall. Below are the commands to do just that:

Firewall

sudo firewall-cmd --add-port=389/tcp --permanent
sudo firewall-cmd --add-port=389/udp --permanent
sudo firewall-cmd --add-port=636/tcp --permanent
sudo firewall-cmd --add-port=53/tcp --permanent
sudo firewall-cmd --add-port=53/udp --permanent
sudo firewall-cmd --add-port=88/tcp --permanent
sudo firewall-cmd --add-port=88/udp --permanent
sudo firewall-cmd --add-port=464/tcp --permanent
sudo firewall-cmd --add-port=464/udp --permanent
sudo firewall-cmd --add-port=135/tcp --permanent
sudo firewall-cmd --add-port=137/udp --permanent
sudo firewall-cmd --add-port=139/tcp --permanent
sudo firewall-cmd --add-port=138/udp --permanent
sudo firewall-cmd --add-port=445/tcp --permanent
sudo firewall-cmd --add-port=3268/tcp --permanent
sudo firewall-cmd --reload

SELinux

sudo chown named:named /usr/local/samba/private/dns
sudo chgrp named /usr/local/samba/private/dns.keytab
sudo chmod g+r /usr/local/samba/private/dns.keytab
sudo chmod 775 /usr/local/samba/private/dns
sudo chown named:named /usr/local/samba/lib/bind9/dlz_bind9_9.so
sudo chcon -t named_conf_t /usr/local/samba/private/dns.keytab
sudo chcon -t named_conf_t /usr/local/samba/private/named.conf.update
sudo chcon -t named_var_run_t /usr/local/samba/private/dns
sudo chcon -t named_var_run_t /usr/local/samba/lib/bind9/dlz_bind9_9.so
sudo semanage fcontext -a -t named_conf_t /usr/local/samba/private/dns.keytab
sudo semanage fcontext -a -t named_conf_t /usr/local/samba/private/named.conf
sudo semanage fcontext -a -t named_conf_t /usr/local/samba/private/named.conf.update
sudo semanage fcontext -a -t named_var_run_t /usr/local/samba/private/dns
sudo semanage fcontext -a -t named_var_run_t /usr/local/samba/lib/bind9/dlz_bind9_9.so

Now we need to run SELinux in permissive mode and add the policy.

sudo setenforce 0
sudo systemctl restart named
sleep 60
sudo systemctl stop named
cd ~
sudo grep named /var/log/audit/audit.log | audit2allow -M named > named.te
sudo semodule -i named.pp 
sudo setenforce 1
sudo systemctl start named

Init files

Samba does not ship with an init file so we will have to create one and enable it to start at boot.

sudo cat << EOF > /etc/init.d/samba
#!/bin/bash
#
# samba4        This shell script takes care of starting and stopping
#               samba4 daemons.
#
# chkconfig: - 58 74
# description: Samba 4.0 will be the next version of the Samba suite
# and incorporates all the technology found in both the Samba4 alpha
# series and the stable 3.x series. The primary additional features
# over Samba 3.6 are support for the Active Directory logon protocols
# used by Windows 2000 and above.

### BEGIN INIT INFO
# Provides: samba4
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Should-Start: $syslog $named
# Should-Stop: $syslog $named
# Short-Description: start and stop samba4
# Description: Samba 4.0 will be the next version of the Samba suite
# and incorporates all the technology found in both the Samba4 alpha
# series and the stable 3.x series. The primary additional features
# over Samba 3.6 are support for the Active Directory logon protocols
# used by Windows 2000 and above.
### END INIT INFO

# Source function library.
. /etc/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

prog=samba
prog_dir=/usr/local/samba/sbin/
lockfile=/var/lock/subsys/$prog

start() {
        [ "$NETWORKING" = "no" ] && exit 1
#       [ -x /usr/sbin/ntpd ] || exit 5
                # Start daemons.
                echo -n $"Starting samba4: "
                daemon $prog_dir/$prog -D
        RETVAL=$?
                echo
        [ $RETVAL -eq 0 ] && touch $lockfile
        return $RETVAL
}

stop() {
        [ "$EUID" != "0" ] && exit 4
                echo -n $"Shutting down samba4: "
        killproc $prog_dir/$prog
        RETVAL=$?
                echo
        [ $RETVAL -eq 0 ] && rm -f $lockfile
        return $RETVAL
}

# See how we were called.
case "$1" in
start)
        start
        ;;
stop)
        stop
        ;;
status)
        status $prog
        ;;
restart)
        stop
        start
        ;;
*)
        echo $"Usage: $0 {start|stop|status|restart}"
        exit 2
esac
EOF
sudo chmod +x /etc/init.d/samba
sudo chkconfig samba on

Flipping the switch

You are now ready to either restart the system or start samba. The next steps to fully migrate to a Samba4 AD backend would be to migrate the FSMO roles to this server. Managing this AD instance is done by loading the Remote Server Administration Tools (RSAT) on a windows client.

Sources

Here are the list of sources and references to compile this tutorial:

  • https://wiki.samba.org/index.php/Join_an_additional_Samba_DC_to_an_existing_Active_Directory
  • https://wiki.samba.org/index.php/Build_Samba_from_source
  • https://wiki.samba.org/index.php/Samba4/InitScript
  • https://wiki.samba.org/index.php/Configure_BIND_as_backend_for_Samba_AD
  • https://lists.samba.org/archive/samba/2013-March/172397.html (Thanks Thomas Simmons)