Samba4 Domain Controller on Ubuntu 18.04
Quick Background
I volunteer as a Systems Administrator for a small medical clinic. They have a very slim IT budget so while their desktop systems are primarily Windows 11, I’ve configured most of their server infrastructure with Linux. A Proxmox server is used to manage their virtualized environment and I’m using Samba4 for their Active Directory Domain Controller.
When I first set up Samba4 as their Active Directory I was able to use CentOS 6 with the Samba4 binary packages from SerNet. Although this has been working well enough, it has always been a little quirky and I had only ever set up a single Domain Controller. So recently I decided to upgrade their Domain Controllers to the newest version and add a second Domain Controller.
Initially I tried to find the SerNet packages but it appears they have rebranded themselves as Samba+ and now charge a subscription fee for the binary packages. While I would love to support them, paying a subscription fee is not an option for this clinic.
I’d really like to stick with CentOS as the server distribution as I have a lot of experience with it and have always found it to be a solid, minimial distribution. However, for reasons RedHat has decided that the Samba4 build that comes with Fedora should not include the ability to act as an Active Directory Domain Controller.
I could build the sources from scratch and still use CentOS, but that would require installing all the build tools on each server and I’m trying to keep them as light as possible. Plus, building from scratch often introduces its own host of challenges and I really just want to set this up and move on to my next project. So instead I’m going to give a go at using Ubuntu, which I really like as a desktop system but have never been terribly thrilled with as a server system.
For setting this up I am mostly following the instructions from tecmint and specifically this one. However, these instructions were written for Ubuntu 16.04 so I’m making this post to document the steps I took in setting up Samba4 on an Ubuntu 18.04 system.
Networking overview
For reference, the main gateway is a
pfSense system set up at 10.0.1.1. This runs
as the primary DNS and DHCP server for the network. The domain name
I’ll use in these instructions is hrakaroo.lan
.
The Active Directory domain is ad.hrakaroo.lan
. I’ve specifically
set this up so that Active Directory is on it’s own sub domain as I
don’t want the rest of the server infrastructure to be dependent on
Active Directory. I’d rather isolate Active Directory to its own
area.
Creating a new system in Proxmox
In Proxmox I’ve created the following new host
Hostname: adc1
Memory: 2 G
Disk: 32 G
Processors: 1
Cores: 2
In retrospect (by looking at the usage charts in Proxmox) it looks like I could have cut the memory, disk and cores in half and it would have been fine, but I’m going to leave it as is for now.
Once the vm is created, start the server.
Most of the installation is pretty straightforward so I’m only going to highlight when I didn’t select the default.
Installer update available
During the install it suggests that an update to the installer is available and asks if you want to update. I’m not sure if it matters much, but I said yes.
Networking
Edit the IPv4 configuration and select Manual
Subnet: 10.0.1.0/24
Address: 10.0.1.25
Gateway: 10.0.1.1
Name servers: 10.0.1.26
Search domains: ad.hrakaroo.lan
10.0.1.26 is the name servers for the existing Active Directory Domain Controller. Once the system is fully configured I’ll change this, but it makes the initial setup much easier if this points at your existing Domain Controller.
Profile Setup
This is the first thing I don’t like about Ubuntu. I’d rather just have a password set for the root account. I get the reason why they are doing this, but for a super small setup this is more of an annoyance than a help. Sadly you also can’t use general accounts like ‘admin’ or ‘staff’ either. So I ended up creating a personal account for Joshua Gerth. (This turned out to be a bit of a mistake, more on this can be found in the additional things at the bottom.)
SSH Setup
[X] Enable install the OpenSSH server.
Basic Server Configuration
For almost all of these commands I find it easier to work by ssh’ing into the box rather than using the Proxmox console as copy/paste and editing all work better.
Update and install emacs
Okay, once the server is up and running I always run the update commands to make sure everything is up to date:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt dist-upgrade
and also, because vi is terrible I always install emacs:
$ sudo apt install -y emacs
Turn off IPv6
This may not be necessary, but I find that debugging things when only IPv4 is enabled to be a lot easier. The environment I’m installing this in is small enough that we are not at risk of running out of IP numbers any time soon and since everything gets NAT’ed anyhow I don’t really see a need to enable IPv6.
That said, this is the second thing that I don’t care for about Ubuntu. In CentOS turning off IPv6 is sort of trivial, but on Ubuntu I this proved to be rather difficult. Most of the existing suggestions only turned off part of IPv6 and it was only after a lot of trial and error did I happen on a post with the best answer.
Basically you need to edit /etc/default/grub
and set
GRUB_CMDLINE_LINUX="xxxxx ipv6.disable=1"
(For me there was nothing in the xxxxx area, but if you have any existing options then leave them there and add the ipv6.disable at the end.)
and then run
$ update-grub
Turn off dnsmasq
This is the third thing that I don’t like about Ubuntu, it runs a stub dnsmasq as a DNS caching server. Again, I get why they did this, but I’ve never found this to be useful on a server and nine out of ten times it just causes problems.
To disable it I’m mostly following these instructions.
Edit /etc/systemd/resolved.conf
and add
DNSStubListener=no
Then remove the existing symlink at /etc/resolv.conf and rebuild it
$ rm /etc/resolv.conf
$ ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
Since this has been such a thorn in my side I prefer to reboot here to make damn sure the new settings have taken.
/etc/resolv.conf
should now show the values that you entered on
initial setup.
NTP
Domain Controllers are sensitive to clock drift and need to be
configured to use a network time server. Normally I would configure
ntpd
on the host, but Ubuntu has decided to ship with timedatectl
instead which claims to be a lightweight ntp client. (Humorously, 90%
of the google searches for timedatectl
suggest turning it off and
replacing it with a real ntpd, however, I’m going to try sticking with
timedatectl for now.)
First I like to set the timezone so I don’t need to convert everything
$ timedatectl set-timezone America/Los_Angeles
Now, edit the /etc/systemd/timesyncd.conf
file and set the NTP entry
to point to your NTP server. (I’m running an NTP server on another VM at
10.0.1.22).
[Time]
NTP=10.0.1.22
restart the timesyncd
$ systemctl restart systemd-timesyncd
and verify it with
$ cat /var/log/syslog | grep systemd-timesyncd
XXX adc1 systemd-timesyncd[1416]: Synchronized to time server 10.0.1.22:123 (10.0.1.22).
Install Samba
Since we are actually about to install Samba I like to do one more reboot here.
Update the hosts file
The /etc/hosts
file should have an entry for every domain
controller, including itself. (I also removed the old IPv6 stuff)
127.0.0.1 localhost
10.0.1.25 adc1.ad.hrakaroo.lan adc1
10.0.1.26 oldadc.ad.hrakaroo.lan oldadc
Again, 10.0.1.25 is this box, the new Active Directory server and 10.0.1.26 is the old Active Directory server.
Install Samba4
Actually install samba
$ apt install -y samba krb5-user krb5-config winbind libpam-winbind libnss-winbind
If you already have things correctly setup then this should automatically find the kerberos SRV records for your domain which are being hosted on your existing Active Directory server, if not it may prompt you for them. If it does prompt you enter the domain in all upper case for the Default realm and in regular case for the Kerberos servers and Administrative server.
Default Kerberos realm: AD.HRAKAROO.LAN
Kerberos servers realm: ad.hrakaroo.lan
Administrative server: ad.hrakaroo.lan
Verify kerberos works by
$ kinit jgerth@AD.HRAKAROO.LAN
Password for jgerth@AD.HRAKAROO.LAN: <passwd>
$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: jgerth@AD.HRAKAROO.LAN
Valid starting Expires Service principal
03/27/20 18:54:49 03/28/20 04:54:49 krbtgt/AD.HRAKAROO.LAN@AD.HRAKAROO.LAN
renew until 03/28/20 18:54:46
Join the Domain
Remove the existing smb.conf as it will be recreated by samba-tool.
$ systemctl stop samba-ad-dc smbd nmbd winbind
$ mv /etc/samba/smb.conf /etc/samba/smb.conf.initial
Use samba-tool to join the domain
$ samba-tool domain join ad.hrakaroo.lan DC -U "AD\jgerth"
Now configure the server to start samba-ad-dc automatically
$ systemctl mask smbd nmbd winbind
Created symlink /etc/systemd/system/smbd.service → /dev/null.
Created symlink /etc/systemd/system/nmbd.service → /dev/null.
Created symlink /etc/systemd/system/winbind.service → /dev/null.
$ systemctl unmask samba-ad-dc
Removed /etc/systemd/system/samba-ad-dc.service.
$ systemctl enable samba-ad-dc
Use the host command to verify your configuration. This apparently hits every nameserver listed so you may get some errors when it tries to hit the non-active directory DNS servers.
$ host ad.hrakaroo.lan
ad.hrakaroo.lan has address 10.0.1.26
ad.hrakaroo.lan has address 10.0.1.25
Host ad.hrakaroo.lan not found: 3(NXDOMAIN)
Host ad.hrakaroo.lan not found: 3(NXDOMAIN)
$ host -t SRV _kerberos._udp.ad.hrakaroo.lan
_kerberos._udp.ad.hrakaroo.lan has SRV record 0 100 88 oldadc.ad.hrakaroo.lan.
_kerberos._udp.ad.hrakaroo.lan has SRV record 0 100 88 adc1.ad.hrakaroo.lan.
$ host -t SRV _ldap._tcp.ad.hrakaroo.lan
_ldap._tcp.ad.hrakaroo.lan has SRV record 0 100 389 oldadc.ad.hrakaroo.lan.
_ldap._tcp.ad.hrakaroo.lan has SRV record 0 100 389 adc1.ad.hrakaroo.lan.
Change DNS
At this point you could be done as the server is now up and running. However, it is technically using the other domain controller for DNS lookups. Even if I wasn’t planning on decommissioning the older server this would still be creating an out of band dependency between them and as Active Directory is, itself, a DNS server I prefer to update the server to use itself for DNS lookups. (Similar to what Ubuntu was initially trying to do with the dnsmasq stuff).
To do this, modify /etc/netplan
and set 127.0.0.1
as first in
your nameserver list and then the upstream DNS server second.
Also verify that search
is set to use the ad domain first and then
your global domain. Like this
nameservers:
addresses:
- 127.0.0.1
- 10.0.1.1
search:
- ad.hrakaroo.lan
- hrakaroo.lan
As always, reboot and check the values in the /etc/resolv.conf
and
do a couple of tests with nslookup
.
Configure Proxmox to boot the server
I also configure Proxmox to start the service at boot. This way if there is a power outage Proxmox will be sure to start your domain controllers.
Options -> Start at boot -> True
Additional things
Decommissioning the old Active Directory Controller
With the new Domain Controller up you can now decommission the old
Domain Controller by moving the roles (7) from the old DC to your
new one. However, the version of Samba which shipps with Ubuntu 18.04
is 4.7 which, apparently, has a bug with the python code that you
use to move the roles. To fix this I had to edit
/usr/lib/python2.7/dist-packages/samba/netcmd/fsmo.py
and insert line
import samba.drs_utils
just after
import samba
around line 20. After doing this the command to move the roles worked just fine and I was able to fully decommission the older active domain controller.
Removing the profile
It turns out that creating the profile as I did during the initial set
up of Ubuntu was a bit of a mistake. It didn’t cause an issue for
this server but it did on a file server I set up later which was also
on Ubuntu. The issue was that the Ubuntu account jgerth
conflicted
with the Active Directory accouunt jgerth
and made testing Windows File
Sharing under my account difficult.
I could have addressed this by using a unique login on the Ubuntu
server (like jogerth
) but that feels like a pretty hacky solution.
Plus, it raises the bigger issue that ultimately someday someone else
is probably going to take over for me as the sysadmin and I don’t
really want them to have to use my account. The right way to solve
this is to create an LDAP server for the Linux boxes and host the
logins centrally, but this feels a bit like overkill to me as we
currently only have around 5 Linux systems and, at least for the time
being, I would be the only person in the LDAP server.
I suppose I could bind the Linux boxes in to the Active Directory LDAP server, but that creates a bit of a chicken and egg dependency on Active Directory that I’m just not comfortable with.
What I really want is just a generic sysadmin account, but if you are
going to do that then why not use the one that already comes with
every Unix/Linux system, root
. So in the end I configured an
explicit password for root
, enabled SSH login for root and deleted
the account I created on setup. I would never recommend this for a
larger environment, but for a small setup this worked out best.
Closing thoughts
In the end I’m glad I set this up from scratch rather than use the build and instructions from SerNet. I have a better understanding of what everything is doing and the weird quirkiness I was experiencing with the old server has gone away (although, to be fair, that could have been due to the older version I was running.) I also feel more comfortable with the samba tool and adding and removing domain controllers.
I’m still not a huge fan of Ubuntu as a server. I don’t care for the dnsmasq stub, the replacement for ntpd or how it forces you to create a non-root account, but since it is a popular system I was able to search for most of the errors I did encounter.
Supporting Windows 11 22H2
In the two years since I set this system up it has been running nearly flawlessly. The only real issue is that with Windows 11 update 22H2 Microsoft changed the encryption protocol (or something similar) and they are no longer able to bind to the domain controller. (This does not seem to impact existing systems that are already bound to the domain.)
The following Reddit link talks about the issue in depth https://www.reddit.com/r/sysadmin/comments/xoqend/samba_495_windows_11_22h2_kerberos/
The fix is to update Samba to version 4.16.0, which isn’t directly available for Ubuntu 18.04. The recommended path is probably to upgrade to Ubuntu 22.x, but since that’s bound to cause it’s own host of complications I instead opted to just change the source for Samba by following these instructions
https://ubunlog.com/en/ya-fue-liberada-la-nueva-version-de-samba-4-16-0-y-estos-son-sus-cambios/
sudo add-apt-repository ppa:linux-schools/samba-latest
sudo apt-get update
sudo apt install samba
This was enough to upgrade samba on 18.04 to 4.16.0. Once I restarted both domain controllers the Windows 11 with update 22H2 system was able to bind to the Domain.