# ============================================================
# Security Bootstrap Playbook
# Εκτελέστε ΠΡΩΤΑ σε κάθε νέο managed server
# Συμβατό με: Debian/Ubuntu, RedHat/Rocky, openSUSE
# ============================================================

- name: Security Bootstrap για νέους servers
  hosts: "{{ target | default('all_managed') }}"
  become: true
  gather_facts: true

  vars:
    # SSH ρυθμίσεις
    ssh_port: 2022
    ssh_permit_root_login: "no"
    ssh_password_authentication: "no"
    ssh_allowed_users: "ansible"

    # Firewall ports
    firewall_allowed_tcp_ports:
      - "{{ ssh_port }}"
      - "80"
      - "443"

  # ══════════════════════════════════════════
  # TASKS
  # ══════════════════════════════════════════
  tasks:

    # ── Εμφάνιση πληροφοριών server ──────────
    - name: Εμφάνιση πληροφοριών server
      ansible.builtin.debug:
        msg:
          - "Hostname    : {{ ansible_facts['hostname'] }}"
          - "OS Family   : {{ ansible_facts['os_family'] }}"
          - "Distribution: {{ ansible_facts['distribution'] }}"
          - "Version     : {{ ansible_facts['distribution_version'] }}"

    # ══════════════════════════════════════════
    # ΕΝΗΜΕΡΩΣΗ ΣΥΣΤΗΜΑΤΟΣ
    # ══════════════════════════════════════════

    # ── Debian/Ubuntu ─────────────────────────
    - name: Update apt cache (Debian/Ubuntu)
      ansible.builtin.apt:
        update_cache: true
        cache_valid_time: 3600
      when: ansible_facts['os_family'] == "Debian"

    # ── RedHat based ──────────────────────────
    - name: Update dnf cache (RedHat)
      ansible.builtin.dnf:
        update_cache: true
      when: ansible_facts['os_family'] == "RedHat"

    # ── openSUSE ──────────────────────────────
    - name: Update zypper cache (openSUSE)
      community.general.zypper:
        name: "*"
        state: latest
      when: ansible_facts['os_family'] == "Suse"

    # ══════════════════════════════════════════
    # ΕΓΚΑΤΑΣΤΑΣΗ PACKAGES
    # ══════════════════════════════════════════

    # ── Κοινά packages για Debian/Ubuntu ──────
    - name: Εγκατάσταση packages (Debian/Ubuntu)
      ansible.builtin.apt:
        name:
          - ferm
          - fail2ban
          - curl
          - vim
          - ufw
        state: present
      when: ansible_facts['os_family'] == "Debian"

    # ── Κοινά packages για RedHat ─────────────
    - name: Εγκατάσταση packages (RedHat)
      ansible.builtin.dnf:
        name:
          - fail2ban
          - curl
          - vim
          - firewalld
        state: present
      when: ansible_facts['os_family'] == "RedHat"

    # ── Κοινά packages για openSUSE ───────────
    - name: Εγκατάσταση packages (openSUSE)
      community.general.zypper:
        name:
          - fail2ban
          - curl
          - vim
          - firewalld
        state: present
      when: ansible_facts['os_family'] == "Suse"

    # ══════════════════════════════════════════
    # SSH CONFIGURATION
    # ══════════════════════════════════════════

    - name: Ρύθμιση SSH - αλλαγή port
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?Port '
        line: "Port {{ ssh_port }}"
        state: present
        backup: true       # ← δημιουργεί backup πριν αλλάξει!
      notify: Restart SSH  # ← καλεί τον handler

    - name: Ρύθμιση SSH - απενεργοποίηση root login
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?PermitRootLogin'
        line: "PermitRootLogin {{ ssh_permit_root_login }}"
        state: present
      notify: Restart SSH

    - name: Ρύθμιση SSH - μόνο key authentication
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?PasswordAuthentication'
        line: "PasswordAuthentication {{ ssh_password_authentication }}"
        state: present
      notify: Restart SSH

    - name: Ρύθμιση SSH - επιτρεπόμενοι χρήστες
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?AllowUsers'
        line: "AllowUsers {{ ssh_allowed_users }}"
        state: present
      notify: Restart SSH

    # ══════════════════════════════════════════
    # FIREWALL - ferm (Debian/Ubuntu)
    # ══════════════════════════════════════════

    - name: Ρύθμιση ferm firewall (Debian/Ubuntu)
      ansible.builtin.copy:
        dest: /etc/ferm/ferm.conf
        backup: true
        mode: '0640'
        content: |
          # Ferm firewall configuration
          # Παράχθηκε από Ansible - ΜΗΝ επεξεργαστείς χειροκίνητα!

          table filter {
            chain INPUT {
              policy DROP;

              # Επιτρέπουμε established connections
              mod state state (ESTABLISHED RELATED) ACCEPT;

              # Loopback interface
              interface lo ACCEPT;

              # ICMP (ping)
              proto icmp ACCEPT;

              # SSH (custom port)
              proto tcp dport {{ ssh_port }} ACCEPT;

              # HTTP & HTTPS
              proto tcp dport (80 443) ACCEPT;
            }

            chain OUTPUT {
              policy ACCEPT;
            }

            chain FORWARD {
              policy DROP;
            }
          }
      when: ansible_facts['os_family'] == "Debian"
      notify: Restart ferm

    # ══════════════════════════════════════════
    # FIREWALL - firewalld (RedHat/openSUSE)
    # ══════════════════════════════════════════

    - name: Εκκίνηση firewalld (RedHat/openSUSE)
      ansible.builtin.service:
        name: firewalld
        state: started
        enabled: true
      when: ansible_facts['os_family'] in ["RedHat", "Suse"]
      ignore_errors: "{{ ansible_check_mode }}"

    - name: Άνοιγμα SSH port στο firewalld
      ansible.posix.firewalld:
        port: "{{ ssh_port }}/tcp"
        permanent: true
        state: enabled
        immediate: true
      when: ansible_facts['os_family'] in ["RedHat", "Suse"]

    - name: Άνοιγμα HTTP στο firewalld
      ansible.posix.firewalld:
        service: http
        permanent: true
        state: enabled
        immediate: true
      when: ansible_facts['os_family'] in ["RedHat", "Suse"]

    - name: Άνοιγμα HTTPS στο firewalld
      ansible.posix.firewalld:
        service: https
        permanent: true
        state: enabled
        immediate: true
      when: ansible_facts['os_family'] in ["RedHat", "Suse"]

    - name: Κλείσιμο default SSH port 22 στο firewalld
      ansible.posix.firewalld:
        service: ssh
        permanent: true
        state: disabled
        immediate: true
      when: ansible_facts['os_family'] in ["RedHat", "Suse"]

    # ══════════════════════════════════════════
    # FAIL2BAN
    # ══════════════════════════════════════════

    - name: Ρύθμιση fail2ban
      ansible.builtin.copy:
        dest: /etc/fail2ban/jail.local
        backup: true
        mode: '0644'
        content: |
          # Fail2ban configuration
          # Παράχθηκε από Ansible - ΜΗΝ επεξεργαστείς χειροκίνητα!

          [DEFAULT]
          # Ban για 1 ώρα
          bantime  = 3600
          # Παράθυρο ελέγχου 10 λεπτά
          findtime = 600
          # Μέγιστες αποτυχημένες προσπάθειες
          maxretry = 5
          # Backend
          backend  = systemd

          [sshd]
          enabled  = true
          port     = {{ ssh_port }}
          logpath  = %(sshd_log)s
          maxretry = 3
      notify: Restart fail2ban

    - name: Εκκίνηση fail2ban
      ansible.builtin.service:
        name: fail2ban
        state: started
        enabled: true
      ignore_errors: "{{ ansible_check_mode }}"

    # ══════════════════════════════════════════
    # ΤΕΛΙΚΟ ΜΗΝΥΜΑ
    # ══════════════════════════════════════════

    - name: Security Bootstrap ολοκληρώθηκε!
      ansible.builtin.debug:
        msg:
          - "✅ SSH port αλλαχθηκε σε: {{ ssh_port }}"
          - "✅ Root login: απενεργοποιημένο"
          - "✅ Password auth: απενεργοποιημένη"
          - "✅ Firewall: ενεργό"
          - "✅ Fail2ban: ενεργό"
          - "⚠️  ΣΗΜΑΝΤΙΚΟ: Ενημέρωσε το inventory!"
          - "⚠️  ansible_port = {{ ssh_port }}"

  # ══════════════════════════════════════════
  # HANDLERS
  # ══════════════════════════════════════════
  handlers:

    - name: Restart SSH
      ansible.builtin.service:
        name: "{{ 'ssh' if ansible_facts['os_family'] == 'Debian' else 'sshd' }}"
        state: restarted
      ignore_errors: "{{ ansible_check_mode }}"

    - name: Restart ferm
      ansible.builtin.service:
        name: ferm
        state: restarted
      ignore_errors: "{{ ansible_check_mode }}"

    - name: Restart fail2ban
      ansible.builtin.service:
        name: fail2ban
        state: restarted
      ignore_errors: "{{ ansible_check_mode }}"
