| your Linux construction kit
Source
← Back to Overview

Windows & Active Directory — Linux that joins your domain automatically.

Enterprise environments run Active Directory. That's reality. If your Linux machines can't join the domain, authenticate against AD, and show up in SCCM — they don't exist to the Windows team. This tutorial builds a self-deploying Linux image that auto-joins AD on first boot, authenticates with Kerberos, and exposes a management console — all from a sealed ISO.

Three parts: build the management server, deploy endpoint images, and wire them into your existing Windows infrastructure. No manual domain joins. No SSH-and-pray. The ISO does everything.

Part 1: Build the management server

What you're building

A Linux server (we call it MasterControl) that acts as a bridge between your Linux fleet and Active Directory. It runs:

  • PostgreSQL — device inventory, profiles, enrollment tokens
  • FastAPI admin console — web UI for managing devices and profiles
  • NGINX — reverse proxy with mTLS for agent communication
  • SSSD + realmd — Active Directory domain join and Kerberos auth
  • Internal CA — issues client certificates to enrolled devices
Think of it as a Linux SCCM that speaks Active Directory natively.

The postinstall.sh

The entire server builds itself from a single postinstall.sh. Here's what each phase does:

Phase 1
Base OS — APT sources, dist-upgrade, install 40+ packages including realmd, sssd, krb5, postgresql, nginx
Phase 2
Users & SSH — create admin users with SSH keys, harden sshd (no root, no password, pubkey only)
Phase 3
Desktop — minimal GNOME with Wayland, operator autologin, kiosk mode pointing to the admin console
Phase 4
PostgreSQL — create database, schema (devices, profiles, enrollment tokens, org settings, admin users)
Phase 5
Internal CA — generate root CA + server cert for mTLS. Agent devices get client certs on enrollment.
Phase 6
FastAPI console — dashboard, device inventory, profile management, AD settings, enrollment token issuing
Phase 7
NGINX — TLS termination, mTLS for /agent/* endpoints, reverse proxy to FastAPI
Phase 8
Cleanup — reset machine-id, regenerate SSH host keys, purge temp files. Ready to clone.

Build and deploy the management server

# 1. Configure the build
export VMNAME="mastercontrol"
export DOMAIN="corp.example.com"
export MC_DOMAIN="mastercontrol.corp.example.com"
export INSTALL_PROFILE="gnome-min"
export NETWORK_MODE="static"
export STATIC_IP="10.100.10.100"

# 2. Build the ISO (bakes postinstall.sh + preseed + darksite into a Debian ISO)
bash build-intunenix.sh

# 3. What happens automatically:
#    - ISO uploads to Proxmox
#    - VM created (UEFI, 4 cores, 4GB RAM, 32GB disk)
#    - Preseed runs unattended Debian install
#    - VM powers off after install
#    - ISO ejected, boot from disk
#    - postinstall.sh runs (installs everything)
#    - VM powers off after postinstall
#    - VM starts for production
#
# Total: ~15 minutes. Zero interaction.

Part 2: Active Directory integration

Domain join from the web console

Open https://mastercontrol.corp.example.com in a browser. Go to AD Settings. Enter your domain details:

AD Domain:          corp.example.com
AD Admin User:      administrator
AD Admin Password:  [your AD admin password]
Computer OU:        OU=Linux,OU=Servers,DC=corp,DC=example,DC=com
[x] Join domain now

Click Save. The server runs realm join with your credentials, configures SSSD for Kerberos authentication, and the machine appears in Active Directory. AD users can now SSH in with their domain credentials.

# What happens under the hood:
realm join corp.example.com --user=administrator --computer-ou="OU=Linux,..."
# SSSD configured for AD authentication
# Kerberos keytab generated
# PAM configured for AD logins
# Home directories auto-created via oddjob-mkhomedir

# AD users can now login:
ssh user@CORP.EXAMPLE.COM@mastercontrol.corp.example.com

Part 3: Deploy endpoint images

Create a device profile

Profiles define what an endpoint should look like. Create one from the web console or CLI:

# From the web console: Profiles → Create
# Name: workstation
# Spec (JSON):
{
  "packages": {
    "apt_install": ["libreoffice", "firefox-esr", "thunderbird", "vlc"]
  },
  "security": {
    "auto_updates": true,
    "ufw_rules": ["allow OpenSSH", "allow 443/tcp"]
  },
  "ad": {
    "auto_join": true,
    "computer_ou": "OU=Workstations,DC=corp,DC=example,DC=com"
  }
}

# Or from CLI:
mcctl new-profile workstation /path/to/workstation.json

Issue enrollment tokens

# Generate a token that endpoints use to register
mcctl issue-token workstation 7d
# TOKEN: a3f8e2c1-7b4d-4e9a-b8c3-1234567890ab
# Expires in 7 days

# Bake this token into endpoint ISOs or pass via seed disk

Build endpoint ISOs

Each endpoint ISO carries an enrollment token and the MasterControl CA cert. On first boot, the endpoint:

  1. Runs firstboot.sh (the IntuneNix firstboot service)
  2. Contacts MasterControl: POST /enroll {cn: "ws-001", token: "a3f8..."}
  3. Receives a client certificate signed by the internal CA
  4. Joins Active Directory using the profile's AD settings
  5. Installs the profile's packages
  6. Applies security policies
  7. Reports back to MasterControl with device status
# The endpoint's firstboot hook:
cat > /opt/intunenix/firstboot.d/01-enroll.sh <<'HOOK'
#!/bin/bash
MC_URL="https://mastercontrol.corp.example.com"
TOKEN="a3f8e2c1-7b4d-4e9a-b8c3-1234567890ab"
CN="$(hostname)"

# Enroll with MasterControl
curl -sk -X POST "${MC_URL}/enroll" \
  -H "Content-Type: application/json" \
  -d "{\"cn\": \"${CN}\", \"token\": \"${TOKEN}\"}"

# Join AD (realm join uses the profile's settings)
realm join corp.example.com \
  --user=svc-linux-join \
  --computer-ou="OU=Workstations,DC=corp,DC=example,DC=com" \
  --unattended
HOOK
chmod +x /opt/intunenix/firstboot.d/01-enroll.sh
USB in. Power on. 15 minutes later: Linux workstation, domain-joined, showing up in AD, managed by MasterControl. Zero touch.

Scale it: spray 50 workstations

# Build once, clone on Proxmox
for i in $(seq 1 50); do
  pvesh create /nodes/fiend/qemu/1002/clone \
    --newid $((2000 + i)) \
    --name "ws-$(printf '%03d' $i)" \
    --full true
  pvesh create /nodes/fiend/qemu/$((2000 + i))/status/start
done

# Each clone boots, runs firstboot, enrolls with MasterControl,
# joins AD, installs packages, and appears in the dashboard.
# 50 workstations. Zero manual configuration.

# Check enrollment:
mcctl ls-devices
#  cn       | profile     | enrolled_at          | last_seen
# ----------+-------------+----------------------+----------
#  ws-001   | workstation | 2026-03-21 08:00:00  | ...
#  ws-002   | workstation | 2026-03-21 08:00:03  | ...
#  ...      | ...         | ...                  | ...

The MasterControl console

What you manage from the browser

Dashboard
Device count, profile count, AD domain status. Quick-issue enrollment tokens.
Profiles
Create/update JSON profiles that define packages, security, AD settings per device type.
Devices
All enrolled devices. Assign profiles. See enrollment time and last check-in.
AD Settings
Domain, admin user, computer OU. Join/rejoin from the browser. View join logs.
API
/enroll, /agent/* (mTLS), /healthz. Build your own integrations.

Why this matters for Windows shops

Linux machines become visible

They show up in AD. They authenticate with Kerberos. The Windows team can see them. Group Policy won't apply (it's Linux), but the machines exist in the directory and can be managed through MasterControl's profile system instead.

Zero-touch deployment

Build the ISO. Burn to USB. Boot. Walk away. The machine installs itself, joins the domain, enrolls with MasterControl, installs its profile's packages, and shows up in the dashboard. No SSH. No manual config. No "let me just fix this one thing."

Darksite compatible

The ISO carries everything. If your AD environment is air-gapped (and many are), the machine can still install from the local darksite repo. Domain join works over LAN. MasterControl enrollment works over LAN. No internet required.

Cattle, not pets

Machine broken? Don't fix it. Blow it away. Clone from the golden image. It re-enrolls, re-joins AD, and re-applies its profile. Total time: 5 minutes. The MasterControl database is the source of truth, not the machine itself.

This is a complete SCCM alternative for Linux endpoints. Enrollment tokens, device profiles, AD integration, mTLS agent communication, and a web console — all built from a single postinstall.sh. No vendor license. No per-seat cost. No cloud dependency. Fork it. Customize it. Deploy it. That's kldload.