Skip to content

Commit

Permalink
ssh passphrase login enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
lee212 committed Sep 29, 2016
1 parent bf6eaa8 commit faecf71
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 7 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ Prerequisite
sudo npm install -g azure-cli
```

Account Setup
-------------------------------------------------------------------------------

- Open a browser to http://go.microsoft.com/fwlink/?LinkId=254432
- ``*-DD-MM-YYYY-credentials.publishsettings`` is downloaded on a local directory
- Run ``azure config mode as`` # To run azure cli tool via the classic service management certificate.
- Run ``azure account import <publishsettings file>``
- Run ``azure account cert export ~/.azure/managementCertificate.pem``

Example
-------------------------------------------------------------------------------
Create a VM on Windows Azure
Expand Down Expand Up @@ -91,6 +100,26 @@ azure.set_location("West Europe")
azure.create_cluster(num=5)
```

List of VMs
-------------------------------------------------------------------------------

```
vars(azure.list_deployments().hosted_services)
```

Terminating VM
-------------------------------------------------------------------------------

```
azure.delete_vm()
```

or

```
azure.delete_vm('vm-name')
```

Clustering
-------------------------------------------------------------------------------

Expand Down
87 changes: 87 additions & 0 deletions docs/Notes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
Import Account credentials
-------------------------------------------------------------------------------

It requires to use azure client tool to decode contents in xml files.

- In classic way of using azure is via servicemanagementcertificate, which can be downloaded from:
http://go.microsoft.com/fwlink/?LinkId=254432
- ``*credentials.publishsettings`` xml file contains subscription id and encoded managementcertificate.
::

<?xml version="1.0" encoding="utf-8"?>
<PublishData>
<PublishProfile
SchemaVersion="2.0"
PublishMethod="AzureServiceManagementAPI">
<Subscription
ServiceManagementUrl="https://management.core.windows.net"
Id="6b3cf2b5-2cc1-4828-b5e0-9f8be72e6e6f"
Name="Pay-As-You-Go"
ManagementCertificate="MII...7nlV" />
</PublishProfile>
</PublishData>

- ``azure account import <filename>`` reads and decodes the contents includeing ``ManagementCertificate`` and
stores a new file in JSON format under ``$HOME/.azure/azureProfile.json`` which looks like::

{
"environments": [],
"subscriptions": [
{
"id": "6b*-2*-4*-b*-9*",
"name": "Pay-As-You-Go",
"user": {
"name": "azure@gmail.com",
"type": "user"
},
"managementCertificate": {
"key": "-----BEGIN RSA PRIVATE KEY-----\n ... 4zhGrEBcX1P0=\n-----END RSA PRIVATE KEY-----\n",
"cert": "-----BEGIN CERTIFICATE-----\n ... TtvBOUFM8kOVxZ/8xulQ==\n-----END CERTIFICATE-----\n"
},
"tenantId": "1ee-c1a-4de-8fe-2a51ef8fb",
"state": "Enabled",
"isDefault": true,
"registeredProviders": [],
"environmentName": "AzureCloud",
"managementEndpointUrl": "https://management.core.windows.net"
}
]
}


- ``azure account cert export`` creates a managementCertificate.pem file which
contains ``key`` and ``cert`` from ``"managementCertificate"``


Issue on decoding managementcertificate without azure cli tool
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It supposes to decode:

- read XML from publishsettings file
::
from xmljson import badgerfish as bf
from xml.etree.ElementTree import fromstring

f = open("<filepath>","r");
data = f.read()
json_data = bf.data(fromstring(data))
subscription = json_data['PublishData']['PublishProfile']['Subscription']
sid = subscription['@Id']
scert = subscription['@ManagementCertificate']
f.close()

- decode with base64

::

f2 = open("myCert.pfx","w")
f2.write(scert.decode('base64'))
f2.close()

- stuck with

- https://github.com/Azure/azure-xplat-cli/blob/984313e0715f5b093955df532af5d48bf7828039/lib/util/profile/publishSettings.js#L41
- https://github.com/Azure/azure-xplat-cli/blob/984313e0715f5b093955df532af5d48bf7828039/lib/util/certificates/pkcs.js#L85

36 changes: 29 additions & 7 deletions simpleazure/simpleazure.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
from urlparse import urlparse
from time import sleep
from azure import *
from azure.servicemanagement import *
from azure.servicemanagement import * # Need to be as asm
from ext.credentials import Credentials
from . import config
from . import ssh
from os.path import expanduser
from utils import generate_password

class SimpleAzure:
"""Constructs a :class:`SimpleAzure <SimpleAzure>`.
Expand Down Expand Up @@ -71,9 +73,10 @@ class SimpleAzure:
azure_config = config.azure_path()
thumbprint_path = azure_config + '/.ssh/thumbprint'
authorized_keys = "/home/" + linux_user_id + "/.ssh/authorized_keys"
#public_key_path = azure_config + '/.ssh/myCert.pem'
public_key_path = expanduser("~") + "/.ssh/id_rsa.pub" # rsa public key
private_key_path = azure_config + '/.ssh/myPrivateKey.key'
key_pair_path = private_key_path
ssh_key_is_on = False

#Adding for cluster
num_4_win = 0
Expand Down Expand Up @@ -179,15 +182,16 @@ def create_vm(self, name=None, location=None):
self.set_image()
self.get_media_link(blobname=name)

self.linux_user_passwd = generate_password(16)
os_hd = OSVirtualHardDisk(self.image_name, self.media_link)
linux_config = LinuxConfigurationSet(self.get_name(), self.linux_user_id,
self.linux_user_passwd, True)
self.linux_user_passwd, self.ssh_key_is_on)

#self.set_ssh_keys(linux_config)
self.set_ssh_keys(linux_config)
self.set_network()
#self.set_service_certs()
self.set_service_certs()
# can't find certificate right away.
sleep(5)
#sleep(5)

result = \
self.sms.create_virtual_machine_deployment(service_name=self.get_name(), \
Expand All @@ -203,6 +207,10 @@ def create_vm(self, name=None, location=None):
self.result = result
return result

def get_login_info(self):
"""return SSH id/pass"""
return {"id":self.linux_user_id, "pass":self.linux_user_passwd}

def connect_service(self, refresh=False):
"""Connect Windows Azure Service via ServiceManagementService() with a
subscription id and a certificate.
Expand Down Expand Up @@ -230,6 +238,10 @@ def create_cloud_service(self, name=None, location=None):
location = self.location
self.sms.create_hosted_service(service_name=name, label=name, location=location)

def use_ssh_key(self, yn=False):
"""Enable SSH Key to connect"""
self.ssh_key_is_on = yn

def set_ssh_keys(self, config):
"""Configure login credentials with ssh keys for the virtual machine.
This is only for linux OS, not Windows.
Expand All @@ -239,11 +251,13 @@ def set_ssh_keys(self, config):
"""

if not self.ssh_key_is_on:
return
# fingerprint captured by 'openssl x509 -in myCert.pem -fingerprint
# -noout|cut -d"=" -f2|sed 's/://g'> thumbprint'
# (Sample output) C453D10B808245E0730CD023E88C5EB8A785ED6B
self.thumbprint = open(self.thumbprint_path, 'r').readline().split('\n')[0]
publickey = PublicKey(self.thumbprint, self.authorized_keys)
publickey = PublicKey(self.thumbprint, self.public_key_path)
# KeyPair is a SSH kay pair both a public and a private key to be stored
# on the virtual machine.
# http://msdn.microsoft.com/en-us/library/windowsazure/jj157194.aspx#SSH
Expand Down Expand Up @@ -291,6 +305,8 @@ def set_service_certs(self):
.pfx at this time.
"""
if not self.ssh_key_is_on:
return
# command used:
# openssl pkcs12 -in myCert.pem -inkey myPrivateKey.key
# -export -out myCert.pfx
Expand Down Expand Up @@ -385,6 +401,12 @@ def list_deployments(self):
self.connect_service()
return self.sms.list_hosted_services()

def delete_vm(self, name=None):
"""Delete vm instance"""

res = self.sms.delete_deployment(name or self.get_name(), name or self.get_name())
return res

def set_image(self, name=None, image=None, refresh=False):
"""Set os image to deploy virtual machines.
self.image_name and self.os_name will be set
Expand Down
26 changes: 26 additions & 0 deletions simpleazure/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""

import os
import random

def ensure_dir_exists(directory):
try:
Expand All @@ -20,3 +21,28 @@ def ensure_dir_exists(directory):
except OSError as exception:
if exception.errno != errno.EEXIST:
raise

# Reference: http://interactivepython.org/runestone/static/everyday/2013/01/3_password.html
def generate_password(length=8, lower=True, upper=True, number=True):
lletters = "abcdefghijklmnopqrstuvwxyz"
uletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# This doesn't guarantee both lower and upper cases will show up
alphabet = lletters + uletters
digit = "0123456789"
mypw = ""

def _random_character(texts):
return texts[random.randrange(len(texts))]

if not lower:
alphabet = uletters
elif not upper:
alphabet = lletters

for i in range(length):
# last half length will be filled with numbers
if number and i >= (length / 2):
mypw = mypw + _random_character(digit)
else:
mypw = mypw + _random_character(alphabet)
return mypw

0 comments on commit faecf71

Please sign in to comment.