--- # Bootstrap nového Ubuntu serveru # - aktualizace systému # - deploy user (UID 1000) # - SSH hardening # - UFW firewall # - fail2ban # - Docker # # Použití: # ansible-playbook -i inventory.yml playbooks/bootstrap-server.yml # - name: Bootstrap home server hosts: homeservers become: true gather_facts: true vars: deploy_user: deploy deploy_uid: 1000 ssh_port: 22 deploy_ssh_key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}" tasks: - name: Update apt cache ansible.builtin.apt: update_cache: true cache_valid_time: 3600 - name: Upgrade all packages ansible.builtin.apt: upgrade: dist update_cache: true - name: Install base packages ansible.builtin.apt: name: - curl - wget - git - vim - htop - ca-certificates - gnupg - ufw - fail2ban - bash-completion state: present - name: Set timezone community.general.timezone: name: "{{ timezone }}" - name: Create deploy user ansible.builtin.user: name: "{{ deploy_user }}" uid: "{{ deploy_uid }}" shell: /bin/bash create_home: true password: "" - name: Setup authorized_keys for deploy user ansible.posix.authorized_key: user: "{{ deploy_user }}" state: present key: "{{ deploy_ssh_key }}" - name: Allow deploy user sudo without password ansible.builtin.copy: dest: "/etc/sudoers.d/{{ deploy_user }}" content: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL\n" mode: "0440" - name: SSH hardening ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#?{{ item.key }}" line: "{{ item.key }} {{ item.value }}" state: present loop: - { key: "Port", value: "{{ ssh_port }}" } - { key: "PermitRootLogin", value: "no" } - { key: "PasswordAuthentication", value: "no" } - { key: "X11Forwarding", value: "no" } - { key: "ClientAliveInterval", value: "300" } - { key: "ClientAliveCountMax", value: "2" } notify: Restart ssh - name: Configure UFW defaults community.general.ufw: direction: incoming policy: deny notify: Reload ufw - name: Allow SSH through UFW community.general.ufw: rule: allow port: "{{ ssh_port }}" proto: tcp - name: Allow HTTP and HTTPS through UFW community.general.ufw: rule: allow port: "{{ item }}" proto: tcp loop: - "80" - "443" - name: Enable UFW community.general.ufw: state: enabled - name: Configure fail2ban ansible.builtin.copy: dest: /etc/fail2ban/jail.local content: | [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 [sshd] enabled = true port = {{ ssh_port }} filter = sshd logpath = /var/log/auth.log maxretry = 3 mode: "0644" notify: Restart fail2ban handlers: - name: Restart ssh ansible.builtin.service: name: sshd state: restarted - name: Reload ufw community.general.ufw: state: reloaded - name: Restart fail2ban ansible.builtin.service: name: fail2ban state: restarted