Access to EC2 instance after keypair loss

I downloaded an EC2 instance a few months ago, and at that time I had a .pem key stored on my PC. The PC crashed, and I had to reinstall Windows on it, and I do not have a backup copy of the .pem file.

Is there any way to get an invitation to an EC2 instance - in any way ssh or otherwise get into the instance?

+9
source share
4 answers

Not easy.

The manual on the forums shows that you can do this by creating a new key pair, then creating a new instance and installing the volume from the original instance and installing the key pair in this volume. After that, the source instance should be able to use a new key pair.

According to this post on AWS Developer Forums, you can do this with:

Creating a new key pair downloads the private key to your computer, and the public key is stored in your AWS account. When starting a new instance (linux), the public key is placed in the file /root/.ssh/authorized_keys (or / home / ubuntu / .ssh / authorized_keys for Canonical Ubuntu AMI), allowing your private key to access the instance.

Private key loss can be fixed by logging into the instance through another linux account if you installed it.

Alternatively, if you are using an EBS-enabled instance, you can stop it, attach the EBS root volume to another instance and put the new public key in the authorized_keys file, then return the volume to the original (stopped) and restart the instance.

If none of them work, then - sorry - you're out of luck. He called the key, because without it you cannot enter.

+8
source

You need to create an image of the current instance, and then use this image to start a new instance. All files and data will be copied from this instance and use a different key when starting the instance, and then access it with the same key

+3
source

When we lose the secret key, you cannot enter this machine. However, there is another way to access this machine by creating a new key pair

To restore the key, follow these steps.

Step 1) Detach the root volume from your computer using the AWS console.
Step 2) Launch a new instance of EC2 (not from your old AMI computer)
Step 3) Attach your old volume to the new EC2 machine
Step 4) Now enter the new ec2 machine and install the old EBS volume
Step 5) Now go to this section, then go to the home directory inside this machine and go to the .ssh folder.
Step 6) Now create a new private and public key. Then paste the public key into the authorized_keys file.
Step 7) After you have completed the above steps, disconnect this volume from this ec2 machine.
Step 8) Now attach this volume to your old machine as the root volume
Step 9) Now try to enter your old car using the newly created key.

Hope this helps!

+2
source

The general idea is to use AWS instance user data to write the new ssh-rsa public key in /root/.ssh/authorized_keys. The cloud-init package installed on the linux instance must support the bootcmd directive. This worked for me with Ubuntu 16.04 and 18.04.

Example user data:

#cloud-config bootcmd: - echo 'ssh-rsa AAAAB3NzaC1... key-comment' > /root/.ssh/authorized_keys 

This can be done manually, for example, generate a new key using PuTTYgen and set user data for the EC2 instance through the AWS console.

Or automated, for example, using Java, using the AWS EC2 Java SDK and Bouncy Castle :

 import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPublicKey; import java.text.SimpleDateFormat; import java.util.Base64; import java.util.Date; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.AmazonEC2ClientBuilder; import com.amazonaws.services.ec2.model.DescribeInstancesRequest; import com.amazonaws.services.ec2.model.InstanceStateName; import com.amazonaws.services.ec2.model.ModifyInstanceAttributeRequest; import com.amazonaws.services.ec2.model.StartInstancesRequest; import com.amazonaws.services.ec2.model.StopInstancesRequest; public class RecoverAwsEc2RootSshAccess { public static void main(String[] args) throws Exception { // use the AWS console to create an AWS IAM user with ec2 permissions for your region, and generate security credentials String awsAccessKey = "..."; String awsSecretKey = "..."; Regions region = Regions.US_EAST_1; String instanceId = "i-..."; File pemKeyFile = new File("private.key.pem"); String keyComment = "key-generated-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date()); KeyPair keyPair; if(pemKeyFile.exists()) { System.out.println("reusing existing RSA private key: " + pemKeyFile.getAbsolutePath()); try(PEMParser pemParser = new PEMParser(new FileReader(pemKeyFile))) { keyPair = new JcaPEMKeyConverter().getKeyPair((PEMKeyPair) pemParser.readObject()); } } else { System.out.println("generating new RSA private key: " + pemKeyFile.getAbsolutePath()); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); keyPair = keyGen.generateKeyPair(); try(JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(pemKeyFile))) { pemWriter.writeObject(keyPair.getPrivate()); } } String authorized_keys = to_authorized_keys_line(keyPair, keyComment); String userdata = "#cloud-config"; userdata += "\n" + "bootcmd:"; userdata += "\n" + " - echo '" + authorized_keys + "' > /root/.ssh/authorized_keys"; String userdataBase64 = Base64.getEncoder().encodeToString(userdata.getBytes(StandardCharsets.UTF_8)); System.out.println("AWS instance user-data (can also be set manually via the AWS console):"); System.out.println(userdata); AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard().withRegion(region) // .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey))).build(); // stop, set userdata, start ec2.stopInstances(new StopInstancesRequest().withInstanceIds(instanceId)); waitForInstanceState(ec2, instanceId, InstanceStateName.Stopped); ec2.modifyInstanceAttribute(new ModifyInstanceAttributeRequest().withInstanceId(instanceId).withUserData(userdataBase64)); ec2.startInstances(new StartInstancesRequest().withInstanceIds(instanceId)); waitForInstanceState(ec2, instanceId, InstanceStateName.Running); // optional: stop, clear userdata, start System.out.println("new IP: " + ec2.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceId)).getReservations() .get(0).getInstances().get(0).getPublicIpAddress()); // next step: automate DNS update } private static void waitForInstanceState(AmazonEC2 ec2, String instanceId, InstanceStateName desiredState) throws Exception { String currentState = "?"; while(!currentState.equals(desiredState.toString())) { Thread.sleep(3_000); currentState = ec2.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceId)).getReservations().get(0) .getInstances().get(0).getState().getName(); System.out.println("instance state: " + currentState + " (waiting for " + desiredState + ")"); } } /** https://stackoverflow.com/questions/3706177/how-to-generate-ssh-compatible-id-rsa-pub-from-java */ private static String to_authorized_keys_line(KeyPair key, String keyComment) throws IOException { byte[] exponent = ((RSAPublicKey) key.getPublic()).getPublicExponent().toByteArray(); byte[] modulus = ((RSAPublicKey) key.getPublic()).getModulus().toByteArray(); ByteArrayOutputStream out = new ByteArrayOutputStream(); out.write(new byte[] { 0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a' }); out.write(toUInt32(exponent.length)); out.write(exponent); out.write(toUInt32(modulus.length)); out.write(modulus); return "ssh-rsa " + Base64.getEncoder().encodeToString(out.toByteArray()) + " " + keyComment; } private static byte[] toUInt32(int value) { return new byte[] { (byte) (value >>> 24 & 0xff), (byte) (value >>> 16 & 0xff), (byte) (value >>> 8 & 0xff), (byte) (value & 0xff) }; } } 

Finally, check the connection, for example, using FileZilla:

enter image description here

0
source

All Articles