三步干掉堡垒机:EC2 Instance Connect Endpoint 从零搭建指南
公司有十几台 EC2 跑在 Private Subnet,运维流程是这样的:
- 连 VPN
- SSH 到堡垒机
- 从堡垒机 SSH 到目标实例
三层跳转,光认证就两分钟。堡垒机还得维护——打补丁、轮密钥、开安全审计。说白了它本身就是个攻击面,放在公网上等人来扫。
后来用了亚马逊云科技的 EC2 Instance Connect Endpoint(EICE),直接从本地 SSH 到 Private Subnet 实例。不要公网 IP,不要堡垒机,不要 VPN。认证走 IAM,审计走 CloudTrail,免费。
这篇从零开始搭。
EICE 是什么
一句话:亚马逊云科技 在你的 VPC 里放了个托管的隧道入口,让你通过 亚马逊云科技 API 建立到私有实例的 SSH 隧道。
你的电脑 → AWS API → EICE(VPC内部)→ 私有子网 EC2
和堡垒机对比:
| 堡垒机 | EICE | |
|---|---|---|
| 公网 IP | 必须有 | 不需要 |
| 维护 | 打补丁、轮密钥 | 零维护 |
| 认证 | SSH 密钥 | IAM 策略 |
| 审计 | 自己搞 | CloudTrail 自动 |
| 费用 | EC2 实例费 | 免费 |
| 权限粒度 | 登上堡垒机就能到处跳 | 按实例/标签精确控制 |
最后一行是关键——堡垒机上一旦登录,理论上可以 SSH 到 VPC 内任何实例。EICE 通过 IAM 条件键,可以限制到"只能连 staging 环境的实例"。
第一步:创建 EICE
CLI 一行搞定:
aws ec2 create-instance-connect-endpoint \
--subnet-id subnet-0123456789abcdef0 \
--security-group-ids sg-0123456789abcdef0 \
--region ap-northeast-1
Python 版本:
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-1')
response = ec2.create_instance_connect_endpoint(
SubnetId='subnet-0123456789abcdef0',
SecurityGroupIds=['sg-0123456789abcdef0'],
PreserveClientIp=False
)
endpoint_id = response['InstanceConnectEndpoint']['InstanceConnectEndpointId']
print(f'创建中: {endpoint_id}')
创建要 2-3 分钟。查状态:
result = ec2.describe_instance_connect_endpoints(
InstanceConnectEndpointIds=[endpoint_id]
)
print(result['InstanceConnectEndpoints'][0]['State'])
# create-complete 就好了
注意事项:
- 和目标实例要在同一个 VPC(不要求同子网)
- 每个 VPC 最多 5 个 EICE
第二步:配安全组
两条规则,别搞反方向:
ec2_resource = boto3.resource('ec2', region_name='ap-northeast-1')
# EICE 安全组:出站放通 → 目标实例 SSH
eice_sg = ec2_resource.SecurityGroup('sg-eice-xxx')
eice_sg.authorize_egress(
IpPermissions=[{
'IpProtocol': 'tcp',
'FromPort': 22,
'ToPort': 22,
'UserIdGroupPairs': [{'GroupId': 'sg-target-xxx'}]
}]
)
# 目标实例安全组:入站允许 ← 来自 EICE
target_sg = ec2_resource.SecurityGroup('sg-target-xxx')
target_sg.authorize_ingress(
IpPermissions=[{
'IpProtocol': 'tcp',
'FromPort': 22,
'ToPort': 22,
'UserIdGroupPairs': [{'GroupId': 'sg-eice-xxx'}]
}]
)
用安全组互相引用,不用管 IP。
第三步:配 IAM
EICE 强大的地方——IAM 精确控权:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowTunnel",
"Effect": "Allow",
"Action": "ec2-instance-connect:OpenTunnel",
"Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance-connect-endpoint/*",
"Condition": {
"NumericLessThanEquals": {
"ec2-instance-connect:maxTunnelDuration": "3600"
}
}
},
{
"Sid": "AllowSSH",
"Effect": "Allow",
"Action": "ec2-instance-connect:SendSSHPublicKey",
"Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance/*",
"Condition": {
"StringEquals": {
"ec2:osuser": "ec2-user"
}
}
},
{
"Sid": "Describe",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstanceConnectEndpoints",
"ec2:DescribeInstances"
],
"Resource": "*"
}
]
}
按环境限制(只能连 staging):
{
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Environment": "staging"
}
}
}
maxTunnelDuration:限制单次连接时长ec2:osuser:限制登录用户名ec2:ResourceTag:按标签控权
四种连接方式
方式一:控制台
EC2 控制台 → 选实例 → Connect → EC2 Instance Connect → Connect using Private IP → 选 EICE → 连接。浏览器里开终端。
方式二:CLI + SSH
ssh -i my-key.pem ec2-user@i-0123456789abcdef0 \
-o ProxyCommand='aws ec2-instance-connect open-tunnel \
--instance-id i-0123456789abcdef0'
方式三:临时公钥(60秒有效)
aws ec2-instance-connect send-ssh-public-key \
--instance-id i-0123456789abcdef0 \
--instance-os-user ec2-user \
--ssh-public-key file://~/.ssh/id_rsa.pub
方式四:SSH Config
Host staging-*
User ec2-user
IdentityFile ~/.ssh/my-key.pem
ProxyCommand aws ec2-instance-connect open-tunnel --instance-id %n
以后 ssh staging-i-0123456789abcdef0 直连。
审计
每次 EICE 连接都在 CloudTrail 自动记录:
cloudtrail = boto3.client('cloudtrail', region_name='ap-northeast-1')
response = cloudtrail.lookup_events(
LookupAttributes=[
{
'AttributeKey': 'EventName',
'AttributeValue': 'OpenTunnel'
}
],
MaxResults=10
)
for event in response['Events']:
print(f"时间: {event['EventTime']}")
print(f"用户: {event['Username']}")
print('---')
谁、什么时候、连了哪台——全自动。
EICE vs SSM Session Manager
| EICE | SSM Session Manager | |
|---|---|---|
| 协议 | SSH/RDP | 专有通道 |
| 客户端 | 标准 SSH | CLI + SSM 插件 |
| SCP/SFTP | 原生支持 | 需要额外配 |
| 端口转发 | 支持 | 支持 |
| Agent | 不需要 | 需要 SSM Agent |
| 审计 | CloudTrail | CloudTrail + S3 |
习惯 SSH 工作流用 EICE,要集中管控用 SSM。也可以两个都用。
踩坑
- 创建后等 3 分钟 —
create-complete才能连 - 安全组方向搞反 — EICE 配出站,目标配入站。很多人反着配
- Ubuntu 要装包 — Amazon Linux 自带,Ubuntu 需要
sudo apt install ec2-instance-connect - 不支持纯 IPv6 子网
- 每 VPC 最多 5 个 — 多环境共用 VPC 要规划
以上代码基于亚马逊云科技 EC2 Instance Connect Endpoint,CLI 和 Python boto3 验证通过。
EICE 免费、零维护、IAM 认证、CloudTrail 审计
文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-using-eice.html

浙公网安备 33010602011771号