Die Automatisierung der Container-Bereitstellung bietet viele Vorteile, die jedoch nicht ohne Komplikationen einhergehen. Die DevOps-Bemühungen haben dazu geführt, dass das Hardcoding von Anmeldeinformationen in Cloud-Init-Skripten gängige Praxis ist, was jedoch große Sicherheitsrisiken birgt. Und was ist, wenn Sie ein Zertifikat auf eine dieser Instanzen übertragen müssen? Speichern Sie es dann in einem Image oder einer Konfigurationsdatei? Dies stellt ein noch größeres Risiko dar, da ein Angreifer nun Zugriff auf einen exportierbaren privaten Schlüssel hat. Durch den Einsatz von Tools wie Puppet oder Ansible in Verbindung mit unserer Keyfactor Command Plattform können wir diese Risiken mindern und das Zertifikat eindeutig für den Container oder die virtuelle Maschine zum Zeitpunkt der Erstellung anfordern. In diesem Beitrag wird dieses Konzept im Kontext von Microsoft Azure VMs demonstriert.
Für die Containerverwaltung benötigen Sie ein Hostsystem (Azure empfiehlt CentOS 7.4, Ubuntu 16.04 LTS oder SLES 12 SP2) mit Ansible/Puppet, dem Python SDK und der Azure CLI 2.0. In diesem Beispiel habe ich ein Standard-B1-System mit Ubuntu 16.04 LTS aufgesetzt und ausgeführt:
# 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
Nach der Konfiguration der Host-Maschine müssen Sie im nächsten Schritt die Azure-Befehlszeilenschnittstelle so konfigurieren, dass Sie neue VMs programmatisch erstellen können. Führen Sie dazu Folgendes aus:
az login
Geben Sie dann den angegebenen Code unter https://microsoft.com/devicelogin ein, nachdem Sie sich am Azure-Portal als der Benutzer authentifiziert haben, unter dem Sie Ansible ausführen möchten. Sie sollten ein Ergebnis erhalten, das wie folgt aussieht:
[
{
"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 benötigt nun ein SSH-Schlüssel/Geheimnispaar, um sich mit der neuen VM zu verbinden. Wir können dies mit
ssh-keygen -t rsa -C [email protected]
Die Angabe einer E-Mail hilft uns, den Schlüssel in Zukunft zu identifizieren. Wenn Sie diesen am Standardspeicherort /home/(aktueller Benutzer)/.ssh/id_rsa speichern, sollte sich Ihr öffentlicher Schlüssel in /home/iamgroot/.ssh/id_rsa.pub befinden. Sie sollten den SSH-Agenten nutzen, wenn Sie Ihren privaten Schlüssel mit einer Passphrase geschützt haben. Der Agent hilft bei der Verwaltung von ssh-Schlüsseln, wenn Sie Dinge automatisieren wollen. Um den privaten Schlüssel zum Agenten hinzuzufügen, führen Sie einfach aus:
ssh-agent bash
ssh-agent add <Path to your Private Key>
Jetzt können wir das Ansible Playbook erstellen. Damit können wir eine Azure-VM hochfahren, ein Python-Skript aufrufen und ein Zertifikat mit einem einzigen command anfordern. Erstellen Sie eine neue Datei mit der Erweiterung .yml, und konfigurieren Sie Folgendes:
- 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
Sobald dies abgeschlossen ist, können Sie sich bei childVM1 mit der angegebenen ssh uri anmelden (aus der Übersicht der VM im Azure-Portal). Der Dialog sieht in etwa wie folgt aus:
[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 ~]$
Ihre .pfx-Datei befindet sich nun in Ihrem Home-Verzeichnis. Bitte beachten Sie, dass Sie möglicherweise pip-Module zu Ansible hinzufügen müssen, um die Python-Abhängigkeiten aufzulösen, je nach Linux-Variante.
Das in diesem Beispiel verwendete Python-Skript finden Sie unter: https://gitlab.com/css-jadkins/Python-CMS-API-Call.