This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
|
ansible:ansible_playbook_example [2023/04/06 19:52] manu created |
ansible:ansible_playbook_example [2025/01/13 17:22] (current) manu [SSH config] |
||
|---|---|---|---|
| Line 4: | Line 4: | ||
| Install linux LAMP | Install linux LAMP | ||
| + | |||
| + | **rhel-lamp.yaml** | ||
| + | <cli> | ||
| + | --- | ||
| + | - hosts: srv-web01 | ||
| + | handlers: | ||
| + | - name: restart httpd | ||
| + | service: | ||
| + | name: httpd | ||
| + | state: restarted | ||
| + | tasks: | ||
| + | - name: 0. MàJ système | ||
| + | dnf: | ||
| + | name: "*" | ||
| + | state: latest | ||
| + | - name: 1. Installation Apache | ||
| + | dnf: | ||
| + | name: httpd | ||
| + | state: latest | ||
| + | |||
| + | - name: 2. Installation PHP | ||
| + | dnf: | ||
| + | name: php | ||
| + | state: latest | ||
| + | - name: 3. Installation extensions PHP | ||
| + | dnf: | ||
| + | name : | ||
| + | - php-pdo | ||
| + | - php-soap | ||
| + | - php-gd | ||
| + | state: latest | ||
| + | - name: 4. Installation de MariaDB | ||
| + | dnf: | ||
| + | name: mariadb-server | ||
| + | state: latest | ||
| + | - name: 5. Démarrage Apache | ||
| + | service: | ||
| + | name: httpd | ||
| + | state: started | ||
| + | enabled: yes | ||
| + | - name: 6. Démarrage MariaDB | ||
| + | service: | ||
| + | name: mariadb | ||
| + | state: started | ||
| + | enabled: yes | ||
| + | - name: 7. Installation index | ||
| + | copy: | ||
| + | src: rhel-lamp.index.php | ||
| + | dest: /var/www/html/index.php | ||
| + | owner: apache | ||
| + | group: apache | ||
| + | mode: 0644 | ||
| + | |||
| + | - name: 8. Ajout de la regle de parefeu | ||
| + | ansible.posix.firewalld: | ||
| + | zone: public | ||
| + | service: "{{ item }}" | ||
| + | permanent: yes | ||
| + | state: enabled | ||
| + | immediate: yes | ||
| + | with_items: | ||
| + | - http | ||
| + | - https | ||
| + | </cli> | ||
| + | |||
| + | |||
| + | |||
| + | ===== Example with LPAR2RRD ===== | ||
| + | |||
| + | <cli> | ||
| + | > my_project | ||
| + | > group_vars | ||
| + | > host_vars | ||
| + | > roles | ||
| + | > lpar2rrd | ||
| + | > defaults | ||
| + | main.yml | ||
| + | --- | ||
| + | lpar2rrd_version: "7.90" | ||
| + | lpar2rrd_bin: /opt/lpar2rrd/bin/lpar2rrd | ||
| + | lpar2rrd_user: lpar2rrd | ||
| + | lpar2rrd_group: "{{ lpar2rrd_user }}" | ||
| + | lpar2rrd_path: /opt/lpar2rrd | ||
| + | lpar2rrd_src: https://master.dl.sourceforge.net/project/lpar2rrd/lpar2rrd-OSagent/7.90/lpar2rrd-agent-7.90-0.noarch.rpm | ||
| + | > files | ||
| + | > handlers | ||
| + | main.yml | ||
| + | --- | ||
| + | - name: reload_daemon_and_restart_lpar2rrd-agent | ||
| + | systemd: | ||
| + | name: lpar2rrd | ||
| + | state: restarted | ||
| + | daemon_reload: yes | ||
| + | enabled: yes | ||
| + | > meta | ||
| + | > tasks | ||
| + | main.yml | ||
| + | --- | ||
| + | - name: check if lpar2rrd exists | ||
| + | stat: | ||
| + | path: "{{ lpar2rrd_bin }}" | ||
| + | register: __check_lpar2rrd_exist | ||
| + | |||
| + | - name: create lpar2rrd user | ||
| + | user: | ||
| + | name: "{{ lpar2rrd_user }}" | ||
| + | append: true | ||
| + | shell: /usr/sbin/nologin | ||
| + | system: false | ||
| + | create_home: true | ||
| + | home: /home/lpar2rrd | ||
| + | - name: create lpar2rrd dir | ||
| + | file: | ||
| + | path: "{{ lpar2rrd_path }}" | ||
| + | state: directory | ||
| + | owner: "{{ lpar2rrd_user }}" | ||
| + | group: "{{ lpar2rrd_group }}" | ||
| + | - name: download and untar lpar2rrd agent | ||
| + | unarchive: | ||
| + | src: "{{ lpar2rrd_src }}" | ||
| + | dest: /tmp/ | ||
| + | remote_src: yes | ||
| + | validate_certs: false | ||
| + | - name: move binary lpar2rrd agent | ||
| + | copy: | ||
| + | src: "/tmp/{{ }}" | ||
| + | dest: "{{ lpar2rrd_path }}" | ||
| + | owner: "{{ lpar2rrd_user }}" | ||
| + | group: "{{ lpar2rrd_group }}" | ||
| + | mode: 0755 | ||
| + | remote_src: yes | ||
| + | when: __check_lpar2rrd_exist.stat.exists == false | ||
| + | - name: cleanup | ||
| + | file: | ||
| + | path: "/tmp/lpar2rrd*" | ||
| + | state: absent | ||
| + | - name: install template | ||
| + | template: | ||
| + | src: lpar2rrd-agent.service.j2 | ||
| + | dest: /etc/systemd/system/lpar2rrd-agent.service | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: 0755 | ||
| + | notify: reload_daemon_and_restart_lpar2rrd-agent | ||
| + | - meta: flush_handlers | ||
| + | | ||
| + | - name: service always start | ||
| + | systemd: | ||
| + | name: lpar2rrd | ||
| + | state: started | ||
| + | enabled: yes | ||
| + | | ||
| + | | ||
| + | > templates | ||
| + | lpar2rrd-agent.service.j2 | ||
| + | [Unit] | ||
| + | Description=lpar2rrd agent | ||
| + | After=network-online.target | ||
| + | | ||
| + | [Service] | ||
| + | User={{ lpar2rrd_user }} | ||
| + | Group={{ lpar2rrd_group }} | ||
| + | Type=simple | ||
| + | ExecStart={{ lpar2rrd_bin }} | ||
| + | | ||
| + | [Install] | ||
| + | WantedBy=multi-user.target | ||
| + | |||
| + | |||
| + | > tests | ||
| + | > vars | ||
| + | 00_inventory.yml | ||
| + | all: | ||
| + | vars: | ||
| + | ansible_python_interpreter: /usr/bin/python3.9 | ||
| + | hosts: | ||
| + | 10.10.10.1: | ||
| + | 10.10.10.2: | ||
| + | playbook.yml | ||
| + | - name: install lpar2rrd agent | ||
| + | hosts: all | ||
| + | become: yes | ||
| + | roles: | ||
| + | - lpar2rrd | ||
| + | </cli> | ||
| + | |||
| + | ===== SSH config ===== | ||
| + | |||
| + | etc_ssh_sshd_config: /etc/ssh/sshd_config | ||
| + | <code> | ||
| + | - name: check if lpar2rrd exists | ||
| + | stat: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | register: __check_sshd_config_exist__ | ||
| + | |||
| + | - name: Set SSH KexAlgorithms | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | state: present | ||
| + | line: 'KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256' | ||
| + | |||
| + | - name: Set SSH Ciphers | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | state: present | ||
| + | line: 'Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' | ||
| + | |||
| + | - name: Set SSH MACs | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | state: present | ||
| + | line: 'MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com' | ||
| + | |||
| + | - name: Set SSH loglevel to verbose | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | regexp: '^#LogLevel INFO' | ||
| + | line: 'LogLevel VERBOSE' | ||
| + | |||
| + | - name: Set log sftp level file access | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | regexp: '^Subsystem\s+sftp\s+/usr/lib/openssh/sftp-server' | ||
| + | line: 'Subsystem sftp /usr/lib/openssh/sftp-server -f AUTHPRIV -l INFO' | ||
| + | |||
| + | - name: Disable SSH root login | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | regexp: '^#PermitRootLogin' | ||
| + | line: 'PermitRootLogin no' | ||
| + | |||
| + | - name: Disable SSH password authentication | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | regexp: '^#PasswordAuthentication yes' | ||
| + | line: 'PasswordAuthentication no' | ||
| + | |||
| + | - name: Set SSH UsePrivilegeSeparation | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | state: present | ||
| + | line: 'UsePrivilegeSeparation sandbox' | ||
| + | |||
| + | - name: Set SSH AuthenticationMethods | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | state: present | ||
| + | line: 'AuthenticationMethods publickey' | ||
| + | |||
| + | # Here you should use your custom port! | ||
| + | - name: Setup alternate SSHd port | ||
| + | lineinfile: | ||
| + | dest: "{{ etc_ssh_sshd_config }}" | ||
| + | regexp: '^#Port' | ||
| + | line: 'Port 4242' | ||
| + | </code> | ||
| + | |||
| + | Using a loop: | ||
| + | <code> | ||
| + | - name: Configure sshd | ||
| + | lineinfile: | ||
| + | path: "{{ etc_ssh_sshd_config }}" | ||
| + | regex: "^(#)?{{item.key}}" | ||
| + | line: "{{item.key}} {{item.value}}" | ||
| + | state: present | ||
| + | loop: | ||
| + | - { key: "PermitRootLogin", value: "no" } | ||
| + | - { key: "PasswordAuthentication", value: "no" } | ||
| + | notify: | ||
| + | - restart sshd | ||
| + | </code> | ||
| + | |||
| + | <code> | ||
| + | - hosts: all | ||
| + | become: yes | ||
| + | become_user: root | ||
| + | become_method: sudo | ||
| + | remote_user: admin | ||
| + | |||
| + | vars: | ||
| + | syslog_facility: AUTHPRIV | ||
| + | log_level: INFO | ||
| + | | ||
| + | tasks: | ||
| + | - name: Get the Active IP address | ||
| + | shell: hostname -I|cut -d " " -f1 | ||
| + | register: get_ip | ||
| + | |||
| + | - set_fact: | ||
| + | IP={{ get_ip.stdout }} | ||
| + | | ||
| + | - name: Change SSH daemon configuration | ||
| + | lineinfile: | ||
| + | line: "{{ item.line }}" | ||
| + | regexp: "{{ item.regexp }}" | ||
| + | path: /etc/ssh/sshd_config | ||
| + | loop: | ||
| + | - line: 'AddressFamily inet' | ||
| + | regexp: '^(#)?AddressFamily' | ||
| + | |||
| + | - line: 'ListenAddress {{IP}}' | ||
| + | regexp: '^(#)?ListenAddress' | ||
| + | |||
| + | - line: 'SyslogFacility {{ syslog_facility }}' | ||
| + | regexp: '^(#)?SyslogFacility' | ||
| + | |||
| + | - line: 'LogLevel {{ log_level }}' | ||
| + | regexp: '^(#)?LogLevel' | ||
| + | |||
| + | - line: 'PermitRootLogin no' | ||
| + | regexp: '^(#)?PermitRootLogin' | ||
| + | |||
| + | - line: 'MaxAuthTries 3' | ||
| + | regexp: '^(#)?MaxAuthTries' | ||
| + | |||
| + | - line: 'HostbasedAuthentication no' | ||
| + | regexp: '^(#)?HostbasedAuthentication' | ||
| + | |||
| + | - line: 'IgnoreRhosts no' | ||
| + | regexp: '^(#)?IgnoreRhosts' | ||
| + | |||
| + | - line: 'PermitEmptyPasswords no' | ||
| + | regexp: '^(#)?PermitEmptyPasswords' | ||
| + | |||
| + | - line: 'PasswordAuthentication yes' | ||
| + | regexp: '^(#)?PasswordAuthentication' | ||
| + | |||
| + | - line: 'X11Forwarding no' | ||
| + | regexp: '^(#)?X11Forwarding' | ||
| + | |||
| + | - line: 'PermitUserEnvironment no' | ||
| + | regexp: '^(#)?PermitUserEnvironment' | ||
| + | |||
| + | - line: 'ClientAliveInterval 900' | ||
| + | regexp: '^(#)?ClientAliveInterval' | ||
| + | |||
| + | - line: 'ClientAliveCountMax 0' | ||
| + | regexp: '^(#)?ClientAliveCountMax' | ||
| + | |||
| + | - line: 'UseDNS no' | ||
| + | regexp: '^(#)?UseDNS' | ||
| + | |||
| + | - line: 'Banner /etc/issue.net' | ||
| + | regexp: '^(#)?Banner' | ||
| + | |||
| + | - line: 'Subsystem sftp /usr/libexec/openssh/sftp-server -f {{ syslog_facility }} -l {{ log_level }}' | ||
| + | regexp: '^(#)?Subsystem' | ||
| + | |||
| + | - name: Set secure HostKeyAlgorithms | ||
| + | lineinfile: | ||
| + | path: /etc/ssh/sshd_config | ||
| + | insertafter: '^#RekeyLimit default none' | ||
| + | line: 'HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256' | ||
| + | state: present | ||
| + | |||
| + | - name: Set secure KexAlgorithms | ||
| + | lineinfile: | ||
| + | path: /etc/ssh/sshd_config | ||
| + | insertafter: '^#RekeyLimit default none' | ||
| + | line: 'KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256' | ||
| + | state: present | ||
| + | |||
| + | - name: Set secure Ciphers | ||
| + | lineinfile: | ||
| + | path: /etc/ssh/sshd_config | ||
| + | insertafter: '^#RekeyLimit default none' | ||
| + | line: 'Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' | ||
| + | state: present | ||
| + | |||
| + | - name: Set secure MACs | ||
| + | lineinfile: | ||
| + | path: /etc/ssh/sshd_config | ||
| + | insertafter: '^#RekeyLimit default none' | ||
| + | line: 'MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com' | ||
| + | state: present | ||
| + | |||
| + | - name: Enable crypto policy on RHEL 7 | ||
| + | lineinfile: | ||
| + | path: /etc/sysconfig/sshd | ||
| + | regexp: '^' | ||
| + | insertafter: EOF | ||
| + | line: 'CRYPTO_POLICY=' | ||
| + | when: (ansible_facts['distribution'] == "RedHat" and ansible_facts['distribution_major_version'] == "7") | ||
| + | |||
| + | - name: Enable crypto policy on RHEL 8 | ||
| + | lineinfile: | ||
| + | path: /etc/sysconfig/sshd | ||
| + | regexp: '^(#)?CRYPTO_POLICY=' | ||
| + | line: 'CRYPTO_POLICY=' | ||
| + | state: present | ||
| + | when: (ansible_facts['distribution'] == "RedHat" and ansible_facts['distribution_major_version'] > "7") | ||
| + | |||
| + | - name: Create tmout.sh file | ||
| + | copy: | ||
| + | dest: /etc/profile.d/tmout.sh | ||
| + | content: | | ||
| + | TMOUT=900 | ||
| + | readonly TMOUT | ||
| + | export TMOUT | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: '0744' | ||
| + | |||
| + | - name: Update banner message | ||
| + | copy: | ||
| + | dest: /etc/issue.net | ||
| + | content: | | ||
| + | ################################################################# | ||
| + | * # | ||
| + | * This system is for the use of authorized users only. # | ||
| + | * Usage of this system monitored & recorded by system personnel.# | ||
| + | * # | ||
| + | ################################################################# | ||
| + | owner: root | ||
| + | group: root | ||
| + | mode: '0744' | ||
| + | |||
| + | - name: Restart SSHD service | ||
| + | service: | ||
| + | name: sshd | ||
| + | state: restarted | ||
| + | </code> | ||
| + | |||
| + | <code> | ||
| + | --- | ||
| + | - hosts: all | ||
| + | tasks: | ||
| + | - name: sshd configuration file update | ||
| + | blockinfile: | ||
| + | path: /etc/ssh/sshd_config | ||
| + | insertbefore: BOF # Beginning of the file | ||
| + | marker: "# {mark} ANSIBLE MANAGED BLOCK BY LINUX-ADMIN" | ||
| + | block: | | ||
| + | PermitRootLogin no | ||
| + | PubkeyAuthentication yes | ||
| + | AuthorizedKeysFile .ssh/authorized_keys | ||
| + | PasswordAuthentication no | ||
| + | backup: yes | ||
| + | validate: /usr/sbin/sshd -T -f %s | ||
| + | |||
| + | - name: Restart SSHD | ||
| + | service: | ||
| + | name: sshd | ||
| + | state: restarted | ||
| + | </code> | ||
| + | |||
| + | ===== SUDO config ===== | ||
| + | |||
| + | <code> | ||
| + | - name: Setup passwordless sudo | ||
| + | lineinfile: | ||
| + | path: /etc/sudoers | ||
| + | state: present | ||
| + | regexp: '^%sudo' | ||
| + | line: '%sudo ALL=(ALL) NOPASSWD: ALL' | ||
| + | validate: '/usr/sbin/visudo -cf %s' | ||
| + | |||
| + | - name: Create a new regular user with sudo privileges | ||
| + | user: | ||
| + | name: "{{ created_username }}" | ||
| + | state: present | ||
| + | groups: sudo | ||
| + | append: true | ||
| + | create_home: true | ||
| + | </code> | ||
| + | https://zakirpcs.medium.com/ssh-hardening-using-ansible-playbook-9717a2e3edfc | ||