Hardening de Servidores Linux Ubuntu con Ansible
Como hacer un Hardening de servidores Linux Ubuntu con Ansible y que sean compliance con diferentes estandars.
¿Que es Ansible?
Con Ansible podemos instalar aplicaciones, orquestar servicios y tareas más avanzas. También se puede utilizar para la estandarización de sistema operativo (Estandarización de servicios instalados, de configuración de ficheros, versiones de software, etcétera) y la administración de servicios centralizados, como por ejemplo DNS.
Para este laboratorio vamos a utilizar 2 Ubuntu Server's. Tendremos un Ansible Master y un Ansible Worker.
Ansible lo encontramos, por defecto, en la mayoria de las distribuciones de linux. La instalacion es sencilla. Para ello ejecutamos:
apt install ansible
Hostname | Dirección TCP IP |
ansiblemaster | 192.168.247.224 |
ansibleworker | 192.168.247.225 |
Vamos a utilizar estos nombres, en los hosts, con estas direcciones IP's.
Instalación Master Node
Ya hemos instalado ansbile, en el servidor, ahora vamos a realizar las configuraciones.
Ansible se conecta a su cliente a través de SSH, primero generaremos una clave pública en el servidor ansible, para copiarla en los clientes ansible.
Genere la clave usando ssh-keygen comando como se muestra a continuación.
santiago@ansiblemaster:/etc/ansible$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/santiago/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/santiago/.ssh/id_rsa.
Your public key has been saved in /home/santiago/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:AT62rfaL7zq06CUlxUP/DKDmyZH3kM/OLJEFQmhlSnw santiago@ansiblemaster
The key's randomart image is:
+---[RSA 2048]----+
| ..+= = |
| .+oEB * |
| ...= @ = |
| + * % = |
| = = S o |
| o.* |
| .o=.+ |
| .+o+ |
| .. o==. |
+----[SHA256]-----+
Cambiamos los permisos en la llave publica y privada.
santiago@ansiblemaster:/etc/ansible$ sudo chmod 0400 /home/santiago/.ssh/id_rsa.pub
santiago@ansiblemaster:/etc/ansible$ sudo chmod 0400 /home/santiago/.ssh/id_rsa
Copiemos la clave pública al host Ansible cuya dirección IP es 192.168.247.225, con ssh-copy-id.
santiago@ansiblemaster:/etc/ansible$ ssh-copy-id -i ~/.ssh/id_rsa.pub santiago@192.168.247.225
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/santiago/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
santiago@192.168.247.225's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'santiago@192.168.247.225'"
and check to make sure that only the key(s) you wanted were added.
Vamos a configurar el inventario, en el Master. Completamos, como en el ejemplo, el /etc/ansible/hosts. Como se puede ver agregamos, dentro de [servers], nuestro worker.
servers:
hosts:
192.168.247.225:
192.168.247.224:
Ahora vamos a probar la conexión.
santiago@ansiblemaster:/etc/ansible$ ansible -m ping servers
ansibleworker | SUCCESS => {
"changed": false,
"ping": "pong"
}
Hacemos un ping y recibimos un pong. Ya estamos llegando al Worker. ¡Podriamos tener, miles!
Algunos comandos
Vamos a consultar nuestro inventario y revisar los discos.
santiago@ansiblemaster:/etc/ansible$ ansible-inventory --list -y
all:
children:
servers:
hosts:
ansiblemaster:
ansible_host: 192.168.247.224
ansible_python_interpreter: /usr/bin/python3
ansibleworker:
ansible_host: 192.168.247.225
ansible_python_interpreter: /usr/bin/python3
ungrouped: {}
santiago@ansiblemaster:/etc/ansible$ ansible all -a "df -h" -u santiago
ansibleworker | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 955M 0 955M 0% /dev
tmpfs 198M 1,2M 196M 1% /run
/dev/sda2 20G 4,0G 15G 22% /
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 5,0M 0 5,0M 0% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
/dev/loop0 89M 89M 0 100% /snap/core/7270
tmpfs 198M 0 198M 0% /run/user/1000
ansiblemaster | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 955M 0 955M 0% /dev
tmpfs 198M 1,3M 196M 1% /run
/dev/sda2 20G 4,3G 15G 23% /
tmpfs 986M 144K 985M 1% /dev/shm
tmpfs 5,0M 0 5,0M 0% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
/dev/loop0 89M 89M 0 100% /snap/core/7270
tmpfs 198M 0 198M 0% /run/user/1000
/dev/loop1 98M 98M 0 100% /snap/core/10444
Hardening Ubuntu
Uno de los blogs mas importantes para realizar un Hardening de Ubuntu 18.04 es el de Florian Utz. Vamos a utilizar ese playbook y aplicar los CIS Benchmark Controls. Es imporante saber que los niveles 1 y 2 se corregiran de forma predeterminada. El rol podria "romper cosas" por eso es imporante leer la documentacion.
Vamos a crear nuestro requirements.yml.
sudo sh -c "echo '- src: https://github.com/joelradon/ubuntu1804-desktop-cis.git' >> /etc/ansible/requirements.yml"
Una vez que creamos el archivo instalamos el rol con el comando ansible-galaxy.
santiago@ansiblemaster:/etc/ansible$ sudo ansible-galaxy install -p roles -r /etc/ansible/requirements.yml
- extracting ubuntu1804-desktop-cis to /etc/ansible/roles/ubuntu1804-desktop-cis
- ubuntu1804-desktop-cis was installed successfully
Ahora vamos a nuestro playbook para iniciar el Hardening. Se le dira a ansible que use el rol, que acabamos de crear, y corra la "receta" en nuestros servidores. Para ello creamos site.yml.
- name: Hardenizar Servidores Ubuntu
hosts: servers
become: yes
roles:
- ubuntu1804-desktop-cis
Vamos cambiar algunas configuraciones para no ingresar con la llave privada y revisar el potencial de Ansible. Hay varias configuraciones posibles para hacerlo, aca les dejo un instructivo que me resulto muy interesante. Pasando el password, como variable, usando Vault de Ansible. Revisenlo.
Vamos a ingresar el usuario y el password en nuestro inventario.
servers:
hosts:
192.168.247.225:
192.168.247.224:
vars:
ansible_user: santiago
ansible_become: True
ansible_become_pass: TUPASSWORD
¡Vamos a correr el playbook! Y que comience la magia. Ejecutamos ansible-playbook -i hosts site.yml.
santiago@ansiblemaster:/etc/ansible$ ansible-playbook -i hosts site.yml
PLAY [Harden Server] *****************************************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [192.168.247.225]
ok: [192.168.247.224]
TASK [ubuntu1804-desktop-cis : Check OS version and family] **************************************************************************************************************************************************
skipping: [192.168.247.225]
skipping: [192.168.247.224]
TASK [ubuntu1804-desktop-cis : Check ansible version] ********************************************************************************************************************************************************
skipping: [192.168.247.225]
skipping: [192.168.247.224]
TASK [ubuntu1804-desktop-cis : PRELIM | List users accounts] *************************************************************************************************************************************************
ok: [192.168.247.225]
ok: [192.168.247.224]
TASK [ubuntu1804-desktop-cis : PRELIM | Gather accounts with empty password fields] **************************************************************************************************************************
ok: [192.168.247.225]
ok: [192.168.247.224]
TASK [ubuntu1804-desktop-cis : PRELIM | Gather UID 0 accounts other than root] *******************************************************************************************************************************
ok: [192.168.247.225]
ok: [192.168.247.224]
De esta manera vamos a tener nuestros servidores Ubuntu en compliance con CIS Controls. Se puede usar OpenSCAP para realizar Compliance As a Code, basado diferentes estandars.
Espero que les sirva para empezar a conocer el poder de Ansible.