Amazon ec2 丢失密钥对后访问EC2实例

Amazon ec2 丢失密钥对后访问EC2实例,amazon-ec2,Amazon Ec2,几个月前我启动了一个EC2实例,当时我的电脑中存储了.pem密钥。此后电脑崩溃,我不得不在其上重新安装Windows,我没有.pem文件的备份 有没有任何方法可以让我在EC2实例上得到提示?有没有任何方法可以通过ssh或其他方式得到该实例?不容易 论坛上的指南表明,您可以通过生成一个新的密钥对,然后启动一个新实例,从原始实例装入卷,然后在该卷中安装密钥对来实现这一点。之后,原始实例应该能够使用新的密钥对 根据需要,可通过以下方式完成: 创建一个新的密钥对会将私钥下载到您的计算机中,公钥存储在您的

几个月前我启动了一个EC2实例,当时我的电脑中存储了.pem密钥。此后电脑崩溃,我不得不在其上重新安装Windows,我没有.pem文件的备份

有没有任何方法可以让我在EC2实例上得到提示?有没有任何方法可以通过ssh或其他方式得到该实例?

不容易

论坛上的指南表明,您可以通过生成一个新的密钥对,然后启动一个新实例,从原始实例装入卷,然后在该卷中安装密钥对来实现这一点。之后,原始实例应该能够使用新的密钥对

根据需要,可通过以下方式完成:

创建一个新的密钥对会将私钥下载到您的计算机中,公钥存储在您的AWS帐户中。当您启动一个新的(linux)实例时,公钥被放入/root/.ssh/authorized_keys文件(或规范ubuntu AMI的/home/ubuntu/.ssh/authorized_keys),允许您的私钥访问该实例

如果您已经设置了一个linux帐户,则可以通过另一个linux帐户登录实例来修复私钥丢失的问题

或者,如果您正在运行一个支持EBS的实例,则可以停止该实例,将根EBS卷附加到另一个实例,并将新的公钥放入授权的_密钥文件中,然后将该卷返回到原始(已停止)实例并再次启动该实例

如果这些都不起作用,那么——对不起——你就不走运了。它叫钥匙,因为没有它你进不去


您必须创建当前实例的映像,然后使用该映像启动新实例。所有文件和数据都将从该实例复制,并在启动实例时使用不同的密钥,然后使用相同的密钥访问该实例

当我们失去私钥时,您无法登录到该计算机。但是,还有另一种方法可以通过生成新的密钥对来访问该机器

请按照以下步骤恢复密钥

步骤1)使用AWS控制台将根卷与计算机分离。
步骤2)启动一个新的EC2实例(不是从旧机器AMI启动)
步骤3)将旧卷连接到新的EC2机器
步骤4)现在登录到新的ec2机器并装载旧的EBS卷
步骤5)现在转到该分区,然后访问该计算机内的主目录并转到.ssh文件夹。
步骤6)现在生成新的私钥和公钥。然后将公钥粘贴到授权密钥文件中。
步骤7)完成上述步骤后,将该卷从此ec2机器上分离。
步骤8)现在将此卷作为根卷连接到旧计算机
步骤9)现在尝试使用新生成的密钥登录到旧计算机


希望能有所帮助

总体思路:使用AWS实例用户数据将新的ssh rsa公钥写入/root/.ssh/authorized_key。linux实例上安装的cloud init包需要支持bootcmd指令。在Ubuntu 16.04和18.04中,它对我有效

用户数据示例:

#cloud-config
bootcmd:
 - echo 'ssh-rsa AAAAB3NzaC1... key-comment' > /root/.ssh/authorized_keys
这可以手动完成,例如使用PuTTYgen生成新密钥,并通过AWS控制台在EC2实例上设置用户数据

或自动化,例如使用Java,使用和:

最后测试连接,例如使用FileZilla:

这很有帮助!
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) };
  }
}