Transmit the public SSH key to the instance without cloud-init

0

Hi,

Below a snippet of our code to ask for an SSH Key name:

"Parameters": {
        ...
	"CGSSHKeyName": {
            "Description": "SSH public key to access to the CacheGuard appliance",
	    "Type": "AWS::EC2::KeyPair::KeyName",
	    "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
        },
        ...
 }

And the related "Properties" part of the AWS::EC2::Instance to create:

"KeyName": {
         "Ref": "CGSSHKeyName"
 }

Very classical until now, right?

What is not classical is that our OS don't embed cloud-init (and we definitely don't want to use it). Therefore, the specified SSH public key is not automatically installed on our instance. That's why we are looking for a low level way to transmit that SSH public key to our instance so we can install it on the right location. Maybe by pushing it using UserData (if possible but we don't know what attribute to use) or by pulling it from our instance from the http://169.254.168.254 server (if possible and again we don't know the right URL).

Does anybody have any ideas on how to do that?

Best Regards,

CG

profile picture
asked 9 months ago262 views
3 Answers
1

For example, why not register the private key in the Systems Manager parameter store and create a script with "Userdate" to retrieve the key from there?
To use this method, it is necessary to execute AWS APIs in Userdata, so EC2 must be configured with IAM roles, etc.
https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html

Also, I believe that Userdata cannot be used unless cloud-init is installed.
I think I need cloud-init to run Userdata.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html

profile picture
EXPERT
answered 9 months ago
profile pictureAWS
EXPERT
reviewed 9 months ago
  • +1 that you cant have User Data without cloud-init. cloud-init is the service that executes the User Data script - the output from running the User Data script is in /var/log/cloud-init-output.log.

    Systems Manager Parameter Store is a more elegant solution, for something quick and dirty just to see if it works you could store the public key as an object in an S3 bucket (no public access, secured with KMS, etc.) and then give the new EC2 instance enough privileges in an attached IAM role to retrieve the key.

0
Accepted Answer

Well, in absence of any satisfactory answer we did some research to we find the solution and we are happy to share it here.

The URL http://169.254.169.254/latest/meta-data/public-keys returns a list of SSH public key references in the form: <index>=<key-name> (for example 0=johndoe)

To get the content of an SSH key in OpenSSH format you can just request the URL http://169.254.169.254/latest/meta-data/public-keys/<index>/openssh-key (for example http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key.

That's it!

profile picture
answered 9 months ago
profile pictureAWS
EXPERT
reviewed 9 months ago
0

Hi,

Thanks for your answers and comments. But we can't consider them as solutions in our case. We are not just looking for solutions to make it work at all costs.

Maybe we had to begin by specifying the context of our need: we are looking to write a CloudFormation template to facilitate the deployment of a network security appliance. We need to design a simple UI/Form that users can quickly understand and fill out. The OS on which our solution is based is a derivation of LFS (Linux From Scratch) and has the vocation of being minimalist --> It embeds only what is really needed in our appliance. Installing cloud-init is just useless for us and adds its part of complexity (that we don't need). In addition, it's installation from the source code requires systemd which is even more useless in our case (we use the sysvinit system which is as robust and enough).

Also, this is not true that UserData can only be used with the help of cloud-init. You can perfectly pull UserData from the URL http://169.254.168.254/latest/user-data and do whatever you want with it in your OS instance. You can also pull the name of public SSH keys that you submit (with the help of a CloudFormation template) from another URL... cloud-init should fetch the public key using an interface with the cloud provider. That's exactly what we are looking for.

Best Regards, CG

profile picture
answered 9 months ago
  • Fair point about using User Data as a medium for passing data to the instance, but not executing it. In this use case Systems Manager Parameter Store would likely be a better fit for what you want to do. As is AWS Secrets Manager, though that's probably overkill if it's for a public key.

  • UserData as its name suggests must be data and not programs. As a reminder, you can download it from your instance by requesting the URL http://169.254.168.254/latest/user-data (using curl for instance). Afterwards you can use it as an input for the program of your choice (during you OS startup for instance)... We think that there is an improper agreement between cloud-init developers and AWS developers to go beyond this initial design.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions