By John Hanley, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
At least in the Linux world, SSH is the primary security mechanism for authentication. SSH enables system administration and file transfers securely over insecure networks. Two methods of authentication are typically used: username and password, and SSH keys. In the cloud world we call SSH keys Key Pairs.
In this section, I want to look at how Alibaba Cloud implements SSH and Key Pairs for managing and controlling access to Linux ECS instances. When you create a new ECS instance, in this example Ubuntu 16.04, you have the option to assign a Key Pair to the instance before creation. You then download the private part of the Key Pair to your local system for use in connecting to the ECS instance. By default, only one user is created. That is the user root.
I often see companies then making the mistake of only using root for each member of the DevOps team to access the ECS instance. This is a bad idea. In this article we will investigate creating additional users, creating a unique Key Pair for each user, and in general providing for auditable security.
While reviewing the ECS documentation, I noticed an interesting API - AttachKeyPair. This API is documented to have the following features:
I cannot begin to mention how many customers have lost their SSH key pair for an instance and wanted to know how to recover. Maybe this ECS feature will solve this problem for Alibaba Cloud customers.
I cannot find documentation for the CLI that documents each command for Alibaba Cloud. So, I go through this process to learn how to use a CLI feature:
Run this command:
aliyuncli ecs
This displays a list of support commands for ECS. Look for a command that looks like the API that I want to use. In this case AttachKeyPair.
Next, run this command:
aliyuncli ecs AttachKeyPair help
This displays a list of command line options for AttachKeyPair:
[ecs.AttachKeyPair]: current operation can uses parameters as follow :
--AccessKeyId | --AccessKeySecret
--InstanceIds | --KeyPairName
--OwnerId | --RegionId
--ResourceOwnerAccount | --ResourceOwnerId
--output | --profile
--version
Next, review the API documentation for AttachKeyPair. The documentation indicates that RegionId, KeyPairName and InstanceIds are required. This corresponds to the AttachKeyPair parameters:
Steps to prepare for development and testing
I had to figure this out the hard way, but you need to escape the ECS Instance IDs values. Here is how to do it for Windows and Linux:
Windows:
aliyuncli ecs AttachKeyPair --InstanceIds "[\"i-abcdeftvgllm854abcde\"]" --KeyPairName Test2
Linux:
aliyuncli ecs AttachKeyPair --InstanceIds '[\"i-abcdeftvgllm854abcde\"]' --KeyPairName Test2
This command reported success.
{
"FailCount": 0,
"TotalCount": 1,
"RequestId": "11CC0000-D577-4462-B410-ABCDEFCF2129",
"Results": {
"Result": [
{
"InstanceId": "i-abcdeftvgllm854abcde",
"Message": "successful",
"Code": "200",
"Success": true
}
]
}
}
Let's go back into the console and verify that the console shows the changed Key Pair.
Reboot the ECS instance and verify that we can login with the Test2 Key Pair, but not the Test1 Key Pair:
aliyuncli ecs RebootInstance --InstanceId i-abcdeftvgllm854abcde
Part 1 is now completed. In the next part we will learn how to create a Key Pair from our local system, import this Key Pair to the Alibaba Console and then assign this Key Pair to our test instance.
The API to use is CreateKeyPair. Let's look at this API. This API is documented to have the following features:
Next, run this command:
aliyuncli ecs CreateKeyPair help
This displays a list of command line options for CreateKeyPair:
[ecs.CreateKeyPair]: current operation can uses parameters as follow :
--AccessKeyId | --AccessKeySecret
--KeyPairName | --OwnerId
--RegionId | --ResourceOwnerAccount
--ResourceOwnerId | --output
--profile | --version
Execute this command to create a new Key Pair:
aliyuncli ecs CreateKeyPair --RegionId us-west-1 --KeyPairName Test3
This command reported success.
{
"KeyPairFingerPrint": "7d6849d03953aa5584240de7c9d4b8c8",
"PrivateKeyBody": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAh1y3ot74ipDU+mHUZEBWDDT22VTkP0NVG4mOL1NQQYhGhccT\nKLqBKtiVeWG1PeHhHFJqrRYVW5qwgC4P/dYA+B+ztdHD1HYdRGwMSW0JxNL/rEy4\n4W9IxKh6jt9/XLUSIacNjtcHocPLF0Nw8/zsfcuSsvBB9EKhyep+c8qTKozWHb7O\nsbFlYXcKLo8rOpHTJIYOyR0Jrd2sR1zP8laB71+mvYtpuf90Rc23IxABn+Z+hefb\n7zSO/sQ2ve5aOaYMlWez8RoAPme2cGBszWFUvyT6GXWMGIucPuUOl9ATRN4DWmqw\n8LltgtLUDQk0Ji3svAYbC4+0dkhkrcfp4VzVlwIDAQABAoIBADSQK3sijG76aMnF\nvX0kgoWA965TScLLObxUwRLdjle0PHZsZKM3MTtbGUgmSgP6t7iQxH3sCmUk/472\n1BzkwkGXxeg/yYSyTREpx+enYNi+eqwEqvJXjXFYXycl4MY2RhEtVpV2KK+HYVDq\nTm1gdNEwgQndRC8+xKas2WfLbTRjJFapqW2zv3p1V83gVassrTLCCYSbV36jJO1z\nNpaU3feQPQL86+5ToNSoNepqYGInY6EYlKhkZHgVGRHsrqgPoyHGjBsyP4I3F1fO\njKcwPuGAerTn6MHtpW6m2kKnjz8qjClAPHY61ZmN9HIZHPTu1S7y9rHId5vy706X\nzwpQwpkCgYEA1H6/l6u2y1Rn2OSteIqTsxhZcJ3ICG8tSQp77fcFSi+LUDPAeBB9\nhvhiYpkzqj0sI5GIlXG+Wg7R8DwUxw6T+vQtFnFMdzqImqsU8+Qva/BqfRkFHsKO\n+FXGwLoWPVYJV25GD2gcDZpJ5KfNGv/hqrh0TEMtikVMKq30UaW58PMCgYEAoxNK\n+x3JnvzyMup/ZIgIlUjj2xy/V1AQq3+Ck3sQ9AaLZFuFPmHW1hKSXV/XBaDL3FfJ\nVVkWMRwmxgd4dMqosgWQYd69Qx5C3H0KKZh//9NpmV17WEiIknHSZbYxzeX14lsD\nWPiSeNdtrzTQRY0Q79JB2YTDUvABrRfJZe9eUc0CgYEAvg0q4MVktRCl3LgSaqhO\nl7TkcbO8r8Z300b8NoZjhclmKXJP51KgYrIOlK7/JXiW3K0SYs8bd8Kfg+TIlIx2\nT9JJ7TOiN1TzzpnLIKNqwniBVaemC6/pXTSikccdkvg7XKY1JRxxUr0277og2NAZ\nDq7w3TCML4nxKI7y4H+AAX8CgYA/T+o4fGQe2c2efvRer4HFk7sDArI2z9ro+mRT\npd/7Hd9YYz/j7FBgZG122xK8GKWNMnf0LtYy0t8q2xOlJFlCZG6d0MBiIomK2PDt\nHUv0orvI00ZkDCUZ1h79ZjMH4VQJQZSXIkqbp+fpsfN6TT5aHaN7M9QxiwTbkvSa\nIsjXsQKBgQCgMvR+jKE9OsCtM70eRBy0LDVEOjky7rce29I+cg3OZkAmKQ8qiE/S\no86+gQeQCMm9y9KiPHLVg9XIuZwkh+eVI4drRrEyM3InrHYLRtBuDfztCH9di+Ru\nF2w6y8t4/Kc5mSg0GBK725uTzfNdkyZE1TZAH6gx1KeSfMGGLP0mqw==\n-----END RSA PRIVATE KEY-----\n",
"RequestId": "01234562-5F4C-4DD9-BC42-ABCDEF26FF96",
"KeyPairName": "Test3"
}
Now, what do we do with the output? I tried just copying the screen output to a file and then importing into my key manager, but it rejected the input. Then I realized that the output is JSON data. So, I wrote a quick little program to take the output from the CLI and write the PrivateKeyBody from the JSON as a PEM file.
write_pem.py
############################################################
# Version 1.00
# Date Created: 2018-05-17
# Last Update: 2018-05-17
# https://www.neoprime.io
# Copyright (c) 2018, NeoPrime, LLC
############################################################
"""
This program reads standard input and writes to standard output
The input is expected to be the output from the Alibaba Cloud CLI command:
aliyuncli ecs CreateKeyPair --RegionId us-west-1 --KeyPairName Test3
"""
import sys
import json
data = json.loads(sys.stdin.read())
print(data['PrivateKeyBody'])
Go back to the Alibaba Console and delete the Test3 Key Pair. Now let's try again but this time sending the output to write_pem.py.
aliyuncli ecs CreateKeyPair --RegionId us-west-1 --KeyPairName Test3 | python write_pem.py > Test3.pem
Now let's look at the contents of Test3.pem.
type Test3.pem
Excellent, this looks like a normal PEM file.
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAmPJORshGZmC+vV58zMAGRBKJs0Bs/bSHvwQtu+ICSNDyUj9+
3l0yCXm3rbYHV0OT4sqMAhZf7dowryRpQRwU2f1YS6Jga/PnuOQ8rhHTgO8jImdj
OWKB02G6SCIB5M/ddrHiEeih/5dIPA4ztZjm3A2ps22KSDFOg0TOybK0HbnWbFKh
FIiS2QqoF4p0+Pe14jKkHEvFDKSIBs7WIAYIjCloQ7DfIy4StjPxUYD9xBbvN4vj
o47yMi9qyoXqyzrTZ1rcqiWeQuv8343sHJ6Rj+yO+yT+dZWCZiY7zMU5pKa3sDds
LD3XwqZYJ1X+ddMpmxngU5zBIi/uPzx7PFf05wIDAQABAoIBABPthktsrteKBXAx
DnuzDV3zOGPVoh3QVtuJlNflE70fFGOpCEO6ytk3Nbp5fC1fjbZAA8wF1EvuYOeB
DAHCwejBPK7mIkAOkIOjoVBg3Djxb5d89w20CwxasGXToIGKn+VmOflxYSInOO8y
PoSLvpCvawwI2rqbSgqKfZMEKLmyl9zQ6gAa4lLC3AMAxv9mFgfnTZtzXwNWmFXW
74MX5LGG8IEK4I18UBaKmYzBZOQ+gNVtKPnhYGe0MC51r6NvBVbA1FHnXSqiHZXq
Ra7g543BFmDa96cIT/hfRhOfY0RxvwE+/84e8/TQ6UqQt3ZPb7eaddIO15YluObC
7vOkDAkCgYEA5bww+BUdIEmZ2EwAScX7lHq1d/tMSGsosEp55IDyMDOAvdexVBVZ
xwVf8RRhWv7d2Y2PMqGQSp2I/4CTpdvfnA/E0usGtKfcgeRZBuSTmfiriUO3+8zm
G2J2Eg0mUqR2QoXlOzHJ62j70jP8JxC/yAyu5+qa6TiInfJftrwh9wMCgYEAqm6x
D3gX0fe0uTG3278jqU3n6ooy44f7gfrFsDvkJzYaUb3FwPKFfaRV9j6nfHd5B6Ks
EBp6WAqDle5cdLCO6J8GCp+9tweFHZ9SaGhDYHECmYzQUbdoDLlM2wYetfVWCgvz
e5CwuHYuX1oXrKwhrkYwxCtZJ/W57gp9zJuz400CgYEAi6uSigEsKAkXQ21Rb4iy
n17LHRrnEdA0eJmO6eGLXMqzJrgP03L3lgwqfENLvSrebfmmab3YH8UPGWduXJQE
qrjbjO/er86uPTo69fnZ0u5gO5+0J54298cwyWC9P9lFHMSSzR5ECJ9XGkEIuCdy
sYkkfVMgw1HfnUdR8aMHc0kCgYASLt0VGWrxK8xMNdG30Byt43Hqw/PJ8qgSpf6R
XtJonI0SS3zdqQI09WN2chjMXrK67dANp8WFvxlq1ZNnn66fgtfSKljDPjolfun7
2aPWljgAydUv4rFnKh3ZAD4mi5YyXDQN6tHv3Cv2YFZGRdcSEMsDItzQNpcvnk7t
lW8LwQKBgEP1uYJMV4HU3MJLqsyPZDTkkCA/a6g3Lkd7+XUlDfxMmm2Q7rjUI6su
l7yIU/T+zRW7+naytm7tPDiL3NoAFQG9bEJo+9nnobM6fsyVyX/jcVFQ+AnjTgE+
6h+ANs/jyLDnxUecSx2ITYA57lsapv+OatcPFnjUvi/+9Ut/vooI
-----END RSA PRIVATE KEY-----
Let's verify that this works by assigning this key pair to our ECS instance, rebooting and verifying that we can now connect via SSH using key pair Test3.pem.
aliyuncli ecs AttachKeyPair --InstanceIds "[\"i-abcdeftvgllm854abcde\"]" --KeyPairName Test3 `
aliyuncli ecs RebootInstance --InstanceId i-abcdeftvgllm854abcde
The previous part created a key pair using Alibaba Cloud. This means that at some point Alibaba Cloud has our private key. Let's now investigate creating our own key pair locally using OpenSSL and then importing just the public key to Alibaba Cloud.
Generate a key pair using OpenSSL.
openssl genrsa -out Test4.pem 2048
Save the public key to a local file
#openssl rsa -in Test4.pem -pubout -out Test4.pub
ssh-keygen -y -f test5.pem > Test4.pub
Now that we have a new key pair (Test4.pem) and the public key (Test4.pub), let's import this into the cloud and verify that we can use this key pair with our test instance.
The API to use is ImportKeyPair. Let's look at this API. This API is documented to have the following features:
Next, review the API documentation for ImportKeyPair. The documentation indicates that RegionId, KeyPairName, and PublicKeyBody are required. This corresponds to the ImportKeyPair parameters:
Note: I could not find anywhere what the format of PublicKeyBody is.
Contents of Test4.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrk3VshObZ8zz6DLQb6yUhC8+gOrm/tu8psXASVPh4FqTkfiMu/DuTNfUV+j3KYTBnHdfEZoydtNNt1JrXi3rngvZsfgBzGw8Yqoyu+CdsR3wrI2LCqgpAOa06MS6iydu+xRo8c/JTZHpscE/igxqF4bNIYHVCHoBV6wKSo4VQSN0m8UB3Je1u9ga0V4jXpPPJZnBa3n9aafNzikTFeycBwbauJjsrY2IpL3xybkwPE14hdkbUxMEFu9cO+FNSTPFGq5UxXsS1vQkPySm5WHgF/N4zC/HMfiNjwwiwKxW+GZnOsCKSbqBBFwRJj+7N3OlIZ2sgEBSQGHYAWAEHU7Od
The final command looks like this:
aliyuncli ecs ImportKeyPair --RegionId us-west-1 --KeyPairName Test4 --PublicKeyBody "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrk3VshObZ8zz6DLQb6yUhC8+gOrm/tu8psXASVPh4FqTkfiMu/DuTNfUV+j3KYTBnHdfEZoydtNNt1JrXi3rngvZsfgBzGw8Yqoyu+CdsR3wrI2LCqgpAOa06MS6iydu+xRo8c/JTZHpscE/igxqF4bNIYHVCHoBV6wKSo4VQSN0m8UB3Je1u9ga0V4jXpPPJZnBa3n9aafNzikTFeycBwbauJjsrY2IpL3xybkwPE14hdkbUxMEFu9cO+FNSTPFGq5UxXsS1vQkPySm5WHgF/N4zC/HMfiNjwwiwKxW+GZnOsCKSbqBBFwRJj+7N3OlIZ2sgEBSQGHYAWAEHU7Od"
This is complicated enough that a Python program is a better choice.
Let's verify that this works by assigning this key pair to our ECS instance, rebooting and verifying that we can now connect via SSH using key pair Test4.pem.
aliyuncli ecs AttachKeyPair --InstanceIds "[\"i-abcdeftvgllm854abcde\"]" --KeyPairName Test4
The command returns the following:
{
"KeyPairFingerPrint": "883aff9af03f3ee5dd0e186099a2e173",
"RequestId": "11CC0000-4675-4F9A-887F-ABCDEFEF7D5B",
"KeyPairName": "Test4"
}
The ECS instance must be rebooted for the new key pair to take effect.
aliyuncli ecs RebootInstance --InstanceId i-abcdeftvgllm854abcde
Note: This section covers Ubuntu 16.04. Most Linux versions have similar procedures.
In this section we will create a new group "developers", a new user "john" as part of the developer group, assign sudo privileges and finally assign an SSH key to login with.
Steps 1 to 4 are performed on the ECS instance.
Step 1. Create a new group named developers. The groupadd command requires a unique number for the Group ID. Display the contents of the file /etc/group. Find the highest number. In my system it is 118. For the new Group ID, I will use 1000.
# cat /etc/group
Execute the following commmand to create a group with the Group ID 1000 named developers:
# groupadd -g 1000 developers
Step 2. Create a new user named john. This command will prompt you for a password for the user, user information, etc.
# adduser john
Review the command output. One of the items will be the home directory for the new user. We will need this path later. In my case the home directory is /home/john.
Add user john to the group developers.
# adduser john developers
Step 3. Add the user to the "sudo" group so that the user has root privileges when required to administer the system. Once this user is logged in, all that is required is using the sudo command in front of each command to obtain administrator privileges.
# usermod -aG sudo john
Step 4. Create a directory for the SSH keys. When a user logs in remotely using SSH, the SSH server will look in the file /home/username/.ssh/authorized_keys for a matching public key. If a match is found the user is granted access. This file can contain more than one public key stored one after another, one per line.
# cd /home/john
# mkdir .ssh
Create an empty authorized_keys file.
# touch /home/john/.ssh/authorized_keys
SSH enforces file and directory permissions to prevent SSH key leakage. It is important that you do not skip these steps.
# chmod 700 /home/john/.ssh
# chown john /home/john/.ssh
# chmod 600 /home/john/.ssh/authorized_keys
# chown john /home/john/.ssh/authorized_keys
Step 5. Create a new key pair. We will use the same steps as above. Once the public key is created, we will add the contents of the public key to the file authorized_keys.
The following commands are performed on your Windows system.
Generate a key pair using OpenSSL.
openssl genrsa -out john.pem 2048
Save the public key to a local file
ssh-keygen -y -f john.pem > john.pub
Add the contents of john.pub to /home/john/.ssh/authorized_keys on the Linux system.
Import the private key john.pem into Bitvise (or your favorite SSH key manager).
Command Line Interface (CLI):
2,599 posts | 765 followers
FollowAlibaba Clouder - May 28, 2018
Alibaba Clouder - October 12, 2019
Alibaba Clouder - May 20, 2019
Alibaba Clouder - June 1, 2018
Alibaba Clouder - June 5, 2018
Alibaba Clouder - June 14, 2019
2,599 posts | 765 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreLearn More
Learn More
More Posts by Alibaba Clouder