--- - name: "Demo: Ubuntu SSH and nginx checks" hosts: linux_vms gather_facts: true become: false vars: report_dir: "./artifacts/raw/ansible" pre_tasks: - name: "Ensure report directory exists" ansible.builtin.file: path: "{{ report_dir }}" state: directory mode: "0755" delegate_to: localhost run_once: true tasks: - name: "Gather SSH effective configuration" ansible.builtin.shell: grep -Ei '^(PasswordAuthentication|PermitRootLogin)' /etc/ssh/sshd_config register: sshd_config changed_when: false - name: "Record SSH password authentication result" ansible.builtin.set_fact: test_results: "{{ test_results | default([]) + [{ 'test_id': 'DEMO-SSH-01', 'category': 'Secure remote administration', 'requirement': 'IEC 62443-3-3 SR 1.7', 'description': 'SSH password authentication shall be disabled', 'passed': ('passwordauthentication no' in sshd_config.stdout), 'expected': 'PasswordAuthentication no', 'actual': sshd_config.stdout_lines | select('match', '^passwordauthentication ') | first | default('not found'), 'severity': 'high', 'remediation': 'Disable SSH password authentication and use managed keys' }] }}" - name: "Gather nginx configuration" ansible.builtin.shell: grep -E '^[[:space:]]*ssl_(protocols|ciphers)' /etc/nginx/sites-enabled/default register: nginx_config changed_when: false - name: "Record obsolete TLS protocol result" ansible.builtin.set_fact: test_results: "{{ test_results + [{ 'test_id': 'DEMO-TLS-01', 'category': 'Secure communications', 'requirement': 'IEC 62443-3-3 SR 4.1', 'description': 'The web server shall allow only TLS 1.2 and TLS 1.3', 'passed': ('TLSv1 ' not in nginx_config.stdout and 'TLSv1.1' not in nginx_config.stdout), 'expected': 'ssl_protocols TLSv1.2 TLSv1.3', 'actual': nginx_config.stdout_lines | select('search', 'ssl_protocols') | first | default('not found'), 'severity': 'high', 'remediation': 'Remove TLSv1 and TLSv1.1 from ssl_protocols' }] }}" - name: "Record weak CBC cipher result" ansible.builtin.set_fact: test_results: "{{ test_results + [{ 'test_id': 'DEMO-TLS-02', 'category': 'Secure communications', 'requirement': 'IEC 62443-3-3 SR 4.1', 'description': 'The web server shall not enable legacy CBC cipher suites', 'passed': ('AES128-SHA' not in nginx_config.stdout), 'expected': 'Modern AEAD cipher suites only', 'actual': nginx_config.stdout_lines | select('search', 'ssl_ciphers') | first | default('not found'), 'severity': 'medium', 'remediation': 'Use a modern Mozilla intermediate TLS cipher configuration' }] }}" - name: "Check nginx process" ansible.builtin.command: pgrep -x nginx register: nginx_process changed_when: false failed_when: false - name: "Record nginx availability result" ansible.builtin.set_fact: test_results: "{{ test_results + [{ 'test_id': 'DEMO-SVC-01', 'category': 'Service availability', 'requirement': 'IEC 62443-3-3 SR 7.1', 'description': 'The nginx service shall be running', 'passed': (nginx_process.rc == 0), 'expected': 'At least one nginx process', 'actual': nginx_process.stdout | default('not running', true), 'severity': 'medium', 'remediation': 'Start nginx and configure service supervision' }] }}" - name: "Generate raw Ansible report" ansible.builtin.include_tasks: library/report.yml