1

I am launching an EC2 instance using cloudformation. I want to enable SSH with a password instead of pem key for that instance. I am able to write the startup script (user data) to do this, but I have set the static password 'pass123' for user 'student'. I want to make this dynamic (random). We would be happy with anything, really, other than SSH client certificate authentication.

Here is my cloudformation template:

{
   "AWSTemplateFormatVersion":"2010-09-09",
   "Description":"Password for instance",
   "Parameters":{
      "KeyName":{
         "Description":"Name of an existing EC2 KeyPair",
         "Type":"String"
      },
      "AWSAmiId":{
         "Description":"AMI Id to find",
         "Type":"String",
         "Default":"x86_64,amzn-ami-pv-2014.09.1.x86_64-ebs,amazon,ebs,paravirtual"
      }
   },
   "Resources":{
      "Ec2Instance":{
         "Type":"AWS::EC2::Instance",
         "DependsOn":"Ec2SecurityGroup",
         "Properties":{
            "ImageId":{
               "Ref":"AWSAmiId"
            },
            "InstanceType":"t1.micro",
            "Tags":[
               {
                  "Key":"Name",
                  "Value":"MYINSTANCE"
               }
            ],
            "DisableApiTermination":"true",
            "SecurityGroupIds":[
               {
                  "Ref":"Ec2SecurityGroup"
               }
            ],
            "KeyName":{
               "Ref":"KeyName"
            },
            "UserData":{
               "Fn::Base64":{
                  "Fn::Join":[
                     "\n",
                     [
                        "#!",
                        "useradd student\n",
                        "echo pass123 | passwd student --stdin\n",
                        "echo \"student ALL=(ALL) NOPASSWD: ALL\" | tee -a /etc/sudoers\n",
                        "mkdir /home/student/.ssh\n",
                        "cp cp ~ec2-user/.ssh/authorized_keys ~student/.ssh/authorized_keys\n",
                        "sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config\n",
                        "service sshd reload\n"
                     ]
                  ]
               }
            }
         }
      },
      "Ec2SecurityGroup":{
         "Type":"AWS::EC2::SecurityGroup",
         "Properties":{
            "GroupDescription":"VPC Security Group",
            "SecurityGroupIngress":[
               {
                  "CidrIp":"0.0.0.0/0",
                  "FromPort":"22",
                  "IpProtocol":"tcp",
                  "ToPort":"22"
               }
            ]
         }
      }
   },
   "Outputs":{
      "Password":{
         "Description":"newly created EC2 instance",
         "Value":"pass123"
      }
   }
}

Password could be:

  • The filename of the SSH key

  • The AMZN account ID (eg: 45678923)

  • A random string (poiblkjfda)

Atish Kumbhar
  • 579
  • 1
  • 8
  • 21
  • And what is the problem? – INVOKE Cloud Apr 25 '18 at 20:31
  • I want to assign this password any random string, instead hard coded 'pass123' – Atish Kumbhar Apr 25 '18 at 20:34
  • Just use a different password in your User Data in the console. Or, if you trigger the launch from a script, have the script choose a password. Is your problem how to generate a random string, or how to include it in the User Data? – John Rotenstein Apr 26 '18 at 01:39
  • @JohnRotenstein, I am looking for 1. How to generate a random string? 2. How to display in the stack output (include in the output section of cloud formation)? – Atish Kumbhar Apr 30 '18 at 13:53

2 Answers2

0

If your requirement is to generate a random string as a password you can use /dev/urandom. For a 10 character string

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 10 ; echo ''

You can include this in your user data instead of the static passphrase.

Udara Jayawardana
  • 1,073
  • 2
  • 14
  • 27
0

There are several options for returning the random password:

  • You could generate it prior to calling CloudFormation. That is, whatever triggers CloudFormation could generate the password, and pass it to the stack as a Parameter. You can then show the Parameter as an Output.
  • You could return the value as part of a CloudFormation WaitCondition, then show the result as an Output.
  • You could generate the password in an AWS Lambda-backed Custom Resources, which is then available to be inserted into the User Data and provided as an Output.
  • You could configure the User Data to store the password in the AWS Secrets Manager, which is more secure than showing it as a stack Output. The user would then retrieve the password themselves.

Only the first one is simple. The rest involve some configuration/coding.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Is there any sample snippet to do this? Becaus, I tried with defining Parameter but no luck. May be I am trying wrongly :( – Atish Kumbhar May 01 '18 at 04:19
  • You might be able to find something via a web search, but your need is fairly unique to your use-case. Try coding it yourself. If you encounter a problem, you can always post another question, showing your code and the problem you are experiencing. – John Rotenstein May 01 '18 at 04:58