From 6c75e2910baba27dada55b90574705f106817ccc Mon Sep 17 00:00:00 2001 From: Jose Date: Sun, 19 Oct 2025 22:25:19 +0200 Subject: [PATCH] patch undefined: Updated the DNS configuration in the `resolv.conf.j2` template to include both the local host and the Ansible-managed DNS server. Added a new line to the `resolv.conf.j2` template to specify the Ansible-managed DNS server (`{{ addc_ansible_host }}`). This ensures that the system uses both the local host and the managed DNS server for DNS resolution. --- defaults/main.yml | 43 ++++---- handlers/main.yml | 12 ++- tasks/0backupcheck.yml | 56 +++++++++++ tasks/dns_hosts.yml | 29 ------ tasks/dns_hosts_restore.yml | 11 --- tasks/install.yml | 73 ++++++++------ tasks/kerberos.yml | 15 ++- tasks/main.yml | 26 +++-- tasks/ntpd.yml | 54 +++++++++++ tasks/preparing.yml | 112 +++++++++++++++++++++ tasks/provision.yml | 44 +++------ tasks/remove.yml | 39 -------- tasks/setupresolver.yml | 8 ++ tasks/verify.yml | 189 ++++++++++++++++++++++++++++++------ templates/krb5.conf.j2 | 17 ---- templates/ntp.conf.j2 | 37 +++++++ templates/resolv.conf.j2 | 8 +- templates/smb.conf.j2 | 15 --- 18 files changed, 549 insertions(+), 239 deletions(-) create mode 100644 tasks/0backupcheck.yml delete mode 100644 tasks/dns_hosts.yml delete mode 100644 tasks/dns_hosts_restore.yml create mode 100644 tasks/ntpd.yml create mode 100644 tasks/preparing.yml delete mode 100644 tasks/remove.yml create mode 100644 tasks/setupresolver.yml delete mode 100644 templates/krb5.conf.j2 create mode 100644 templates/ntp.conf.j2 delete mode 100644 templates/smb.conf.j2 diff --git a/defaults/main.yml b/defaults/main.yml index 59629d7..b54aed1 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,25 +1,30 @@ -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 }}" +# Hostname = DC1 +addc_hostname: "DC1" +# DC local IP Address = 10.99.0.1 +addc_ansible_host: "10.99.0.1" +# NetBIOS domain name (Workgroup). +addc_netbios_domain: "SAMDOM" +# Top level Domain = EXAMPLE.COM +addc_tld: "EXAMPLE.COM" +# Authentication Domain = SAMDOM.EXAMPLE.COM +addc_auth_domain: "{{ adc_netbios_domain | upper }}.{{ addc_tld | upper }}" -samba_log_dir: /var/log/samba -samba_provision_log_file: "{{ samba_log_dir }}/ad_provision.log" -# allows skipping verification when needed -samba_verify: true +addc_admin_password: "Passw0rd" +addc_dns_backend: "SAMBA_INTERNAL" +addc_server_role: "dc" + + + +addc_ip_network_prefix: "{{ addc_ansible_host.split('.')[:3] | join('.') }}" +addc_ip_last_octet: "{{ addc_ansible_host.split('.')[-1] }}" +addc_reverse_zone_name: "{{ addc_ip_network_prefix.split('.') | reverse | join('.') }}.in-addr.arpa" +addc_tld: "{{ addc_auth_domain | lower }}" + # 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" +location_internal_dns: 192.168.2.100 +location_external_dns: 8.8.8.8 +backup_path: "/path/to/your/backup/directory" \ No newline at end of file diff --git a/handlers/main.yml b/handlers/main.yml index e8d8e86..4b9c1c0 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,5 +1,15 @@ --- +- name: Restart NetworkManager + ansible.builtin.systemd: + name: NetworkManager + state: restarted + - name: Restart Samba AD DC - service: + ansible.builtin.service: name: samba-ad-dc state: restarted + +- name: Restart ntp service + ansible.builtin.service: + name: ntp + state: restarted \ No newline at end of file diff --git a/tasks/0backupcheck.yml b/tasks/0backupcheck.yml new file mode 100644 index 0000000..077dce8 --- /dev/null +++ b/tasks/0backupcheck.yml @@ -0,0 +1,56 @@ +--- +- name: Check if backup directory exists + stat: + path: "{{ backup_path }}" + register: backup_dir_stat + +- name: Check if backup directory is not empty + find: + paths: "{{ backup_path }}" + file_type: any + recurse: false + when: backup_dir_stat.stat.exists and backup_dir_stat.stat.isdir + register: backup_dir_contents + + +- name: Check if each required file exists + stat: + path: "{{ dir_path }}/{{ item }}" + loop: "{{ backup_required_files }}" + register: required_file_stats + +- name: Determine missing files + set_fact: + missing_files: >- + {{ required_file_stats.results + | selectattr('stat.exists', 'equalto', false) + | map(attribute='item') + | list }} + +- name: Set fact if all required files are present + set_fact: + all_required_files_present: true + when: missing_files | length == 0 + +- name: Debug - Show status + debug: + msg: >- + {% if all_required_files_present | default(false) %} + All required files are present. + {% else %} + Missing required files: {{ missing_files }} + {% endif %} + +- name: Set fact if backup directory exists and is not empty + set_fact: + backup_dir_valid: true + when: + - backup_dir_stat.stat.exists + - backup_dir_stat.stat.isdir + - backup_dir_contents.matched | int > 0 + - all_required_files_present + +- name: Debug - Show final result + debug: + msg: "Backup directory exists and is not empty." + when: backup_dir_valid | default(false) diff --git a/tasks/dns_hosts.yml b/tasks/dns_hosts.yml deleted file mode 100644 index dedb15b..0000000 --- a/tasks/dns_hosts.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -- 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 - diff --git a/tasks/dns_hosts_restore.yml b/tasks/dns_hosts_restore.yml deleted file mode 100644 index 43cb601..0000000 --- a/tasks/dns_hosts_restore.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- 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 diff --git a/tasks/install.yml b/tasks/install.yml index aa7e228..c949ca1 100644 --- a/tasks/install.yml +++ b/tasks/install.yml @@ -1,47 +1,62 @@ --- - name: Install required packages - apt: + ansible.builtin.package: name: + - acl + - attr - samba + - winbind + - libpam-winbind + - libnss-winbind - krb5-config - krb5-user - - winbind - - smbclient - - dnsutils - state: present - update_cache: yes + - dnsutils + - python3-setproctitle + # - smbclient + - ntp + state: latest - name: Stop samba-ad-dc before provisioning (if running) - service: + ansible.builtin.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 + + + +# - name: Check if backup exist + +# - name: Provision AD domain +# include_tasks: provision.yml + +# - name: Deploy smb.conf +# ansible.builtin.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 +# ansible.builtin.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 diff --git a/tasks/kerberos.yml b/tasks/kerberos.yml index 8faab3d..9ab994c 100644 --- a/tasks/kerberos.yml +++ b/tasks/kerberos.yml @@ -1,8 +1,17 @@ --- -- name: Configure Kerberos (krb5.conf) - template: - src: krb5.conf.j2 +- name: Extract krb5.conf path from provision output + # The samba-tool output usually contains the path on a specific line. + # We extract the path using regex and the 'search' filter. + ansible.builtin.set_fact: + krb5_conf_path: "{{ samba_provision_output.stdout | regex_search('krb5.conf file is located at (.*)', '\\1') | first }}" + when: samba_provision_output.stdout is defined + +- name: Copy krb5.conf to /etc/krb5.conf + ansible.builtin.copy: + src: "{{ krb5_conf_path }}" dest: /etc/krb5.conf owner: root group: root mode: '0644' + # Only run this if the provision was successful (changed) + when: samba_provision_output.changed \ No newline at end of file diff --git a/tasks/main.yml b/tasks/main.yml index 4d367ec..20a15cf 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,9 +1,23 @@ --- -- name: Install or remove Samba AD DC - include_tasks: install.yml - when: samba_ad_dc_state == 'present' +- name: Prepare for Samba AD DC + include_tasks: preparing.yml -- name: Remove Samba AD DC - include_tasks: remove.yml - when: samba_ad_dc_state == 'absent' +- name: Install + include_tasks: install.yml + +- name: Provision + include_tasks: provision.yml + +- name: Setup DNS resolver + include_tasks: setupresolver.yml + +- name: Configure Kerberos + include_tasks: kerberos.yml + +- name: Testing Samba AD DC + include_tasks: verify.yml + +- name: Configure Time Synchronization + include_tasks: ntpd.yml + \ No newline at end of file diff --git a/tasks/ntpd.yml b/tasks/ntpd.yml new file mode 100644 index 0000000..95ba29a --- /dev/null +++ b/tasks/ntpd.yml @@ -0,0 +1,54 @@ +--- +- name: Ensure the ntp package is installed + ansible.builtin.package: + name: ntp + state: present + +- name: Search common Samba locations for the 'ntp_signd' directory + ansible.builtin.find: + paths: + # Common paths for Samba installations + - /var/lib/samba/ + - /usr/local/samba/ + - /etc/samba/ + pattern: ntp_signd + file_type: directory + register: find_ntp_signd + +- name: Set the path variable, failing if not found + ansible.builtin.set_fact: + ntp_signd_path: "{{ find_ntp_signd.files[0].path }}" + # This conditional logic ensures the playbook stops if the directory is missing, + # or if more than one directory named 'ntp_signd' is found (which is unlikely/undesirable). + when: find_ntp_signd.matched == 1 + failed_when: find_ntp_signd.matched != 1 + +- name: Verify permissions on the detected 'ntp_signd' directory + ansible.builtin.stat: + path: "{{ ntp_signd_path }}" + register: ntp_signd_stats + +- name: Assert that the permissions allow read access + ansible.builtin.assert: + that: + # Check if the directory exists and has permissions that grant read/execute to 'other' (r-x) + - ntp_signd_stats.stat.exists + - ntp_signd_stats.stat.mode is search('[rwx-]{2}[rwx-]{2}[4-7]') + fail_msg: "FATAL: The detected ntp_signd directory ({{ ntp_signd_path }}) does not have necessary read permissions (mode: {{ ntp_signd_stats.stat.mode }})." + success_msg: "SUCCESS: Permissions on {{ ntp_signd_path }} are correctly configured." + +- name: Configure ntp.conf for Active Directory Domain Controller (AD DC) + ansible.builtin.template: + src: templates/ntp.conf.j2 # Path to your NTP template file + dest: /etc/ntp.conf + owner: root + group: root + mode: '0644' + notify: + - Restart ntp service + +- name: Enable and start the ntp service + ansible.builtin.service: + name: ntp + state: started + enabled: true \ No newline at end of file diff --git a/tasks/preparing.yml b/tasks/preparing.yml new file mode 100644 index 0000000..f3616a8 --- /dev/null +++ b/tasks/preparing.yml @@ -0,0 +1,112 @@ +--- +# Disable tools, such as resolvconf, that automatically update your /etc/resolv.conf DNS resolver configuration file +- name: Stop and disable systemd-resolved if present + ansible.builtin.systemd: + name: systemd-resolved + enabled: false + state: stopped + when: ansible_facts.services['systemd-resolved.service'] is defined + +- name: Remove /etc/resolv.conf if it's a symlink to systemd-resolved + ansible.builtin.file: + path: /etc/resolv.conf + state: absent + when: "'/run/systemd/resolve' in ansible_facts.lsb.description | default('')" + +- name: Create static /etc/resolv.conf + ansible.builtin.copy: + dest: /etc/resolv.conf + content: | + nameserver {{ location_internal_dns }} + nameserver {{ location_external_dns }} + owner: root + group: root + mode: '0644' + +- name: Disable resolvconf package (if installed) + ansible.builtin.package: + name: resolvconf + state: absent + +- name: Disable DNS updates from NetworkManager (if present) + ansible.builtin.blockinfile: + path: /etc/NetworkManager/NetworkManager.conf + block: | + [main] + dns=none + notify: Restart NetworkManager + when: ansible_facts.services['NetworkManager.service'] is defined + +- name: Prevent dhclient from modifying resolv.conf (if present) + ansible.builtin.lineinfile: + path: /etc/dhcp/dhclient.conf + regexp: '^#?supersede domain-name-servers' + line: 'supersede domain-name-servers {{ location_internal_dns }}, {{ location_external_dns }};' + create: yes + +# Verify that the /etc/hosts file on the DC correctly resolves the fully-qualified domain name (FQDN) and short host name to the LAN IP address of the DC +- name: Set /etc/hosts entry for Samba AD DC + ansible.builtin.lineinfile: + path: /etc/hosts + line: "{{ addc_ansible_host }} {{ addc_hostname | upper }}.{{ addc_tld }} {{ addc_hostname | upper }}" + state: present + create: yes + +- name: Ensure '127.0.0.1 localhost' is present and nothing else on that line + ansible.builtin.lineinfile: + path: /etc/hosts + regexp: '^127\.0\.0\.1\s+' + line: '127.0.0.1 localhost' + state: present + +# Remove any existing smb.conf file +- name: Get compiled default smb.conf path from smbd + ansible.builtin.shell: smbd -b | grep CONFIGFILE | awk '{print $2}' + register: smb_conf_path + changed_when: false + failed_when: smb_conf_path.rc != 0 + +- name: Remove smb.conf using discovered path + ansible.builtin.file: + path: "{{ smb_conf_path.stdout }}" + state: absent + +# Remove all Samba database files, such as *.tdb and *.ldb files +- name: Get Samba directories from smbd -b + ansible.builtin.shell: smbd -b | egrep "LOCKDIR|STATEDIR|CACHEDIR|PRIVATE_DIR" | awk '{print $2}' + register: samba_dirs + changed_when: false + failed_when: samba_dirs.rc != 0 + +- name: Filter existing directories + ansible.builtin.find: + paths: "{{ item }}" + file_type: directory + recurse: no + loop: "{{ samba_dirs.stdout_lines }}" + register: existing_dirs + +- name: Collect existing directories + ansible.builtin.set_fact: + valid_dirs: "{{ existing_dirs.results | selectattr('matched', '>', 0) | map(attribute='files') | sum(start=[]) | map(attribute='path') | list }}" + +- name: Find *.tdb and *.ldb files + ansible.builtin.find: + paths: "{{ item }}" + patterns: "*.tdb,*.ldb" + recurse: yes + use_regex: false + loop: "{{ valid_dirs }}" + register: db_files + +- name: Remove found tdb/ldb files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ db_files.results | map(attribute='files') | sum(start=[]) }}" + when: item.path is defined + +- name: Report removed files + ansible.builtin.debug: + msg: "Removed: {{ item.path }}" + loop: "{{ db_files.results | map(attribute='files') | sum(start=[]) }}" \ No newline at end of file diff --git a/tasks/provision.yml b/tasks/provision.yml index a7757ad..9a19240 100644 --- a/tasks/provision.yml +++ b/tasks/provision.yml @@ -1,37 +1,15 @@ --- ---- -- 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: > +- name: Provision the Samba AD DC + ansible.builtin.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 }}" + --realm={{ addc_auth_domain }} + --domain={{ addc_netbios_domain }} + --server-role={{ addc_server_role }} + --dns-backend={{ addc_dns_backend }} + --adminpass={{ addc_admin_password }} + --option="interfaces=lo eth0" + --option="bind interfaces only=yes" 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=********" + changed_when: samba_provision_output.rc == 0 + no_log: true # You may toggle this if password should be hidden diff --git a/tasks/remove.yml b/tasks/remove.yml deleted file mode 100644 index c66804b..0000000 --- a/tasks/remove.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- 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 diff --git a/tasks/setupresolver.yml b/tasks/setupresolver.yml new file mode 100644 index 0000000..d0b04f3 --- /dev/null +++ b/tasks/setupresolver.yml @@ -0,0 +1,8 @@ +--- +- name: Template /etc/resolv.conf with custom DNS nameservers + template: + src: resolv.conf.j2 + dest: /etc/resolv.conf + owner: root + group: root + mode: '0644' diff --git a/tasks/verify.yml b/tasks/verify.yml index 20f632b..9f1b7a2 100644 --- a/tasks/verify.yml +++ b/tasks/verify.yml @@ -1,40 +1,165 @@ --- -- name: Verify Samba AD DC setup - when: samba_verify | bool - block: +- name: Start the samba service + ansible.builtin.service: + name: samba + state: started + enabled: true - - name: Run 'samba-tool domain info' - command: samba-tool domain info 127.0.0.1 - register: domain_info - changed_when: false +- name: Create the reverse DNS zone {{ addc_reverse_zone_name }} + community.general.expect: + # Note: The 'expect' module is in the 'community.general' collection + command: "samba-tool dns zonecreate {{ addc_ansible_host }} {{ addc_reverse_zone_name }} -U Administrator" + responses: + # Use the '(?i)' flag for case-insensitive matching of the prompt. + '(?i)password for.*:': "{{ addc_admin_password }}" + no_log: true # Highly recommended to prevent the password from appearing in logs - - 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: Create the PTR (reverse) DNS record + community.general.expect: + # Command syntax: samba-tool dns add PTR + command: > + samba-tool dns add {{ addc_ansible_host }} + {{ addc_reverse_zone_name }} + {{ addc_ip_last_octet }} PTR + {{ addc_hostname | lower }}.{{ addc_tld }} + -U Administrator + responses: + # Expects the standard Samba password prompt + '(?i)password for.*:': "{{ addc_admin_password }}" + no_log: true # Hide sensitive data from logs - - 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: Verify Samba file server by listing local shares + ansible.builtin.command: smbclient -L localhost -N + register: smbclient_output + changed_when: false # This is a verification step, it doesn't change the host state - - name: Assert Kerberos ticket exists - assert: - that: - - "'krbtgt/{{ samba_realm }}@{{ samba_realm }}' in klist_result.stdout" +- name: Report the results of the smbclient verification + ansible.builtin.debug: + msg: "Samba Shares found: {{ smbclient_output.stdout }}" - - name: Check Samba AD DC service status - service_facts: +- name: Verify Samba AD authentication by accessing the netlogon share + community.general.expect: + # Command to run: smbclient //localhost/netlogon -UAdministrator -c 'ls' + # The -c 'ls' command lists files on the share. + command: smbclient //localhost/netlogon -UAdministrator -c 'ls' + responses: + # Use the (?i) flag for case-insensitive matching of the prompt. + '(?i)password:': "{{ addc_admin_password }}" + no_log: true # CRITICAL: Prevents the password from being logged + register: auth_verification + changed_when: false # This is a verification/check, not a change - - 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' + +- name: Verify LDAP Service Record (SRV _ldap._tcp) + ansible.builtin.command: host -t SRV _ldap._tcp.{{ addc_tld }}. + register: ldap_srv_check + changed_when: false + failed_when: "'has SRV record' not in ldap_srv_check.stdout" + +- name: Debug - Show LDAP SRV check result + ansible.builtin.debug: + var: ldap_srv_check.stdout + + +- name: Verify Kerberos Service Record (SRV _kerberos._udp) + ansible.builtin.command: host -t SRV _kerberos._udp.{{ addc_tld }}. + register: kerberos_srv_check + changed_when: false + failed_when: "'has SRV record' not in kerberos_srv_check.stdout" + +- name: Debug - Show Kerberos SRV check result + ansible.builtin.debug: + var: kerberos_srv_check.stdout + + +- name: Verify DC's A (Forward) Record + ansible.builtin.command: host -t A {{ addc_hostname | lower }}.{{ addc_tld }}. + register: a_record_check + changed_when: false + failed_when: "{{ addc_ansible_host }} not in a_record_check.stdout" + +- name: Debug - Show A Record check result + ansible.builtin.debug: + var: a_record_check.stdout + + +- name: Verify DC's PTR (Reverse) Record + ansible.builtin.command: host -t PTR {{ addc_ansible_host }} + register: ptr_record_check + changed_when: false + # Assuming dc1.{{ addc_tld }} is the expected output for the reverse record + failed_when: "'domain name pointer {{ addc_hostname | lower }}.{{ addc_tld }}' not in ptr_record_check.stdout" + +- name: Debug - Show PTR Record check result + ansible.builtin.debug: + var: ptr_record_check.stdout + +- name: Verify Kerberos authentication using kinit + community.general.expect: + # Command to run: kinit administrator + command: kinit administrator + responses: + # Expects the standard Kerberos password prompt + # The (?i) flag ensures case-insensitive matching. + '(?i)password for administrator.*:': "{{ addc_admin_password }}" + no_log: true # CRITICAL: Prevents the password from being logged + register: kinit_check + changed_when: false # This is a verification/check, not a change + +- name: Debug - Show kinit verification result (should be empty on success) + ansible.builtin.debug: + msg: "Kerberos kinit verification successful. Output: {{ kinit_check.stdout }}" + +- name: Optional: Show the cached Kerberos ticket + ansible.builtin.command: klist + register: klist_output + changed_when: false + when: kinit_check is succeeded + +- name: Debug - Show klist output + ansible.builtin.debug: + var: klist_output.stdout + when: klist_check is defined + + + + + + + +# - 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' diff --git a/templates/krb5.conf.j2 b/templates/krb5.conf.j2 deleted file mode 100644 index c7af8c5..0000000 --- a/templates/krb5.conf.j2 +++ /dev/null @@ -1,17 +0,0 @@ -[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 }} diff --git a/templates/ntp.conf.j2 b/templates/ntp.conf.j2 new file mode 100644 index 0000000..051b563 --- /dev/null +++ b/templates/ntp.conf.j2 @@ -0,0 +1,37 @@ +# This configuration file is managed by Ansible. +# It is configured to run as an Active Directory Domain Controller. + +# Enable kernel time discipline (important for a DC) +tos maxclock 10 + +# Use your own local clock as a reliable fallback/default +# Local clock. Note that is not the "localhost" address! +server 127.127.1.0 # Undisciplined local clock +fudge 127.127.1.0 stratum 10 + +# Where to retrieve the time from +# Optionally, add external sources for greater accuracy (NTP pool) +# You should choose servers close to your location or use a reliable pool. +server 0.pool.ntp.org iburst prefer +server 1.pool.ntp.org iburst prefer +server 1.pool.ntp.org iburst prefer + +# Drift file location +driftfile /var/lib/ntp/ntp.drift +logfile /var/log/ntp +ntpsigndsocket {{ ntp_signd_path }} + +# Access control +# Default restriction: Allow clients only to query the time +restrict default kod nomodify notrap nopeer limited mssntp + +# No restrictions for "localhost" +restrict 127.0.0.1 + +# Enable the time sources to only provide time to this host +restrict 0.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery +restrict 1.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery +restrict 2.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery + +# tell NTP not to panic and exit +tinker panic 0 \ No newline at end of file diff --git a/templates/resolv.conf.j2 b/templates/resolv.conf.j2 index 5121f74..5320276 100644 --- a/templates/resolv.conf.j2 +++ b/templates/resolv.conf.j2 @@ -1,5 +1,3 @@ -# Managed by Ansible - Samba AD DC DNS - -{% for ns in samba_dns_nameservers %} -nameserver {{ ns }} -{% endfor %} +# Managed by Ansible - Samba AD DC DNS- DO NOT EDIT MANUALLY +search {{ addc_tld }} +nameserver {{ addc_ansible_host }} \ No newline at end of file diff --git a/templates/smb.conf.j2 b/templates/smb.conf.j2 deleted file mode 100644 index 4ea2c97..0000000 --- a/templates/smb.conf.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[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