Launch and SSH to EC2¶
本文主要介绍了如何使用 SSH 连接到 AWS EC2.
Step1. Launch EC2¶
本质上 EC2 就是使用 虚拟机软件, 例如 VMWare, 在亚马逊的数据中心上运行的虚拟机. 虚拟机主要作为服务器使用, 这里面 90% 以上的服务器是 Linux.
Step2. Connect via SSH¶
Grant access to your pem key:
chmod 400 ~/ec2-pem/<key-pair-name>.pem
SSH connect:
$ ssh -i {path-to-your-pem-file} {username}@{ip-address}
path-to-your-pem-file
: it is where you store your EC2 SSH Key Pair.pem
file, usually, you should put it at${HOME}/ec2-pem/<key-pair-name>.pem
username
: the operation system username account. By default, if it is Amazon Linux, it isec2-user
. If it is ubuntu, it isubuntu
. It is not your IAM username!ip-address
: For EC2 on public subnet, public IPV4 address, can be found at your EC2 instances dashboard. For EC2 on private subnet, it is private IPV4 address.
Reference:
Connecting to Your Linux Instance Using SSH: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
Transferring Files to Linux Instances from Linux Using SCP
Step3. Connect via SSH the Better Way¶
由于在我们启动一个 EC2 的时候, 是并不知道他的 public ip 地址的. 而每次 EC2 关闭再启动后, 这个 IP 地址都会改变. 我们希望提供一小段代码, 使得每次想要 SSH 到 EC2 上的时候, 只要快速的复制粘贴即可.
# specify your ec2 name
EC2_NAME="your-ec2-name"
# specify your cli profile
AWS_PROFILE="your-aws-cli-profile"
# retrieve public ip
EC2_IP="$(aws ec2 describe-instances --filters "Name=tag:Name,Values=${EC2_NAME}" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text --profile ${AWS_PROFILE})"
# retrieve private ip
EC2_IP="$(aws ec2 describe-instances --filters "Name=tag:Name,Values=${EC2_NAME}" --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text --profile ${AWS_PROFILE})"
# specify the default user, for redhat, centos, amazon linux, it is ec2-user. for ubuntu it is ubuntu
EC2_USER="ec2-user"
# specify the location of your pem file
EC2_PEM="path-to-your-pem-file"
# run ssh connect
echo EC2_PEM="${EC2_PEM}", EC2_USER="${EC2_USER}", EC2_IP="${EC2_IP}" && ssh -i ${EC2_PEM} ${EC2_USER}@${EC2_IP}
Step4. Copy file or dir between EC2 and local machine via SSH Copy¶
Reference:
Linux – How to Securely Copy Files Using SCP examples: https://haydenjames.io/linux-securely-copy-files-using-scp/
# Copy file from a EC2 to local host:
$ scp -i {path-to-your-pem-file} <username>@<ec2-ip>:<path-to-ec2-file> <path-to-file>
# Copy file from local host to a EC2:
$ scp -i {path-to-your-pem-file} <path-to-file> <username>@<ec2-ip>:<path-to-ec2-file>
# Copy directory from a EC2 to local host:
$ scp -i {path-to-your-pem-file} -r <username>@<ec2-ip>:<path-to-ec2-dir> <path-to-dir>
# Copy directory from local host to a EC2:
$ scp -i {path-to-your-pem-file} -r <path-to-dir> <username>@<ec2-ip>:<path-to-ec2-dir>
Tool¶
# -*- coding: utf-8 -*-
"""
Generate the ssh command to connect to ec2 for you.
You have to put your ec2 key pair (.pem) file at ${HOME}/${AWS_ACCOUNT_ALIAS}/${AWS_REGION}/${KEY_NAME}
Ref:
- Default user name for AMI: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connection-prereqs.html#connection-prereqs-get-info-about-instance
- For Amazon Linux 2 or the Amazon Linux AMI, the user name is ec2-user.
- For a CentOS AMI, the user name is centos.
- For a Debian AMI, the user name is admin.
- For a Fedora AMI, the user name is ec2-user or fedora.
- For a RHEL AMI, the user name is ec2-user or root.
- For a SUSE AMI, the user name is ec2-user or root.
- For an Ubuntu AMI, the user name is ubuntu.
"""
import boto3
from pathlib import Path
# ------------------------- File in value here -------------------------
aws_profile = "your_aws_profile"
aws_region = "us-east-1"
ec2_name = ""
# ----------------------------------------------------------------------
print(f"try to create the ssh connect command for the ec2 {ec2_name!r} ...")
boto_ses = boto3.session.Session(profile_name=aws_profile, region_name=aws_region)
ec2_client = boto_ses.client("ec2")
iam_client = boto_ses.client("iam")
def get_aws_account_alias() -> str:
return iam_client.list_account_aliases()["AccountAliases"][0]
def get_instance_dict(ec2_name: str) -> dict:
res = ec2_client.describe_instances(
Filters=[
dict(
Name="tag:Name",
Values=[
ec2_name,
]
)
]
)
inst_dict = res["Reservations"][0]["Instances"][0]
return inst_dict
def get_image_name(image_id: str) -> str:
image_dct = ec2_client.describe_images(
ImageIds=[image_id, ]
)["Images"][0]
image_name = image_dct["Name"]
return image_name
aws_account_alias = get_aws_account_alias()
instance_dict = get_instance_dict(ec2_name)
public_ip = instance_dict["PublicIpAddress"]
image_id = instance_dict["ImageId"]
key_name = instance_dict["KeyName"]
image_name = get_image_name(image_id)
pem_file_path = (
Path.home().absolute()
/ "ec2-pem"
/ aws_account_alias
/ aws_region
/ f"{key_name}.pem"
)
if image_name.startswith("amzn"):
username = "ec2-user"
elif image_name.startswith("RHEL"):
username = "ec2-user"
elif image_name.startswith("suse"):
username = "ec2-user"
elif image_name.startswith("fedora"):
username = "ec2-user"
elif image_name.startswith("ubuntu"):
username = "ubuntu"
elif image_name.startswith("debian"):
username = "admin"
else:
username = "ec2-user"
cmd = "ssh -i {ec2_pem} {username}@{public_ip}".format(
ec2_pem=pem_file_path, username=username, public_ip=public_ip,
)
if pem_file_path.exists():
print("enter the following command to terminal:")
print()
print(cmd)
else:
raise FileNotFoundError(f"{pem_file_path} not found!")