====== Ansible playbooks example ======
===== xxxx =====
Install linux LAMP
**rhel-lamp.yaml**
---
- 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
===== Example with LPAR2RRD =====
> 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
===== SSH config =====
etc_ssh_sshd_config: /etc/ssh/sshd_config
- 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'
Using a loop:
- 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
- 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
---
- 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
===== SUDO config =====
- 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
https://zakirpcs.medium.com/ssh-hardening-using-ansible-playbook-9717a2e3edfc