First Commit

This commit is contained in:
Lonny Lowe 2026-09-24 11:29:54 -05:00
commit 2e5a4751a7
30 changed files with 2517 additions and 0 deletions

93
docker-compose.yml Normal file
View file

@ -0,0 +1,93 @@
# =====================================================================================
# Samba AD Domain Controller - production shape.
#
# cp .env.example .env && chmod 600 .env
# make build && make up && make verify
#
# WHY host networking by default
# ----------------------------
# An AD DC writes *its own IP* into DNS A records and Windows clients then connect to
# that IP on 88/389/445/3268 plus dynamically allocated DCE-RPC ports. NAT/port
# publishing breaks that contract: the DC advertises an address the client cannot route
# to, and group policy / Kerberos / secure channel fail in ways that look like auth bugs.
# With network_mode: host, host IP == DC IP == the published record: self-consistent.
#
# Before `make up`:
# * nothing may hold TCP/UDP 53 (systemd-resolved stub!), 88, 135, 139, 445, 3268
# * get the host a DHCP reservation. A DHCP lease change silently rots the DNS A record.
#
# Other modes:
# AD_NETWORK_MODE=adlan -> use the named bridge below (lab; needs published ports)
# macvlan -> see docs/docker-compose.macvlan.yml.example
# =====================================================================================
name: windowsad
x-ad-dc: &ad-dc
image: local/samba-ad-dc:4.22-debian13
build:
context: .
dockerfile: image/Dockerfile
args:
SAMBA_VERSION: "2:4.22.11+dfsg-0+deb13u1" # bump deliberately, see README "Upgrades"
env_file:
- .env
volumes:
- ./conf:/etc/samba # smb.conf lives here so you can read it on the host
- ./data/samba:/var/lib/samba # sam.ldb + SYSVOL + private keys -> BACK THIS UP
- ./secrets:/run/ad-secrets:ro
- /etc/localtime:/etc/localtime:ro # password expiry / logs follow host TZ
stop_grace_period: 90s # let SMB sessions and the LDB/BDK close cleanly
restart: unless-stopped
# Least privilege this image actually runs with (validated by tests/smoke.sh).
cap_drop: [ALL]
cap_add:
- CHOWN
- FOWNER
- SETUID
- SETGID
- DAC_OVERRIDE
- NET_BIND_SERVICE
- SYS_NICE
- SYS_RESOURCE
- AUDIT_WRITE
# Required: Samba stores NT ACLs in the security.NTACL xattr, which the kernel
# refuses without CAP_SYS_ADMIN inside a container (provisioning dies on SYSVOL ACLs).
- SYS_ADMIN
services:
# ---- only / primary domain controller ---------------------------------------------
ad-dc:
<<: *ad-dc
container_name: ${AD_CONTAINER:-ad-dc}
hostname: ${AD_HOSTNAME:-dc1}.${AD_DNS_DOMAIN:-ad.example.com}
network_mode: ${AD_NETWORK_MODE:-host}
# ---- second domain controller (HA / replica) --------------------------------------
# Because this uses host networking, run this profile on a SECOND MACHINE with the repo
# synced to it (or switch to macvlan so each DC gets its own LAN address).
# In .env set: AD_HOSTNAME2=dc2 AD_IP=<that machine's ip> AD_JOIN_SERVER=dc1.<domain>
# AD_JOIN_USER=administrator AD_JOIN_PASSWORD=<or secrets/join.password>
# Then: docker compose --profile replica up -d
ad-dc2:
<<: *ad-dc
profiles: ["replica"]
container_name: ${AD_CONTAINER2:-ad-dc2}
hostname: ${AD_HOSTNAME2:-dc2}.${AD_DNS_DOMAIN:-ad.example.com}
network_mode: ${AD_NETWORK_MODE:-host}
volumes:
- ./conf-dc2:/etc/samba
- ./data/samba-dc2:/var/lib/samba
- ./secrets:/run/ad-secrets:ro
- /etc/localtime:/etc/localtime:ro
networks:
# Only used when AD_NETWORK_MODE=adlan. Kept here so `make up` can be switched to a
# sandboxed bridge without editing YAML. Real Win11 joins from the LAN will NOT work in
# this mode - see docs/ for macvlan if you need LAN-reachable without host networking.
adlan:
name: adlan
driver: bridge
ipam:
config:
- subnet: 172.28.90.0/24