softasap.sa_box_bootstap

Estado de Construcción

Ejemplo de uso:

Sencillo

roles:
   - {
       role: "sa-box-bootstrap",
       deploy_user: "{{jenkins_user}}",
       deploy_user_authorized_keys: "{{jenkins_authorized_keys}}",
       timezone: "Europe/Kiev"
     }

Avanzado

vars:
  - root_dir: ..

  - jenkins_user: jenkins
    jenkins_authorized_keys:
      - "{{playbook_dir}}/components/files/ssh/vyacheslav1.pub"
      - "{{playbook_dir}}/components/files/ssh/vyacheslav2.pub"
      - "{{playbook_dir}}/components/files/ssh/vyacheslav3.pub"
      - "{{playbook_dir}}/components/files/ssh/vyacheslav4.pub"
  - timezone: "Europe/Kiev"

pre_tasks:
  - debug: msg="Sección de tareas previas"

roles:
   - {
       role: "sa-box-bootstrap",
       deploy_user: "{{jenkins_user}}",
       deploy_user_key: "{{playbook_dir}}/components/files/ssh/jenkins_rsa",
       deploy_user_pub_key: "{{playbook_dir}}/components/files/ssh/jenkins_rsa.pub",
       deploy_user_authorized_keys: "{{jenkins_authorized_keys}}",

       timezone: "Europe/Kiev",

       option_copy_initial_authorized_keys: true,
       option_enforce_ssh_keys_login: true,
       option_file2ban: true,
       option_firewall: true,
       option_monit: true
     }

Importante: si no especificas el parámetro deploy_user_sudo_password, el usuario de despliegue creado podrá ejecutar sudo sin confirmación de contraseña. Mientras que en algunos casos esto está bien, tener un nivel adicional de seguridad nunca está de más. Por lo tanto:

Usuario de despliegue solicitando una contraseña de sudo

vars:
  - user_authorized_keys:
      - "~/.ssh/id_rsa.pub"
  - user_sudo_pass: "secreto"

roles:
   - {
       role: "sa-box-bootstrap",
       deploy_user: "slavko",
       deploy_user_authorized_keys: "{{user_authorized_keys}}",
       deploy_user_sudo_password: "{{user_sudo_pass | password_hash('sha512')}}",
       option_enforce_ssh_keys_login: yes
     }

Si tienes un usuario de despliegue que requiere ingresar una contraseña de sudo, debes proporcionarla a través del parámetro ansible_become_password.

register
$BOX_PLAYBOOK
$BOX_NAME
$BOX_ADDRESS
$BOX_USER
$BOX_PWD

verbose 4
set box_address $BOX_ADDRESS
set ansible_become_password secreto

provision $BOX_NAME

Prepara tu caja para el despliegue

Contexto

Hoy en día, los despliegues se han trasladado desde servidores físicos a máquinas virtuales que se inician rápidamente, como las que ofrecen Amazon, Digital Ocean, y proveedores basados en OpenStack. Por lo tanto, la configuración de la caja ya no requiere pasos de administración manuales. Una de las opciones son las imágenes de caja preconfiguradas listas para usar. Otro enfoque es comenzar desde un reinicio del sistema inicial y provisionarlo según las necesidades del proyecto con algún provisionador como Ansible, Chef o Puppet.

El primer paso para proceder con el aprovisionamiento personalizado es realizar una seguridad básica de la caja, ya que en algunos casos se te puede entregar una caja recién instalada con la contraseña de root.

Déjame compartir contigo una receta rápida sobre la seguridad inicial de la caja, que debería funcionar para la mayoría de los despliegues web.

Desafíos a abordar

Al final del artículo, deberíamos poder asegurar un servidor virtual Ubuntu 14.04 LTS.

  • Configurar firewall, permitiendo solo los puertos 22, 443 y 80.
  • Registrar tus claves públicas para el usuario de despliegue.
  • Asegurar SSH para permitir solo la autorización mediante claves.
  • Poner un proceso automático en funcionamiento para prohibir a los intrusos que intenten acceder por SSH desde Internet.

Rol de Bootstrap de Caja

Ansible viene con un bonito concepto de reutilización de fragmentos de despliegue, llamado roles. Así que veamos lo que hace el rol sa-box-bootstrap:

Opciones de configuración

Las siguientes variables pueden ser sobrescritas:

  • root_dir - requerido, recetas para desarrolladores de Ansible repositorio.
  • option_enforce_ssh_keys_login (true|false) - si se debe forzar la seguridad de SSH.
  • ufw_rules_default - política de firewall predeterminada. En la mayoría de los casos no se modifica.
  • ufw_rules_allow - conjunto de reglas de entrada a configurar.
  • sshd_config_lines - cambios necesarios en la configuración de SSHD para asegurar la caja.
  • option_file2ban - si es verdadero, se instalará adicionalmente el paquete file2ban.
  • whitelistedips - conjunto de IPs que se consideran seguras: tu puerta de enlace de oficina, servidor de compilación, etc.; Para evitar que te bloqueen accidentalmente.

Paso 1: Activar el firewall

El primer paso es instalar y configurar el firewall ufw:

- include: "{{root_dir}}/tasks_ufw.yml"

Por defecto, se aplican las siguientes reglas de firewall (saliente cualquier, http, https y ssh permitidos):

ufw_rules_default:
  - {
      policy: deny,
      direction: incoming
    }
  - {
      policy: allow,
      direction: outgoing
    }

ufw_rules_allow:
  - {
      port: 80,
      proto: tcp
     }
  - {
      port: 443,
      proto: tcp
    }
  - {
      port: 22,
      proto: tcp
     }

Puedes sobrescribir estas variables para adaptarlas a tus necesidades.

Paso 2: Crear usuario de despliegue

Si piensas trabajar y aprovisionar esta caja, lo más probable es que no quieras hacerlo como root. Por lo tanto, el segundo paso es crear un usuario de despliegue, autorizado por un conjunto de claves ssh proporcionadas, y permitido convertirse en sudo sin contraseña (requisito básico para aprovisionamiento automático).

- include: "{{root_dir}}/use/__create_deploy_user.yml user={{deploy_user}} group={{deploy_user}} home=/home/{{deploy_user}}"
  when: deploy_user is defined

- name: SSH | Autorizar claves
  authorized_key: user={{deploy_user}} key="{{ lookup('file', item) }}"
  when: deploy_user_keys is defined
  with_items: "{{deploy_user_keys}}"
  sudo: yes

Puedes definir el usuario en tu playbook, por ejemplo, de esta manera:

jenkins_user: jenkins
jenkins_authorized_keys:
  - "{{playbook_dir}}/components/files/ssh/vyacheslav.pub"

Y luego pasar esto como parámetros al rol:

roles:
   - {
       role: "sa-box-bootstrap",
       root_dir: "{{playbook_dir}}/public/ansible_developer_recipes",
       deploy_user: "{{jenkins_user}}",
       deploy_user_keys: "{{jenkins_authorized_keys}}"
     }

Paso 3: Asegurar SSH (opcional)

- name: SSH | Forzar la seguridad de las claves SSH
  lineinfile: dest=/etc/ssh/sshd_config regexp="{{item.regexp}}" line="{{item.line}}"
  with_items: "{{sshd_config_lines}}"
  when: option_enforce_ssh_keys_login
  become: true
  tags: ssh

Si la variable option_enforce_ssh_keys_login está configurada como verdadera, la configuración de sshd se modifica de acuerdo con las reglas de sshd_config_lines. Por defecto, utiliza el protocolo v2, prohíbe el inicio de sesión root, y la autenticación por contraseña.

Paso 4: Prohibir a extraños que adivinen tu acceso de usuario SSH

Si la variable option_file2ban está configurada como verdadera, se instalará la herramienta especial file2ban. Esta se encargará de vigilar los intentos de inicio de sesión SSH fallidos y prohibir a los intrusos. Para evitar bloqueos accidentales, es buena idea incluir en la lista blanca tus IPs, se aceptan tanto IPs individuales como máscaras de red, por ejemplo:

whitelistedips:
 - 127.0.0.1
 - 127.0.0.1/8

Creando tu propio proyecto de bootstrap de caja

Vamos a preparar un proyecto básico de bootstrap que se pueda utilizar en el futuro. Incluye los siguientes archivos:

  • bootstrap.sh - instala ansible junto con sus dependencias.
  • init.sh - inicializa.
  • .projmodules - totalmente compatible con la sintaxis de .gitmodules, especifica la lista de las dependencias que se utilizarán en el playbook. Incluye, en particular, ansible - por defecto recetas de desarrolladores (repositorio con un conjunto de recetas útiles de despliegue) y el rol de ansible llamado sa-box-bootstrap responsable de pasos para asegurar la caja.
[submodule "public/ansible_developer_recipes"]
    path = public/ansible_developer_recipes
    url = [email protected]:Voronenko/ansible-developer_recipes.git
[submodule "roles/sa-box-bootstrap"]
    path = roles/sa-box-bootstrap
    url = [email protected]:softasap/sa-box-bootstrap.git
  • hosts - lista aquí las credenciales iniciales de la caja que se te proporcionaron para el servidor.
[bootstrap]
box_bootstrap ansible_ssh_host=192.168.0.17 ansible_ssh_user=tu_usuario ansible_ssh_pass=tu_contraseña
  • box_vars.yml - define aquí las sobrescrituras específicas del entorno, como tu nombre de usuario de despliegue y claves preferidas.
  • box_bootstrap.yml - aquí pones los pasos de aprovisionamiento de tu caja. Asegurar la caja es solo el primer paso. Para sobrescribir parámetros para sa-box-bootstrap - pasa los parámetros como en el siguiente ejemplo.
- hosts: all

  vars_files:
    - ./box_vars.yml
  roles:
     - {
         role: "sa-box-bootstrap",
         root_dir: "{{playbook_dir}}/public/ansible_developer_recipes",
         deploy_user: "{{my_deploy_user}}",
         deploy_user_keys: "{{my_deploy_authorized_keys}}"
       }

Código en acción

El código se puede descargar desde el repositorio https://github.com/Voronenko/devops-bootstrap-box-template. Para usarlo, haz un fork, ajusta los parámetros a tus necesidades, y úsalo. El ajuste incluye: la creación del archivo box_vars.yml. Puedes sobrescribir ahí cualquiera de las variables mencionadas. El conjunto mínimo requerido es el usuario de despliegue y tus claves públicas.

box_deploy_user: jenkins
box_deploy_authorized_keys:
  - "{{playbook_dir}}/components/files/ssh/vyacheslav.pub"

Asegúrate de tener ansible (bootstrap.sh para instalar) y haber clonado los directorios de roles (init.sh). Luego ejecuta setup.sh. Si todo está configurado correctamente, verás algo así:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [box_bootstrap]

TASK: [sa-box-bootstrap | Establece correctamente el nombre de host] **********
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | debug var="ufw_rules_allow"] ***********************
ok: [box_bootstrap] => {
    "var": {
        "ufw_rules_allow": [
            {
                "port": 80,
                "proto": "tcp"
            },
            {
                "port": 443,
                "proto": "tcp"
            },
            {
                "port": 22,
                "proto": "tcp"
            }
        ]
    }
}

TASK: [sa-box-bootstrap | UFW | Reiniciar] *************************************
ok: [box_bootstrap]

TASK: [sa-box-bootstrap | UFW | Configurar reglas de entrada/salida predeterminadas] ***
ok: [box_bootstrap] => (item={'policy': 'deny', 'direction': 'incoming'})
ok: [box_bootstrap] => (item={'policy': 'allow', 'direction': 'outgoing'})

TASK: [sa-box-bootstrap | UFW | Configurar reglas para permitir tráfico entrante] ** 
ok: [box_bootstrap] => (item={'port': 80, 'proto': 'tcp'})
ok: [box_bootstrap] => (item={'port': 443, 'proto': 'tcp'})
ok: [box_bootstrap] => (item={'port': 22, 'proto': 'tcp'})

TASK: [sa-box-bootstrap | UFW | Habilitar] ************************************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Monit | Ver si está instalado] **********************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Monit | dependencia libssl-dev] **********************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Monit | Descargar] ***********************************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Monit | Instalar] ************************************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | debug msg="Creando usuario de despliegue {{my_deploy_user}}:{{my_deploy_user}} con directorio de inicio /home/{{my_deploy_user}}"] *
ok: [box_bootstrap] => {
    "msg": "Creando usuario de despliegue jenkins:jenkins con directorio de inicio /home/jenkins"
}

TASK: [sa-box-bootstrap | Usuario de despliegue | Creando grupo] **************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Usuario de despliegue | Creando usuario] *************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Usuario de despliegue | Comprobando presencia de clave] ***
ok: [box_bootstrap]

TASK: [sa-box-bootstrap | Usuario de despliegue | Copiar authorized_keys de {{ansible_user_id}}] *
skipping: [box_bootstrap]

TASK: [sa-box-bootstrap | Usuario de despliegue | Establecer permisos en authorized_keys] ****
skipping: [box_bootstrap]

TASK: [sa-box-bootstrap | Usuario de despliegue | Asegurando que sudoers no pida pwd] ****
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | SSH | Autorizar claves] *******************************
changed: [box_bootstrap] => (item=/home/slavko/labs/devops-bootstrap-box-template/components/files/ssh/vyacheslav.pub)

TASK: [sa-box-bootstrap | SSH | Forzar la seguridad de las claves SSH] ********
ok: [box_bootstrap] => (item={'regexp': '^Protocol.*', 'line': 'Protocol 2'})
changed: [box_bootstrap] => (item={'regexp': '^PermitRootLogin.*', 'line': 'PermitRootLogin no'})
ok: [box_bootstrap] => (item={'regexp': '^RSAAuthentication.*', 'line': 'RSAAuthentication yes'})
ok: [box_bootstrap] => (item={'regexp': '^PubkeyAuthentication.*', 'line': 'PubkeyAuthentication yes'})
ok: [box_bootstrap] => (item={'regexp': '^ChallengeResponseAuthentication.*', 'line': 'ChallengeResponseAuthentication no'})
changed: [box_bootstrap] => (item={'regexp': '^PasswordAuthentication.*', 'line': 'PasswordAuthentication no'})
changed: [box_bootstrap] => (item={'regexp': '^MaxAuthTries.*', 'line': 'MaxAuthTries 3'})

TASK: [sa-box-bootstrap | SSH | Reiniciar SSHD] *********************************
changed: [box_bootstrap]

TASK: [sa-box-bootstrap | Instalar paquetes base de Ubuntu] *********************
changed: [box_bootstrap] => (item=unzip,mc)

PLAY RECAP ********************************************************************
box_bootstrap              : ok=21   changed=13   unreachable=0    failed=0   

Finalmente, tienes la caja asegurada, con el usuario de despliegue especificado que tiene permiso para autorizar solo con las claves que hayas establecido. No se permite el inicio de sesión como root. Solo se permiten ciertos puertos de entrada de acuerdo a tus reglas.

Verifica con NMap e intenta iniciar sesión:

ssh  192.168.0.17
Permiso denegado (clave pública).

ssh -ldeploy_user 192.168.0.17
Bienvenido a Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-32-generic x86_64)
deploy_user@LABBOX17:~$

Puntos de interés

Puedes reutilizar este playbook para crear tus propios proyectos de bootstrap de cajas y reutilizar el rol para configurar tus entornos de manera más rápida y segura con Ansible.

Acerca del proyecto

Role to perform basic securing of fresh instance for further automated deploy

Instalar
ansible-galaxy install softasap.sa_box_bootstap
Licencia
Unknown
Descargas
1.7k
Propietario
Get your application deployed in a robust way