• Inicio
  • Blog
  • Cómo crear contenedores de forma segura mediante la gestión de certificados

Cómo crear contenedores de forma segura mediante la gestión de certificados

La automatización del despliegue de contenedores tiene muchas ventajas, pero estas ventajas no están exentas de complicaciones. Los esfuerzos de DevOps han convertido en práctica común la codificación de credenciales en scripts de inicio en la nube, pero esto plantea importantes riesgos de seguridad. Además, ¿qué ocurre si necesitas introducir un certificado en una de estas instancias? ¿Lo guarda en una imagen o en un archivo de configuración? Esto supone un riesgo aún mayor, ya que ahora un adversario tiene acceso a una clave privada exportable. Usando herramientas como Puppet o Ansible junto con nuestra plataforma, podemos mitigar estos riesgos. Keyfactor Command podemos mitigar estos riesgos y solicitar el certificado de forma única para el contenedor o máquina virtual en el momento de su creación. Este post demostrará este concepto en el contexto de Microsoft Azure VMs.

Cómo crear contenedores de forma segura mediante CMS, Puppet y Ansible

La administración de contenedores requiere que dispongas de un sistema host (Azure recomienda CentOS 7.4, Ubuntu 16.04 LTS o SLES 12 SP2) con Ansible/Puppet, el SDK de Python y la CLI 2.0 de Azure. En este ejemplo, he puesto en marcha un B1 estándar con Ubuntu 16.04 LTS y corrió:

 

# install required packages

sudo apt-get update && sudo apt-get install -y libssl-dev libffi-dev python-dev python-pip

sudo pip install ansible[azure]

 

# add Azure CLI repo to package manager

AZ_REPO=$(lsb_release -cs)

echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | \

   sudo tee /etc/apt/sources.list.d/azure-cli.list

curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add –

 

# install Azure CLI

sudo apt-get install apt-transport-https

sudo apt-get update && sudo apt-get install azure-cli

 

# the VM we will spin up will be running the yum package manager so we will need it on the host

# as well to acquire the proper Python bindings

sudo apt-get install yum

 

Después de configurar la máquina host, el siguiente paso es configurar la CLI de Azure para que te permita crear nuevas máquinas virtuales mediante programación. Para ello, ejecute:

 

az login

 

A continuación, introduzca el código dado en https://microsoft.com/devicelogin después de autenticarse en su portal Azure como el usuario con el que desea ejecutar Ansible. Deberías obtener un resultado similar:

 

[

  {

    "cloudName": "AzureCloud",

    "id": " f9c3e574-235a-4998-a604-8a13b91e2100",

    "isDefault": true,

    "name": "Your Subscription Name"

    "state": "Enabled",

    "tenantId": " 4c00ebbc-e7cc-4790-bbbb-71dc5fb948e2",

    "user": {

      "name": "[email protected]",

      "type": "user"

    }

  }

]

 

Ahora Ansible nos pedirá una clave SSH/par secreto para conectarnos a la nueva VM. Podemos generar esto con

 

ssh-keygen -t rsa -C [email protected]

 

Proporcionar un correo electrónico nos ayudará a identificar la clave en el futuro. Si guarda esto en la ubicación predeterminada, /home/(usuario actual)/.ssh/id_rsa, su clave pública debería residir en /home/iamgroot/.ssh/id_rsa.pub. Si ha protegido su clave privada con una frase de contraseña, deberá utilizar el agente SSH. El agente ayuda con la gestión de claves ssh cuando estás haciendo cosas en torno a la automatización. Para añadir la clave privada al agente, simplemente ejecute:

 

ssh-agent bash

ssh-agent add <Path to your Private Key>

 

Ahora podemos crear el Playbook de Ansible. Esto nos permitirá poner en marcha una máquina virtual de Azure, extraer un script de Python y solicitar un certificado con un solo command. Crea un nuevo archivo con extensión .yml, y configura lo siguiente:

 

- name: Provision Azure VM with Certificate

  hosts: localhost

  connection: local

  tasks:

 

  # The first thing the play will do is spin up

  # a new Azure Virtual Machine on the same

  # network.

 

  - name: Create public IP address

    azure_rm_publicipaddress:

      resource_group: AnsibleTest-Jake

      allocation_method: Static

      name: childVM1-ip

  - name: Create Network Security Group that allows SSH

    azure_rm_securitygroup:

      resource_group: AnsibleTest-Jake

      name: childVM1-nsg

      rules:

        - name: SSH

          protocol: Tcp

          destination_port_range: 22

          access: Allow

          priority: 1001

          direction: Inbound

  - name: Create virtual network inteface card

    azure_rm_networkinterface:

      resource_group: AnsibleTest-Jake

      name: childVM1-nic

      virtual_network: AnsibleTest-Jake-vnet

      public_ip_name: childVM1-ip

      subnet_name: default

      security_group: childVM1-nsg

  - name: Create VM

    azure_rm_virtualmachine:

      resource_group: AnsibleTest-Jake

      name: childVM1

      vm_size: Standard_DS1_v2

      admin_username: azureuser

      ssh_password_enabled: false

      ssh_public_keys: # the ssh key used here is found in /home/<Your User>/.ssh/id_rsa.pub

        - path: /home/azureuser/.ssh/authorized_keys

          key_data: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDr4kQvWCZcqDbNOFHumbHUi1x6LAdeRImjmz79+srshS14cHsLD1qX5ATOhxWTZtfXZUG9UnlB2ag5I15b3xEVpo/eX9CnTMKWKpkiaQIfQgb20EdFgWE8dP9VXvdfTpJBGLOYKcmUbn/BnkKp3B1BWkp0YRiV8S1r1yYZxyFMGPcOJqwHwFyvJjxR8bGNIFWZ6tdZa+MCkoxSKk9IeIsCEHZhCTrMPceUZnzbKIU0waiwvnidZkRXjj//rQcDrcWyrem6pHS03f/Dt+1LpU50ahtp8we/SnlQNT+nYPiNcSzTSicPe0O1imSCB63bHLmtW/SRFTr8Yhsvq28VVAkV [email protected]"

      network_interfaces: childVM1-nic

      image:

        offer: CentOS

        publisher: OpenLogic

        sku: '7.5'

        version: latest

 

  # in order to connect to the new host with Ansible,

  # we must tell Ansible that it exists

 

  - name: Get childVM1 IP to add to Ansible Inventory

    azure_rm_publicipaddress_facts:

        resource_group: AnsibleTest-Jake

        name: childVM1-ip

    register: azure_ip

  - debug: var=azure_ip

 

 - name: Add childVM1 to Ansible Inventory

    add_host:

        hostname: "{ { item.properties.ipAddress } }"

        groupname: launched

        ansible_ssh_private_key_file: ~/.ssh/id_rsa

        ansible_ssh_user: azureuser

    with_items: "{ { azure_ip.ansible_facts.azure_publicipaddresses } }"

 

  - name: Add Epel Repository to Remote Host

    yum_repository:

        name: epel

        description: EPEL YUM repo

        baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  - name: Update Yum on Remote Host

    yum:

        name: '*'

        state: latest

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  - name: Install Git on Remote Host

    yum:

        name: git

        state: latest

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  - name: Create Git Download Directory

    file: path=/home/azureuser/gitdl state=directory

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  # download python file from git repo

  - name: Download API Result

    git:

        repo: https://gitlab.com/css-jadkins/Python-CMS-API-Call.git

        dest: /home/azureuser/gitdl

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  - name: Set Execute Permissions

    file:

        path: /home/azureuser/gitdl/Enroll-PKCS12.py

        owner: azureuser

        mode: 0650

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

  - name: Execute Python Script

    command: python /home/azureuser/gitdl/Enroll-PKCS12.py

    become: true

    become_user: root

    become_method: sudo

    delegate_to: "{ { azure_ip.ansible_facts.azure_publicipaddresses[0].properties.ipAddress } }"

 

Now run the ansible playbook:

 

ansible-playbook azure_create_vm_basic.yml

 

Una vez completado, podrás iniciar sesión en childVM1 utilizando la uri ssh dada (desde la visión general de la VM en el portal de Azure). El cuadro de diálogo se verá algo como esto:

 

[azureuser@childVM1 ~]$ ssh [email protected]

The authenticity of host '137.116.85.88 (137.116.85.88)' can't be established.

ECDSA key fingerprint is SHA256:jJt9S1CVT/Mz8a4aC+l4G3fzbP1VBItlumbyvTEhGdg.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '137.116.85.88' (ECDSA) to the list of known hosts.

Enter passphrase for key '/home/iamgroot/.ssh/id_rsa': *************

[azureuser@childVM1 ~]$

 

Verás que tu archivo .pfx reside ahora en tu directorio personal. Ten en cuenta que puede que necesites añadir módulos pip a Ansible para resolver las dependencias de Python dependiendo de tu versión de Linux.

El script de Python utilizado en este ejemplo se encuentra en: https://gitlab.com/css-jadkins/Python-CMS-API-Call.