Back to blog
InfrastructureSeptember 25, 2024·Nathan Kovac

Connecting the Dots: Domain Controller and Mixed-OS Networking

One identity across Windows dev machines and Linux servers. It sounds simple. It involved SSSD, DNS forwarding, and several hours of staring at Kerberos errors.

#Active Directory#Domain Controller#Networking#Windows#Linux

The goal was simple: one login that works everywhere. I log into my Windows desktop as nate@sorren.local, and that same identity authenticates me on the Linux servers, the Proxmox nodes, everything.

The implementation was not simple. But it works now, and here's how.

Why a Domain Controller at All?

For a two-person operation, this looks like overkill. But we already have a Proxmox cluster running half a dozen VMs, plus dev machines, plus whatever's coming. Managing users per-machine doesn't scale past three boxes, and it scales to exactly zero when you want to revoke access across everything at once.

Active Directory handles this — the boring, battle-tested answer to centralized identity. And because it speaks standard protocols (LDAP, Kerberos, DNS), Linux machines can authenticate against it without joining the Windows world culturally.

The DC: Windows Server in Proxmox

I created a VM on the Proxmox cluster and installed Windows Server 2022. Gave it 4 vCPUs, 8 GB RAM, a 60 GB disk. Promoted it to a domain controller via Server Manager → "Add roles and features" → Active Directory Domain Services. The wizard creates the forest — I named it sorren.local.

DNS is the critical piece. When you promote a server to DC, it installs DNS Server automatically. This DNS zone (sorren.local) becomes the source of truth for every machine name on the network. I set the DC's IP as the primary DNS on every machine — Windows, Linux, Proxmox nodes — either via DHCP or static config.

For external resolution, the DC forwards to 1.1.1.1 and 8.8.8.8. Internal names resolve locally; everything else goes upstream. Standard.

Joining Windows Machines

This part is easy. On each Windows dev machine: Settings → rename this PC (advanced) → change → Domain → enter sorren.local → enter domain admin credentials → reboot. The machine is now domain-joined. Users log in as SORREN\nate instead of a local account.

File shares, printer management, Group Policy — it all becomes available. For now I'm mostly using it for identity and DNS, but the foundation is there.

Joining Linux Machines: SSSD

This is where it gets interesting. Linux doesn't "join" Active Directory the way Windows does — it authenticates against it. The tool for this is sssd (System Security Services Daemon), configured to talk LDAP and Kerberos to the DC.

I used realmd to do the heavy lifting, because it generates most of the SSSD config for you:

# Install prerequisites
sudo apt install realmd sssd sssd-tools adcli krb5-user \
  packagekit samba-common-bin oddjob oddjob-mkhomedir

# Discover the domain
realm discover sorren.local

# Join
sudo realm join --user=nate sorren.local

If that succeeds, sssd is configured and running. But I had to make a few manual tweaks to the config for things to feel right:

# /etc/sssd/sssd.conf
[domain/sorren.local]
use_fully_qualified_names = False
fallback_homedir = /home/%u
default_shell = /bin/bash
krb5_store_password_if_offline = True

The use_fully_qualified_names = False line matters — without it, logins are nate@sorren.local instead of just nate, which breaks muscle memory and half my scripts.

Permissions on the config file are strict, because SSSD refuses to start otherwise:

sudo chmod 600 /etc/sssd/sssd.conf
sudo systemctl restart sssd

Now id nate on any Linux server returns the domain user, and ssh nate@dev-box works with domain credentials.

The Kerberos Trap

The one error that ate an hour: KDC reply did not match expectations while getting initial credentials. Classic. The cause was DNS — the Linux box couldn't resolve the DC's Kerberos service record. The fix is making sure the DC is the DNS server and that the SRV records are present:

# Should return the DC's hostname
dig _ldap._tcp.sorren.local SRV

If that comes back empty, DNS isn't set up correctly on the DC side. Once I pointed everything at the DC for DNS and confirmed the SRV records, Kerberos auth worked cleanly.

Network Shares

For shared storage between Windows and Linux, I set up a Samba share on one of the Linux VMs, joined to the domain so it authenticates via AD. Windows machines map it as a network drive; Linux machines mount it via cifs with sec=krb5:

//filestore.sorren.local/share  /mnt/share  cifs  sec=krb5,uid=1000,gid=1000  0  0

No stored passwords. Authentication flows through Kerberos. Clean.

What We Got

After all this:

  • One identity. I'm nate everywhere.
  • Centralized DNS. Every machine name resolves.
  • SSH to Linux boxes with domain credentials — no per-machine key management for humans.
  • Shared file storage with consistent permissions.
  • A foundation for adding new users or machines without touching each one.

Was it worth the Kerberos errors? Yes. Centralized identity is infrastructure you stop thinking about once it works, and that's the highest compliment I can give any system.

The next problem: models. We need to run inference, and I'd rather not pay per-token forever. That means GPUs, and that means a local inference stack. Coming up.

NK
Nathan Kovac
Founder & Lead Engineer at Sorren.ai