L'automatisation du déploiement des conteneurs présente de nombreux avantages, mais ces avantages ne vont pas sans complications. Les efforts de DevOps ont fait du codage en dur des identifiants dans les scripts de cloud-init une pratique courante, mais cela pose des risques de sécurité majeurs. En outre, que se passe-t-il si vous avez besoin d'obtenir un certificat sur l'une de ces instances ? Vous l'enregistrez dans une image ou un fichier de configuration ? Le risque est encore plus grand, car un adversaire a désormais accès à une clé privée exportable. En utilisant des outils comme Puppet ou Ansible conjointement avec notre plateforme, nous pouvons atténuer ces risques. Keyfactor Command nous pouvons atténuer ces risques et demander le certificat uniquement pour le conteneur ou la machine virtuelle au moment de sa création. Ce billet démontrera ce concept dans le contexte des machines virtuelles Microsoft Azure.
L'administration des conteneurs nécessite que vous disposiez d'un système hôte (Azure recommande CentOS 7.4, Ubuntu 16.04 LTS ou SLES 12 SP2) avec Ansible/Puppet, le SDK Python et la CLI Azure 2.0. Dans cet exemple, j'ai démarré un Standard B1 fonctionnant sous Ubuntu 16.04 LTS et j'ai exécuté :
# 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
Après avoir configuré la machine hôte, l'étape suivante consiste à configurer la CLI Azure pour vous permettre de créer de nouvelles machines virtuelles par programmation. Pour ce faire, exécutez :
az login
Ensuite, saisissez le code donné sur https://microsoft.com/devicelogin après vous être authentifié sur votre portail Azure en tant qu'utilisateur sous lequel vous souhaitez exécuter Ansible. Vous devriez obtenir un résultat qui ressemble à ceci :
[
{
"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"
}
}
]
Ansible nous demande maintenant d'avoir une paire clé SSH/secret pour nous connecter à la nouvelle VM. Nous pouvons générer cette paire avec
ssh-keygen -t rsa -C [email protected]
Le fait de fournir un courriel nous aidera à identifier la clé à l'avenir. Si vous l'enregistrez à l'emplacement par défaut, /home/(current user)/.ssh/id_rsa, votre clé publique devrait se trouver dans /home/iamgroot/.ssh/id_rsa.pub. Vous voudrez utiliser l'agent SSH si vous avez protégé votre clé privée par une phrase de passe. L'agent aide à la gestion des clés ssh lorsque vous faites des choses autour de l'automatisation. Pour ajouter la clé privée à l'agent, il suffit d'exécuter :
ssh-agent bash
ssh-agent add <Path to your Private Key>
Nous pouvons maintenant créer le Playbook Ansible. Cela nous permettra de démarrer une VM azure, d'extraire un script python et de demander un certificat à l'aide d'une simple adresse command. Créez un nouveau fichier avec une extension .yml et configurez les éléments suivants :
- 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
Une fois cette opération terminée, vous pourrez vous connecter à childVM1 en utilisant l'uri ssh donnée (à partir de la vue d'ensemble de la VM dans le portail Azure). La boîte de dialogue ressemblera à ceci :
[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 ~]$
Vous constaterez que votre fichier .pfx se trouve désormais dans votre répertoire personnel. Veuillez noter que vous devrez peut-être ajouter des modules pip à Ansible pour résoudre les dépendances Python en fonction de votre version de Linux.
Le script Python utilisé dans cet exemple est disponible à l'adresse suivante : https://gitlab.com/css-jadkins/Python-CMS-API-Call.