基于 Amazon EC2 和 Amazon Systems Manager Session Manager 的堡垒机的设计和自动化实现

news2024/12/22 9:38:10

文章目录

  • 1. 背景
  • 2. 云上堡垒机设计
    • 2.1 安全设计
    • 2.2 高可用和弹性设计
    • 2.3 监控告警设计
    • 2.4 自动化部署设计
      • 2.4.1 堡垒机代码设计
      • 2.4.2 Session Manager 配置设计
      • 2.4.3 堡垒机 IAM 角色设计
  • 3. 部署堡垒机
    • 3.1 堡垒机部署架构图
    • 3.2 堡垒机自动化部署
  • 4. 堡垒机使用场景
    • 4.1 堡垒机使用前置条件
    • 4.2 堡垒机使用场景实操
      • 4.2.1 场景一:通过亚马逊云科技管理控制台/命令行登录堡垒机
      • 4.2.2 场景二:通过堡垒机实现远程主机端口转发
      • 4.2.3 场景三:通过本地 SSH 连接到堡垒机
  • 5. 未来架构演进
  • 6. 总结
  • 7. 参考文档

1. 背景

在很多企业的实际应用场景中,特别是金融类的客户,大部分的应用都是部署在私有子网中,如何能够让客户的开发人员和运维人员从本地的数据中心中安全的访问云上资源,堡垒机是一个很好的选择。

传统堡垒机的核心实现原理是基于 SSH 协议的安全连接,通常运用 SSH(Secure Shell)协议实现数据的加密通信。SSH 为安全身份验证和数据加密提供了可靠保障,从而确保了连接的安全性。然而,传统的自建堡垒机在其管理和运维方面面临着多种挑战:

  1. 部署与维护复杂性:自建堡垒机的部署和配置往往涉及多个复杂步骤和组件,导致管理和维护的工作量显著增加。
  2. 安全性风险:自行管理多个密钥和凭证可能会增加安全漏洞的风险。若密钥管理不当,可能导致未经授权的访问。
  3. 可用性问题:自建堡垒机常常无法实现高可用性和弹性,多用户同时访问时可能出现性能问题,影响用户体验。
  4. 扩展困难:随着用户数量和需求的增加,自建堡垒机可能难以灵活扩展,导致资源分配不均。
  5. 更新和升级:自建堡垒机需要定期进行更新和升级,以保持安全性和性能,然而这可能会导致业务中断或不稳定情况。
  6. 外网暴露:传统堡垒机需要在云上环境中部署一个有外网访问的权限的机器,增加了被攻击的风险。

与传统方式不同,基于 Amazon Systems Manager Session Manager 的堡垒机通过建立双向加密通道,连接客户端和远程节点,并采用 TLS 1.2 进行流量加密和 Sigv4 签名请求。这一方式具备显著优势:

  1. 一键式部署: 该方案极大简化了堡垒机部署流程,从而减少了部署难度和运维成本。
  2. 卓越安全性: Session Manager 提供了加密和身份验证功能,保障连接的安全性。

a. 基于 Amazon Identity and Access Management (IAM) 角色的最小权限原则,管理员能够通过集中的IAM 策略管理堡垒机的访问授权。 b. 无需管理堡垒机密钥。 c. 支持云上私有子网部署,无需部署在公有子网中,且无需打开入站端口。

  1. 高可用性: 通过弹性伸缩功能实现了堡垒机的跨可用区高可用性。
  2. 可扩展性: 基于 CPU 利用率的弹性伸缩策略能够自动调整容量,以适应不同流量访问的需求。
  3. 简化管理: Systems Manager Session Manager 是一项无需用户自行管理实例的托管服务。无需预先启动实例,也无需将实例直接暴露在公网上,从而降低了管理复杂性。
  4. 端口转发与跨平台支持:通过 Session Manager,可在本地客户端进行远程节点端口转发,并实现连接。同时,它对 Linux、Windows、Mac 等多种操作系统平台提供了跨平台访问支持。
  5. 全面的日志记录与审计:Session Manager 支持多种方式进行日志记录,涵盖登录时间、命令执行等内容,以确保会话连接活动得到完整记录。这些记录可用于审计和故障排除。
  6. 提供监控告警功能:针对堡垒机的性能指标进行监控告警,以便在性能异常时及时收到通知。

基于 Session Manager 的堡垒机为访问管理提供了高效、安全、高可用的解决方案,成为提升操作效率和保障安全性的理想选择。堡垒机作为一种安全措施,允许用户通过中间主机来访问位于私有子网中的实例或资源。它作为一座桥梁,帮助用户在安全的环境下连接到内部资源,同时减少对直接连接的需求,从而降低被攻击的风险。

对于企业的安全管理员来说,堡垒机可以增强安全性、简化网络配置、降低网络资源暴露风险、提供审计跟踪,对于开发运维人员来说,他们可以在本地环境中使用熟悉的开发、运维工具,如数据库客户端、浏览器、RDP 等去访问云上私有资源,大大提高生产效率。

本文主要阐述的是基于 Amazon Systems Manager 的 Session Manager 特性和 Amazon EC2 堡垒机的设计和实现。主要内容包括堡垒机的架构设计、安全设计、日志监控设计、高可用弹性设计以及自动化部署设计等,同时针对堡垒机在不同场景中的使用方式和脚本进行举例说明。

2. 云上堡垒机设计

2.1 安全设计

在进行云上堡垒机设计时,安全是第一个需要考虑的要求。Session Manager 是一种无需通过公网 IP 或 SSH 密钥来连接到 EC2 实例的服务,它通过 Systems Manager 的控制台或 CLI 来创建和管理安全的交互式会话。其安全设计主要考虑以下四点:

  • IAM 权限和访问控制:

Session Manager 权限: 确保只有授权的用户或角色拥有使用 Session Manager 的权限。为用户或角色分配适当的 IAM 策略,限制其对 Session Manager 的访问,一般情况下,通过与客户已有的 AD 进行集成,通过分组来控制启动 Session Manager 的权限。

多因素认证(MFA): 强制启用多因素认证,增加用户身份验证的安全性。

  • VPC 和子网安全性:

控制对 Session Manager 的网络访问:设置 VPC Endpoints 的安全组仅允许来自堡垒机及私有子网中主机的访问,并且设置 VPC Endpoints 的策略,以限制特定受信任实体才能访问。

  • 日志和审计:

监控 Session Manager 会话:启用 CloudTrail 以记录 Session Manager 的 API 调用活动,以便审计和监控用户对会话的操作;配置 Session Manager 参数,发送会话日志到 Amazon CloudWatch 日志组和 S3 存储桶,确保用户在会话中的所有操作均被记录,CloudWatch 日志组中的数据将保存 3 个月,S3 桶中的会话日志将持久存储以满足安全监管和审计需求。同时,通过脚本来实现对本地 Session Manager 插件 SSH 登录上的操作进行详细记录,并存储在指定的存储桶中。

  • 安全加密:

加密各类堡垒机相关资源:使用 Amazon Key Management Service(KMS)对 Session Manager 的会话进行加密,加密 Amazon CloudWatch 日志组及 S3 存储桶,以确保会话和日志的安全性。

2.2 高可用和弹性设计

堡垒机的高可用设计可以确保在发生故障或负载增加时,堡垒机仍然能够保持可用,并继续提供安全的访问控制。

  • 堡垒机的高可用性

使用 Auto Scaling Group(ASG): 配置堡垒机所在的 EC2 实例为一个 Auto Scaling Group。当堡垒机实例的负载增加时,ASG 会根据设置的扩展规则自动增加实例数量,保持高可用性。

设置负载均衡: 当多个堡垒机实例同时运行时,可以使用负载均衡器来分发流量,确保各个实例的负载均衡。负载均衡器还可以在某些实例出现故障时自动将流量路由到其他健康的实例,提高了整体的可用性。

  • 定时扩展和缩减

通过 Auto Scaling Group 的定时规则,控制堡垒机的启动和关机时间,从而来节约堡垒机的费用。

2.3 监控告警设计

Amazon CloudWatch 指标监控: CloudWatch 可以监控 EC2 实例和其他亚马逊云资源的性能指标。可监控实例的 CPU 使用率、内存利用率、磁盘等关键指标。并通过 Amazon SNS 服务设置报警,以便在性能异常时及时收到通知。

2.4 自动化部署设计

2.4.1 堡垒机代码设计

考虑到堡垒机的高可用设计,在其中一台机器宕机的情况下,可以自动、快速的拉起一台新的堡垒机以供使用,我们采取 EC2 launch template 的方式进行堡垒机的构建,以下是 IaC 样例代码:

通过弹性伸缩启动模版创建堡垒机的 IaC 代码样例,包含启动模版、弹性伸缩组、弹性规则等。

## 创建Bastion的launch template
resource "aws_launch_template" "bastion_template" {
  name = "bastion_template"
  block_device_mappings {
    device_name = "/dev/xvda"
    ebs {
      volume_size = 8
      encrypted   = true
    }
  }

  iam_instance_profile {
    name = aws_iam_instance_profile.bastion_ec2_profile.id
  }

  image_id                             = data.aws_ami.linux_2023_image.id
  instance_initiated_shutdown_behavior = "terminate"
  instance_type                        = var.bastion_instance_type
  
  monitoring {
    enabled = true
  }

  network_interfaces {
    associate_public_ip_address = false
    device_index                = 0
    security_groups             = [aws_security_group.bastion.id]
    subnet_id                   = element(module.vpc.private_subnets, 0)
    delete_on_termination       = true
  }

  user_data = base64encode(
    templatefile(
      "${path.module}/templates/user_data.sh.tftpl",
      {
        ##传入值到user data中所需要的变量中
      }
    )
  )
}

## 创建Bastion的弹性伸缩组
resource "aws_autoscaling_group" "bastion_asg" {
  launch_template {
    id      = aws_launch_template.bastion_template.id
    version = "$Latest"
  }
  availability_zones        = ["${var.region}a","${var.region}b"]
  name                      = "bastion_daily"
  max_size                  = 1
  min_size                  = 1
  health_check_grace_period = 300
  health_check_type         = "EC2"
  force_delete              = true
  termination_policies      = ["OldestInstance"]

  tag {
    key                 = "Name"
    value               = "bastion"
    propagate_at_launch = true
  }
}

## 创建Bastion的弹性伸缩规则-样例中使用定时规则
resource "aws_autoscaling_schedule" "bastion_scale_down" {
  scheduled_action_name  = "bastion_scale_down"
  min_size               = 0
  max_size               = 0
  desired_capacity       = 0
  recurrence             = "0 20 * * *" # 20:00 UTC +8 时间
  time_zone              = "Asia/Chongqing"
  autoscaling_group_name = aws_autoscaling_group.bastion_asg.name
}

resource "aws_autoscaling_schedule" "bastion_scale_up" {
  scheduled_action_name  = "bastion_scale_up"
  min_size               = 1
  max_size               = 1
  desired_capacity       = 1
  recurrence             = "0 8 * * *" # 8:00 UTC +8 时间
  time_zone              = "Asia/Chongqing"
  autoscaling_group_name = aws_autoscaling_group.bastion_asg.name
}

## 或者基于CPU利用率的弹性伸缩规则(样例)
resource "aws_autoscaling_group" "bation_cpu" {
  name                 = "bastion-cpu-asg"
  launch_configuration = aws_launch_configuration.bastion_template.name
  min_size             = 2
  max_size             = 4
  desired_capacity     = 2
  
  metric_trigger {
    metric_name = "CPUUtilization"
    namespace   = "AWS/EC2"
    statistic   = "Average"
    unit        = "Percent"
    threshold   = 70  # CPU利用率超过70%时扩容
    comparison_operator = "GreaterThanOrEqualToThreshold"
    dimensions = {
      AutoScalingGroupName = aws_autoscaling_group.bastion_cpu.name
    }
  }

  scaling_policy {
    name = "scale-up-policy"
    adjustment_type         = "ChangeInCapacity"
    scaling_adjustment      = 1
    cooldown               = 300  # 冷却时间300s
  }

定义堡垒机的 EC2 用户数据代码样例

在创建堡垒机时,不仅仅是单独的创建一台 EC2 的实例,还需要针对用于该 EC2 的实例进行安全加固、安装相应的工具、设置对于堡垒机的监控等功能,以下是 IaC 代码中,用于 EC2 实例初始化的用户数据(User Data)样例。

## 安全加固
yum -y update --security

## 仅允许ec2-user访问该目录
mkdir /var/log/bastion
chown ec2-user:ec2-user /var/log/bastion
chmod -R 770 /var/log/bastion
setfacl -Rdm other:0 /var/log/bastion

## Make OpenSSH execute a custom script on logins
echo -e "\\nForceCommand /usr/bin/bastion/shell" >> /etc/ssh/sshd_config
echo "AllowTcpForwarding yes" >> /etc/ssh/sshd_config
awk '!/X11Forwarding/' /etc/ssh/sshd_config > temp && mv temp /etc/ssh/sshd_config
echo "X11Forwarding no" >> /etc/ssh/sshd_config

sed  -i "s/002/022/g" /etc/profile
umask 022

## SSH命令记录脚本
mkdir /usr/bin/bastion
cat > /usr/bin/bastion/shell << 'EOF'

  # The format of log files is /var/log/bastion/YYYY-MM-DD_HH-MM-SS_user
  LOG_FILE="`date --date="today" "+%Y-%m-%d_%H-%M-%S"`_`whoami`"
  LOG_DIR="/var/log/bastion/"
  echo ""
  echo "NOTE: This SSH session will be recorded"
  echo "AUDIT KEY: $LOG_FILE"
  echo ""
  SUFFIX=`mktemp -u _XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`
  script -qf --timing=$LOG_DIR$LOG_FILE$SUFFIX.time $LOG_DIR$LOG_FILE$SUFFIX.data --command=/bin/bash
EOF

chmod a+x /usr/bin/bastion/shell
chown root:ec2-user /usr/bin/script
chmod g+s /usr/bin/script

##关闭根用户登录
systemctl stop sshd
echo "PermitRootLogin no" >> /etc/ssh/sshd_config
echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config
systemctl start sshd

## 安装CloudWatch Agent,进行系统日志收集及性能指标收集
sudo yum -y install amazon-cloudwatch-agent
sudo yum install -y collectd
cat > /opt/aws/amazon-cloudwatch-agent/etc/config.json << _EOF_
{
    "agent": {
            "metrics_collection_interval": 60,
            "run_as_user": "root"
    },
    "logs": {
            "logs_collected": {
                    "files": {
                            "collect_list": [
                                    {
                                            "file_path": "/var/log/messages",
                                            "log_group_name": "/aws/ec2/bastion/messages",
                                            "log_stream_name": "{instance_id}",
                                            "retention_in_days": 30
                                    },
                                    {
                                            "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
                                            "log_group_name": "/aws/ec2/bastion/amazon-cloudwatch-agent",
                                            "log_stream_name": "{instance_id}",
                                            "retention_in_days": 30
                                    }
                            ]
                    }
            }
    },
    "metrics": {
            "aggregation_dimensions": [
                    [
                            "InstanceId"
                    ]
            ],
            "append_dimensions": {
                    "AutoScalingGroupName": "$${aws:AutoScalingGroupName}",
                    "InstanceId": "$${aws:InstanceId}"
            },
            "metrics_collected": {
                    "collectd": {
                            "metrics_aggregation_interval": 60
                    },
                    "disk": {
                            "measurement": [
                                {
                                    "name":"used_percent",
                                    "rename":"disk_used_percent"
                                }
                            ],
                            "metrics_collection_interval": 60,
                            "resources": [
                                    "*"
                            ]
                    },
                    "mem": {
                            "measurement": [
                                {
                                    "name":"used_percent",
                                    "rename":"mem_used_percent"
                                }    
                            ],
                            "metrics_collection_interval": 60
                    },
                    "statsd": {
                            "metrics_aggregation_interval": 60,
                            "metrics_collection_interval": 10,
                            "service_address": ":8125"
                    }
            }
    }
}
_EOF_

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json -s
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start

设计和创建堡垒机安全组

根据 Session Manager 安全组的最佳实践,本方案中堡垒机的安全组设计如下:

入站规则:

协议端口备注
NANANA无入站规则

出站规则:

目标协议端口备注
VPC CIDRTCP0-65535允许访问 VPC 内部资源
VPC endpoints Security group IDHTTPS443允许访问 VPC Interface endpoints
VPC endpoints S3 prefix listHTTPS443允许访问 S3 Gateway endpoint

IaC 代码设计样例如下:

# 创建堡垒机安全组并配置规则
resource "aws_security_group" "bastion" {
  description = "Ingress should be only from Systems Session Manager"
  name        = "bastion-sg"
  vpc_id      = module.vpc.vpc_id

  tags = merge(
    {
      Name = "bastion-sg"
    }
  )
}

resource "aws_security_group_rule" "basion_egress_1" {
  security_group_id = aws_security_group.bastion.id

  description = "bastion_to_local_VPC_CIDRs"
  type        = "egress"
  from_port   = "0"
  to_port     = "65535"
  protocol    = "TCP"
  cidr_blocks = [local.vpc_cidr]
}

resource "aws_security_group_rule" "basion_egress_2" {
  security_group_id = aws_security_group.bastion.id

  description              = "bastion_egress_to_inteface_endpoints"
  type                     = "egress"
  from_port                = "443"
  to_port                  = "443"
  protocol                 = "TCP"
  source_security_group_id = aws_security_group.vpc_endpoints.id
}

resource "aws_security_group_rule" "bastion_linux_3" {
  security_group_id = aws_security_group.bastion.id

  description     = "bastion_linux_egress_to_s3_endpoint"
  type            = "egress"
  from_port       = "443"
  to_port         = "443"
  protocol        = "TCP"
  prefix_list_ids = [data.aws_vpc_endpoint.s3.prefix_list_id]
}

2.4.2 Session Manager 配置设计

在启用 Session Manager 时,需要对 Session Manager 进行相关的配置,如是否开启 Session 加密,是否将日志存储到 CloudWatch Logs 或者 S3 上,是否对日志进行加密,最大的 Session 时长等。我们通过创建 SSM Documents 的方式来进行配置,如以下 IaC 样例代码所示:

## ssm run shell json
{
    "schemaVersion": "1.0",
    "description" : "Document for SSM log configuration",
    "sessionType" : "Standard_Stream",
    "inputs": {
        "s3BucketName" : "${bucket_name}",
        "s3KeyPrefix" : "ssm",
        "s3EncryptionEnabled" : true,
        "cloudWatchLogGroupName" : "${log_group_name}",
        "cloudWatchEncryptionEnabled" : true,
        "cloudWatchStreamingEnabled": true,
        "kmsKeyId" : "${kms_id}",
        "runAsEnabled": true,
        "idleSessionTimeout": "20",
        "maxSessionDuration":"60",
    } 
}

## IaC code 创建SessionManagerRunShell documents
resource "aws_ssm_document" "ssm_shell" {
  name            = "SSM-SessionManagerRunShell"
  document_format = "JSON"
  document_type   = "Session"
  content = templatefile("${path.module}/templates/ssm_runshell.json", {
    bucket_name    = join("-", [local.bucket_name, data.aws_caller_identity.current.account_id])
    log_group_name = "/aws/sessionmanager"
    kms_id         = aws_kms_key.this.arn
    }
  )
}

2.4.3 堡垒机 IAM 角色设计

在本设计中,堡垒机的 IAM 角色主要包含以下权限:

  • AmazonSSMManagedInstanceCore
  • CloudWatchAgentServerPolicy
  • Logs 部分权限
  • SSM Messages 部分权限
  • S3 部分权限
  • KMS 部分权限

如需自定义更多 Session Manager IAM 角色的详细可访问:自定义 Session Manager IAM 角色

以下是 IaC 代码样例:

## 关联托管的IAM Policy
resource "aws_iam_role_policy_attachment" "bastion_managed" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  role       = aws_iam_role.bastion_role.name
}

resource "aws_iam_role_policy_attachment" "bastion_managed_cloudwatch" {
  policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
  role       = aws_iam_role.bastion_role.name
}

## 创建IAM 角色及关联的Policy Documents
data "aws_iam_policy_document" "bastion_assume_policy_document" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "bastion_role" {
  name               = "bastion_ec2_role"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.bastion_assume_policy_document.json

  tags = merge(
    {
      Name = "bastion_linux_ec2_role"
    },
  )
}

3. 部署堡垒机

本章将介绍如何通过基础设施即代码(Infrastructure as code)的方式一键式构建云上堡垒机,通过 Terraform 进行相应的 IaC 代码开发。

3.1 堡垒机部署架构图

根据云上堡垒机的设计,我们在堡垒机的部署中,将使用到亚马逊云上的多种服务:如Amazon CloudWatch、Key Management Service(KMS) 、 Identity and Access Management(IAM)、Systems Manager、Amazon Simply Notification Service(SNS)、Amazon Simple Storage Service(S3) 、Amazon PrivateLink、Amazon EC2 以及Amazon EC2 Auto Scaling等,以下为部署架构图:
在这里插入图片描述

图 3-1 堡垒机部署架构图

以下对部署中所使用到的主要亚马逊云相关服务的用途进行简单介绍:

  • Amazon EC2/Amazon EC2 Auto Scaling:在 EC2 上进行堡垒机的部署,并通过 AutoScaling 确保堡垒机的高可用;
  • Amazon Simple Storage Service(S3):用于存放通过 Session Manager 和 SSH 登录到堡垒机上所产生的操作日志信息;
  • Amazon VPC endpoints:用于堡垒机在没有外网访问的条件下,进行安全的访问如 Amazon CloudWatch(Logs/Monitoring)、Amazon S3、Systems Manager、Amazon KMS 等服务;
  • Amazon CloudWatch:用于存放通过控制台的 Session Manager 功能访问堡垒机的操作日志存储;
  • Amazon KMS:用于加密堡垒机部署过程中的相关服务,如 Session 加密、CloudWatch logs 加密、S3桶加密等;
  • Amazon Simply Notification Service:用于接受 Bastion Host 在 CPU/Memory/磁盘超过阈值的时候的告警信息。

需要创建的 Endpoints 列表:

序号名称类型用途
1com.amazonaws..ssmInterface与 Session Manager 进行安全交互
2com.amazonaws..ssmmessagesInterface用于 SSM Agent 到 Session Manager 的 API 操作
3com.amazonaws..ec2messagesInterface用于 SSM Agent 到 Session Manager 的 API 操作
4com.amazonaws..logsInterface与 CloudWatch 服务进行安全交互
5com.amazonaws..monitoringInterface与监控告警服务进行安全交互
6com.amazonaws..kmsInterface与 KSM 服务进行安全交互
7com.amazonaws..s3Gateway与 S3 服务进行安全交互
8eice-*.ec2-instance-connect-endpoint..amazonaws.comEC2 Instance Connect Endpoint发送 Public Key 到远端 EC2(中国区不支持该功能)

3.2 堡垒机自动化部署

当 IaC 代码开发完成后,可以将该代码集成在其他资源的 CICD pipeline 中,也可以通过 Terraform 命令,直接进行部署。

# Terraform plan 检查要部署的Bastion资源
$ terraform plan -var-file=common.tfvars  ## common.tfvars包含堡垒机所需的相关参数

# Terraform apply 执行部署
$ terraform apply -var-file=common.tfvars
等到命令执行完成后,登录到亚马逊云科技管理控制台检查相应资源是否按照预期部署完成。

4. 堡垒机使用场景

4.1 堡垒机使用前置条件

如果要在本地机器上使用堡垒机,需要满足以下条件:

  1. 确保亚马逊云上堡垒机已经部署完成,并且处于 running 状态;
  2. 确保网络联通性,确认堡垒机能访问私网环境中的 RDS 数据库、WebServer EC2 等;
  3. 确保你本地使用的 IAM 角色至少具有以下权限:

ec2:DescribeInstances
ssm:StartSession
ec2-instance-connect:SendSSHPublicKey

  1. 确保本地环境中正确安装了亚马逊云命令行工具( CLI V2) 和 Session Manager 插件

4.2 堡垒机使用场景实操

假设客户在亚马逊云上的私有子网中,部署了一个 Web 应用,包含 Web 前端和服务后端以及 RDS 数据库(以 SQL Server 为例)。该客户对于安全性的要求非常高,云上 VPC 环境中没有 Internet 访问,也没有在本地网络与云上环境之间搭建专线直连(Direct Connect)和 VPN。

但客户的开发人员和运维人员,要求提供一个安全、高效、可靠的方式从本地的客户端、应用程序、浏览器去访问云上资源,以提高开发、运维效率。下图为堡垒机实操环境的部署示意图:
在这里插入图片描述

图 4-1 堡垒机实操环境部署示意图

4.2.1 场景一:通过亚马逊云科技管理控制台/命令行登录堡垒机

在这个场景中,开发人员或者运维人员通过公司 AD 集成的账号拿到了相应的角色权限,直接登录到亚马逊云的管理控制台,然后通过 Session Manager 直接连接到堡垒机上进行操作。操作步骤如下:

  • 方式一: 直接进入到 EC2 控制台,选择堡垒机,然后点击“Connect”进行连接
  • 方式二:进入到 Systems Manager→ Session Manager→ Start Session,然后选择堡垒机进行连接

两种方式登录后,进入的界面如下图所示:

在这里插入图片描述

图 4-2 通过控制台登录堡垒机

或者在本地启动 SSM Session Manager 的插件,从本地电脑中,直接访问堡垒机:

## 通过CLI获取Bastion的Instance ID
$ InstanceID=$(aws ec2 describe-instances --no-cli-pager \
    --filters "Name=tag:Name,Values=bastion_linux" \
    --query 'Reservations[0].Instances[0].InstanceId' --output text) 

## 启动本地会话
$ aws ssm start-session --target $InstanceID

在这里插入图片描述

图 4-3 通过 CLI 从本地机器登录堡垒机

通过控制台或者本地 CLI 进入到堡垒机后,所有的操作都会被记录到 Amazon CloudWatch Log Group “/aws/sessionmanager”,日志保留时间为 3 个月,并且还会上传到 S3 桶(S3 桶名:bastion-audit-log-bucket-<AccountID>,路径为:ssm/)中做持久化存储。

在这里插入图片描述

图 4-4 日志组中存储的堡垒机操作审计日志

在这里插入图片描述

图 4-5 S3 中存储的堡垒机操作审计日志

4.2.2 场景二:通过堡垒机实现远程主机端口转发

在该场景中,开发人员或者运维人员通过公司 AD 集成的账号拿到了相应的角色权限,然后在本地启动 Session Manager 插件 来进行远程主机的端口转发,通过这种方式,开发人员或运维人员可以方便的使用本地客户端进行操作云上资源,如访问云上数据库和访问 WebServer 等。以下命令是启动如何在本地机器上实现远程主机端口转发:

## 通过CLI获取Bastion的Instance ID
$ InstanceID=$(aws ec2 describe-instances --no-cli-pager \
    --filters "Name=tag:Name,Values=bastion_linux" \
    --query 'Reservations[0].Instances[0].InstanceId' --output text) 

## 启动远程主机端口转发,请替换掉命令中的<>为实际的远程端口、本地端口以及远程主机IP或者DNS
$ aws ssm start-session --target $InstanceID \
      --document-name AWS-StartPortForwardingSessionToRemoteHost \
      --parameters '{"portNumber":["<Remote_Host_Port_Number>"],"localPortNumber":["<LocalPortNumber>"],"host":["<Remote_Host_DNS/IP>"]}'

(1) 远端数据库端口转发

以在本地访问云上 SQLServer 数据库为例子,端口号为 1433,本地端口号为 12345,远程主机 DNS 为:“bastion-test-db.xxxxx.<REGION>.rds.amazonaws.com”,启动后,如下图所示:

在这里插入图片描述

图 4-6 本地启动远程主机端口转发(DNS)

打开本地 SQLServer 客户端,输入 RDS Server 端地址和端口:“127.0.0.1,12345”,并输入登录数据库的账号和密码,如下图所示:

在这里插入图片描述

图 4-7 配置本地数据库客户端连接

点击“Connect”,即可访问云上 RDS 数据库并进行操作:

在这里插入图片描述

图 4-8 本地数据库客户端连接 RDS 成功

(2) 远端服务器端口转发

以本地通过浏览器访问 Web Server 为例,端口号为 80,本地端口号为 8080,远程主机 IP 为:“10.99.3.132”,启动后,如下图所示:

9

图 4-9 本地启动远程端口转发(IP 地址)

通过本地浏览器访问 127.0.0.1:8080,可看到能够成功访问到位于私有网络中的 WebServer:

在这里插入图片描述

图 4-10 本地浏览器成功访问 WebServer

4.2.3 场景三:通过本地 SSH 连接到堡垒机

在开发人员或者运维人员在实际工作中,偶尔会需要通过 SSH 连接到堡垒机或者远端的主机上进行调试或者运维,并上传相应的文件到堡垒机上。

一般情况下,运维人员需要拿到 EC2 的密钥并确保安全组中包含有 22 端口及客户端的 IP 地址的入站规则,然后才能连接到云上服务器上,这种情况不仅增加了密钥管理的难度,同时对于只存在私有网络中的服务器且本地数据中心和云上环境没有互联的场景是一个很大的挑战。

通过 ec2-instance-connect 服务特性并结合 Session Manager 可以方便的满足客户通过 SSH 访问云上 EC2 的情景。

## Step 1: 通过 CLI 获取 Bastion 的 Instance ID
$ InstanceID=$(aws ec2 describe-instances --no-cli-pager \
    --filters "Name=tag:Name,Values=bastion_linux" \
    --query 'Reservations[0].Instances[0].InstanceId' --output text)
 
## Step 2: 生成临时 ssh key
$ echo -ne "Generating SSH key pair................\r"
$ echo -e 'y\n' | ssh-keygen -t rsa -f temp-key -N '' > /dev/null 2>&1

## Step 3: 发送生成 SSH public key 到堡垒机中,根据实际情况替换掉命令行中的变量
$ echo -ne "Pushing public key to instance.........\r"
$ aws ec2-instance-connect send-ssh-public-key --region $AWS_DEFAULT_REGION \
    --instance-id $instanceId --availability-zone <az> \
    --instance-os-user <ssm_user> \
    --ssh-public-key file://temp-key.pub > /dev/null 2>&1

## Step 4: 修改 ~/.ssh/config 配置(仅需要一次配置)
Host test-ssh-bastion
     IdentityFile ~/test/temp-key
     StrictHostKeyChecking no
     UserKnownHostsFile /dev/null
     LogLevel QUIET
     User ec2-user
     ProxyCommand sh -c "aws ssm start-session --target $(aws ec2 describe-instances --no-cli-pager \
        --filters 'Name=tag:Name,Values=bastion_linux' \
        --query 'Reservations[0].Instances[0].InstanceId' --output text) \
     --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --region us-east-1"

## Step 5: 修改完成后,通过 ssh 就可以连接到堡垒机中,如下图所示
$ ssh test-ssh-bastion

将以上代码中的 Step1 到 Step3 编写成一个脚本,在每次执行 ssh 之前,先运行该脚本,确保新生成的 SSH Key 有效(通过 send-ssh-public-key 上传到 EC2 上的 Key 有效期只有 60s)。

在这里插入图片描述

图 4-11 启动本地 SSH 访问堡垒机

注意: 如果使用动态生成 SSH Key 的方式,需要先创建“EC2 Instance Connect Endpoint”,同时确保本地电脑上使用的 IAM 角色包含有“ec2-instance-connect:SendSSHPublicKey”的权限。另外,亚马逊云科技中国区暂时不支持该 Endpoint 类型的创建。

通过本地 Session Manager 插件 SSH 进入到堡垒机后,所有的操作都会上传到 S3 桶(S3 桶名:bastion-audit-log-bucket-<AccountID>,路径为:logs/)中做持久化存储。

在这里插入图片描述

图 4-12 S3 中存储的在本地通过 SSH 操作堡垒机的审计日志

除通过 SSH 登录到堡垒机外,SSM 还可以支持 SSH Socks Proxy,如下图在浏览器中设置 Proxy(以 Firefox 为例):

在这里插入图片描述

图 4-13 Socks Proxy 配置

使用以下代码启动 SSH Socks Proxy:

ssh -f -N -p 2200 -i temp -o "IdentitiesOnly=yes" -D 1080 ec2-user@localhost

启动后,就可以通过 Socks Proxy 访问内网的 WebServer。

5. 未来架构演进

本方案中堡垒机是根据最常用的功能,如端口转发、SSH 访问来设计的,但在一些特定的场景中,还需要设计更多复杂的堡垒机方案,如:Windows 类型的堡垒机支持、如何使用 IAM 角色对堡垒机权限进行更精细化的管理等,这些都是未来本方案演进和增强的一个方向。

目前我们方案中,创建的堡垒机类型只有一种,任何拥有启动 Session Manager 的 IAM 用户/角色都可以去访问它并进行操作,但在一些场景下,客户需要对于不同的角色使用不同的堡垒机:如角色 A 仅可以访问堡垒机 A,并通过该堡垒机上赋予的 IAM 权限进行相应的操作;角色 B 仅可以访问堡垒机 B,通过该堡垒机上赋予的 IAM 权限进行相应的操作。不同的用户角色和客户自有的 AD 域控进行集成,可以灵活的进行更精细化的权限控制。

6. 总结

本文主要介绍了基于 Amazon Systems Manager Session Manager 的堡垒机的设计和实现,并通过 IaC 自动化方式构建和部署云上堡垒机,同时基于堡垒机的使用场景进行了举例,介绍了不同场景下堡垒机的使用方法和步骤。该堡垒机方案已经集成到 Cloud Foundations 快速启动包服务中,为企业用户提供更便捷的部署方式。

7. 参考文档

  • Amazon Systems Manager Session Manager 官方文档
  • Amazon 官方博客:New – Port Forwarding Using AWS System Manager Session Manager

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1168356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[python 刷题] 2866 Beautiful Towers II

[python 刷题] 2866 Beautiful Towers II 题目如下&#xff1a; You are given a 0-indexed array maxHeights of n integers. You are tasked with building n towers in the coordinate line. The ith tower is built at coordinate i and has a height of heights[i]. A co…

Wi-Fi还可以做什么?柯南解释IOT应用

大会报告&#xff1a;无线人工智能技术正在改变世界 Wi-Fi还可以做什么&#xff1f;随着带宽的提升&#xff0c;无线终端可以识别出更多的多径&#xff0c;每条多径都可以视作一个虚拟传感器&#xff0c;以感知周边环境。基于此&#xff0c;越来越多的无线感知产品应运而生。20…

Leetcode1122. 数组的相对排序

Every day a Leetcode 题目来源&#xff1a;1122. 数组的相对排序 解法1&#xff1a;哈希 用集合 set 存储 arr2 中的元素。 遍历数组 arr1 &#xff0c;设当前元素为 num&#xff1a; 如果 num 在 set 中出现&#xff0c;用哈希表 hash 记录 num 和它出现的次数。否则&a…

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的解决方案&#xff09; GNSS配置如下&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;包括BUG复…

大数据毕业设计选题推荐-热门旅游景点数据分析-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

第二章 Python字符串处理

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

『亚马逊云科技产品测评』活动征文|搭建基础运维环境

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 目录 1、什么是容器化部署 2、连接到控制台 3、安装docker 3.1 更新…

学习Opencv(蝴蝶书/C++)代码——1.macOS下安装OpenCV4.8.0和QT5.15(C++)

文章目录 1.前置条件-cmake和c2. opencv2.1 opencv安装2.2 opencv测试2.2.1 基本测试2.2.2 opencv里的自带测试图像 2.3 报错2.3.1 MacOSX10.15.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture2.2.2 电脑上没有安装java(Unable to locate a Java Runtime…

TSINGSEE青犀智能分析网关人员徘徊AI算法应用场景概述

我们的AI边缘计算网关硬件 —— 智能分析网关目前有5个版本&#xff1a;V1、V2、V3、V4、V5&#xff0c;每个版本都能实现对监控视频的智能识别和分析&#xff0c;支持抓拍、记录、告警等&#xff0c;每个版本在算法模型及性能配置上略有不同。硬件可实现的AI检测包括&#xff…

HCIA数据通信——路由协议

数据通信——网络层&#xff08;OSPF基础特性&#xff09;_咕噜跳的博客-CSDN博客 数据通信——网络层&#xff08;RIP与BGP&#xff09;_咕噜跳的博客-CSDN博客 上述是之前写的理论知识部分&#xff0c;懒得在实验中再次提及了。这次做RIP协议以及OSPF协议。不过RIP协议不常用…

哪里能找到可以学习的前端实战项目?

前言 下面是我整理的一些关于GitHub上的前端相关的项目&#xff0c;希望对你有所帮助&#xff0c;整理不易&#xff0c;可以的话不要吝啬你的点赞喜欢收藏哈~ 废话少说&#xff0c;我们直接进入正题——> 实用工具向 1.Echarts Star&#xff1a;55.6k Echarts提供了大量…

【C++】异常【完整版】

目录 1.C语言传统的处理错误的方式 2. C异常概念 3. 异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3异常安全 3.4 异常规范 4.自定义异常体系 5.C标准库的异常体系 6.异常的优缺点 1.C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序…

什么是OTP认证?OTP认证服务器有哪些应用场景?

OTP是一次性密码&#xff0c;即只能使用一次的密码。它基于专门的算法&#xff0c;每隔60秒生成一个不可预测的随机数字组合。这种密码的有效期仅在一次会话或交易过程中&#xff0c;因此不容易受到重放攻击。在计算器系统或其他数字设备上&#xff0c;OTP是一种只能使用一次的…

重定向-缓冲区

1.重定向 文件描述符对应的分配规则是什么? 尝试用这个代码 关闭0,1&#xff0c;2文件描述符&#xff0c;看看有什么现象&#xff1f;关闭哪个&#xff0c;你打开的文件fd应该就是哪个 结论&#xff1a; 从0下标开始&#xff0c;寻找最小的没有没使用的数组位置&#xff0c;它…

【算法 | 哈希表 No.1】leetcode 217. 存在重复元素

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

网站如何保护自身安全

随着网络威胁的不断升级&#xff0c;保护网站免受攻击变得尤为重要。网站被攻击不仅可能导致数据泄露和服务中断&#xff0c;还可能损害声誉和客户信任。本文将从时代因素、人为因素和环境因素的角度&#xff0c;探讨如何解决网站被攻击的问题&#xff0c;提供一些简单而实用的…

关于docker网络实践中遇到的问题

1.禁用docker自动修改iptables规则 查看docker.service文件/usr/lib/systemd/system/docker.service 默认在宿主机部署容器&#xff0c;映射了端口的话&#xff0c;docker能自己修改iptables规则&#xff0c;把这些端口暴露到公网。 如果要求这些端口不能暴露到公网&#xf…

启用NTP服务解决Linux系统时间与北京时间不同步问题

一、背景 1、服务器的Linux版本为Linux version 4.18.0-348.7.1.el8_5.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)) #1 SMP Wed Dec 22 13:25:12 UTC 2021 2、NTP即Network Time Protocol&#xff08;网络时间协议&am…

路由器基础(七):NAT原理与配置

一、NAT 配置 华为路由器配置NAT 的方式有很多种&#xff0c;考试中可能考到的基本配置方 式主要有EasyIP和通过NAT地址池的方式。图22-7-1是一个典型的通过EasyIP进行NAT的示意图&#xff0c;其中Router出接口GE0/0/1的IP地址为200.100.1.2/24,接口E0/0/1的IP地址为192.168.0.…

VR博物馆:让博物馆传播转化为品牌影响力

随着VR技术的不断进步&#xff0c;VR全景技术已经成为了文化展示和传播的一项重要工具&#xff0c;相较于传统视频、图文等展现方式&#xff0c;VR全景体验更加直观、便捷&#xff0c;其中蕴涵的信息量也更加丰富&#xff0c;这也为公众了解博物馆和历史文化带来了更为深刻的体…