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

news2024/10/6 6:51:56

25885190b7f0af6e1d0d3b2fd8984ebb.gif

01

背景

在很多企业的实际应用场景中,特别是金融类的客户,大部分的应用都是部署在私有子网中。为了能够让客户的开发人员和运维人员从本地的数据中心中安全的访问云上资源,堡垒机是一个很好的选择。传统堡垒机的核心实现原理是基于 SSH 协议的安全连接,通常运用 SSH (Secure Shell) 协议实现数据的加密通信。SSH 为安全身份验证和数据加密提供了可靠保障,从而确保了连接的安全性。然而,传统的自建堡垒机在其管理和运维方面面临着多种挑战:

  1. 部署与维护复杂性:自建堡垒机的部署和配置往往涉及多个复杂步骤和组件,导致管理和维护的工作量显著增加。

  2. 安全性风险:自行管理多个密钥和凭证可能会增加安全漏洞的风险。若密钥管理不当,可能导致未经授权的访问。

  3. 可用性问题:自建堡垒机常常无法实现高可用性和弹性,多用户同时访问时可能出现性能问题,影响用户体验。

  4. 扩展困难:随着用户数量和需求的增加,自建堡垒机可能难以灵活扩展,导致资源分配不均。

  5. 更新和升级:自建堡垒机需要定期进行更新和升级,以保持安全性和性能,然而这可能会导致业务中断或不稳定情况。

  6. 外网暴露:传统堡垒机需要在云上环境中部署一个有外网访问的权限的机器,增加了被攻击的风险。

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

1. 一键式部署: 该方案极大简化了堡垒机部署流程,从而减少了部署难度和运维成本。

2. 卓越安全性: Session Manager 提供了加密和身份验证功能,保障连接的安全性。

  1. 基于 Amazon Identity and Access Management (IAM) 角色的最小权限原则,管理员能够通过集中的 IAM 策略管理堡垒机的访问授权。

  2. 无需管理堡垒机密钥。

  3. 支持云上私有子网部署,无需部署在公有子网中,且无需打开入站端口。

3、高可用性: 通过弹性伸缩功能实现了堡垒机的跨可用区高可用性。

4、可扩展性: 基于 CPU 利用率的弹性伸缩策略能够自动调整容量,以适应不同流量访问的需求。

5、简化管理:Systems Manager Session Manager 是一项无需用户自行管理实例的托管服务。无需预先启动实例,也无需将实例直接暴露在公网上,从而降低了管理复杂性。

6、端口转发与跨平台支持:通过 Session Manager,可在本地客户端进行远程节点端口转发,并实现连接。同时,它对 Linux、Windows、Mac 等多种操作系统平台提供了跨平台访问支持。

7、全面的日志记录与审计:Session Manager 支持多种方式进行日志记录,涵盖登录时间、命令执行等内容,以确保会话连接活动得到完整记录。这些记录可用于审计和故障排除。

8、提供监控告警功能:针对堡垒机的性能指标进行监控告警,以便在性能异常时及时收到通知。

基于 Session Manager 的堡垒机为访问管理提供了高效、安全、高可用的解决方案,成为提升操作效率和保障安全性的理想选择。堡垒机作为一种安全措施,允许用户通过中间主机来访问位于私有子网中的实例或资源。它作为一座桥梁,帮助用户在安全的环境下连接到内部资源,同时减少对直接连接的需求,从而降低被攻击的风险。对于企业的安全管理员来说,堡垒机可以增强安全性、简化网络配置、降低网络资源暴露风险、提供审计跟踪,对于开发运维人员来说,他们可以在本地环境中使用熟悉的开发、运维工具,如数据库客户端、浏览器、RDP 等去访问云上私有资源,大大提高生产效率。

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

02

云上堡垒机设计

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 样例代码:

1、通过弹性伸缩启动模版创建堡垒机的 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
  }

左滑查看更多

2、定义堡垒机的 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

左滑查看更多

3、设计和创建堡垒机安全组

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

入站规则:

487f2a5c9e10d7e5ac5e5d0911cf9975.png

出站规则:

b575733bbbaa27f4b8456ea051cbb0a8.png

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 角色

  • 自定义 Session Manager IAM 角色:

    https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html

以下是 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"
    },
  )
}

左滑查看更多

03

部署堡垒机

本章将介绍如何通过基础设施即代码(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 等,以下为部署架构图:

d5635ee4e7f3f7209b33b14d7f3383d4.png

图 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 列表:

e7e666f95a387a2832dbbc2549c88259.png

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

左滑查看更多

等到命令执行完成后,登录到亚马逊云科技管理控制台检查相应资源是否按照预期部署完成。

04

堡垒机使用场景

4.1  堡垒机使用前置条件

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

1、确保亚马逊云上堡垒机已经部署完成,并且处于 running 状态;

2、确保网络联通性,确认堡垒机能访问私网环境中的 RDS 数据库、WebServer EC2 等;

3、确保你本地使用的 IAM 角色至少具有以下权限:

  • a. ec2:DescribeInstances

  • b. ssm:StartSession

  • c. ec2-instance-connect:SendSSHPublicKey

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

4.2  堡垒机使用场景实操

假设客户在亚马逊云上的私有子网中,部署了一个 Web 应用,包含 Web 前端和服务后端以及 RDS 数据库(以 SQL Server 为例)。该客户对于安全性的要求非常高,云上 VPC 环境中没有 Internet 访问,也没有在本地网络与云上环境之间搭建专线直连(Direct Connect)和 VPN。但客户的开发人员和运维人员,要求提供一个安全、高效、可靠的方式从本地的客户端、应用程序、浏览器去访问云上资源,以提高开发、运维效率。下图为堡垒机实操环境的部署示意图:

dd946b7a75267c8cf102ba95492aa88c.png

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

4.2.1  场景一:

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

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

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

  • 方式二:进入到 Systems Manager→ Session Manager→ Start Session,然后选择堡垒机进行连接

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

a562b69b6f340dee2f71fc465ec75d8c.png

图 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

左滑查看更多

5bd1886de0ae99926e6a50b3602c0ee3.png

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

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

b170aa0ac91a2add0ae10b70ca69160f.png

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

3bf3e0895a075b002e8fcdfd20227e51.png

图 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..rds.amazonaws.com”,启动后,如下图所示:

f42c89bfa109f5a75765d2d2a19ea7b2.png

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

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

52f155f6e5a9c9dbd05a513d31d0e228.png

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

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

07e1506dda7e59e33fe673a6c87d6ea4.png

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

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

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

af0765cefe06cc6f3991ad98c66bbede.png

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

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

598d3c110df6229b8eb6deab9a4d17a3.png

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

4.2.2  场景三:

通过本地 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)。

b5d6ab42a269d082b3ce3c4409fc1477.png

图 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/)中做持久化存储。

b6918ccb69ddef9180d2786f59b33fcf.png

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

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

4ab6d612322d28ebff32fd4cbddcf3c6.jpeg

图 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。

05

未来架构演进

本方案中堡垒机是根据最常用的功能,如端口转发、SSH 访问来设计的,但在一些特定的场景中,还需要设计更多复杂的堡垒机方案,如:Windows 类型的堡垒机支持、如何使用 IAM 角色对堡垒机权限进行更精细化的管理等,这些都是未来本方案演进和增强的一个方向。目前我们方案中,创建的堡垒机类型只有一种,任何拥有启动 Session Manager 的 IAM 用户/角色都可以去访问它并进行操作,但在一些场景下,客户需要对于不同的角色使用不同的堡垒机:如角色 A 仅可以访问堡垒机 A,并通过该堡垒机上赋予的 IAM 权限进行相应的操作;角色 B 仅可以访问堡垒机 B,通过该堡垒机上赋予的 IAM 权限进行相应的操作。不同的用户角色和客户自有的 AD 域控进行集成,可以灵活的进行更精细化的权限控制。

06

总结

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

07

参考文档

  • Amazon Systems Manager Session Manager 官方文档:

    https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html

  • Amazon 官方博客:New – Port Forwarding Using Amazon System Manager Session Manager

    https://aws.amazon.com/cn/blogs/aws/new-port-forwarding-using-aws-system-manager-sessions-manager/

本篇作者

a4c1faa07164f9654dfb407fb12d4528.jpeg

叶文军

亚马逊云科技专业服务团队云架构咨询顾问。负责企业客户的云架构设计、迁移、安全和优化,云上自动化运维,容器等相关咨询服务。在云原生技术、DevOps 及私有云部署运维等方面有着丰富的经验。

4cb887c4c46607da21f3050521f8cfe9.jpeg

袁文俊

亚马逊云科技专业服务部顾问。曾在亚马逊美国西雅图总部工作多年,就职于 Amazon Relational Database Service (RDS) 关系型数据库服务开发团队。拥有丰富的软件开发及云上运维经验。现负责业务持续性及可扩展性运行、企业应用及数据库上云和迁移、云上灾难恢复管理、云上良好架构框架等架构咨询、方案设计及项目实施工作。

e126f72a3497cbdbe8ef98a751284c16.jpeg

刘育新

Amazon ProServe 团队高级顾问,长期从事企业客户入云解决方案的制定和项目的实施工作。

6a36b6c527199963ec19d46f5e8a1059.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

3f24cf704e0876daba28134926e90d6a.gif

听说,点完下面4个按钮

就不会碰到bug了!

6b641295d777711a8faabe170b9d6265.gif

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

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

相关文章

模板——“C++”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容是C中的模板初阶的内容&#xff0c;下面&#xff0c;让我们进入C模板的世界吧&#xff01;&#xff01;&#xff01; 1. 泛型编程 2. 函数模板 3. 类模板 泛型编程 如何实现一个通用的交换函数呢&#xff1f;…

汽车ECU的虚拟化技术初探(二)

目录 1.概述 2.U2A虚拟化方案概述 3.U2A的虚拟化功能概述 4.虚拟化辅助功能的使能 5.留坑 1.概述 在汽车ECU的虚拟化技术初探(一)-CSDN博客里&#xff0c;我们聊到虚拟化技术比较关键的就是vECU的虚拟地址翻译问题&#xff0c;例如Cortex-A77就使用MMU来进行虚实地址的转换…

阿里云ACK(Serverless)安装APISIX网关及APISIX Ingress Controller

在k8s上安装apisix全家&#xff0c;通过helm安装很简单&#xff0c;但是会遇到一些问题。 安装 首先登录阿里云控制台&#xff0c;在ACK集群详情页&#xff0c;进入CloudShell&#xff0c;执行下面helm命令安装apisix、apisix-ectd、apisix-dashboard和apisix-ingress-contro…

【Linux】Kali(WSL)基本操作与网络安全入门

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍WSL安装Kali及基本操作。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路…

从0到0.01入门React | 004.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

upload-labs关卡7(基于黑名单的空格绕过)通关思路

文章目录 前言一、回顾上一关知识点二、靶场第七关通关思路1、看源代码2、空格绕过3、检查文件是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚未授权的网站做渗透测试…

【GEE】10、使用 Google 地球引擎创建图形用户界面【GUI开发】

1简介 在本模块中&#xff0c;我们将讨论以下概念&#xff1a; 用于生成图形用户界面的 GEE 对象。如何开发具有交互元素的面板。如何将地理处理元素连接到交互式元素。 2背景 在过去的十个单元中&#xff0c;我们展示了 Google Earth Engine 可以成为一种重要且高效的资源&a…

数字双向码、密勒码、传号反转(CMI)码、AMI、HDB3的编码规则和功率谱解析+眼图

数字双向码、密勒码、传号反转&#xff08;CMI&#xff09;码、AMI、HDB3的编码规则和功率谱解析眼图 本文主要涉及数字双向码、密勒码、传号反转&#xff08;CMI&#xff09;码、AMI、HDB3的编码规则,优缺点和功率谱解析以及眼图的分析。关于简单二元码大家可以参考简单二元码…

Python---元组的相关操作方法

由于元组中的数据不允许直接修改&#xff0c;所以其操作方法大部分为查询方法。 编号函数作用1元组[索引]根据索引下标查找元素2index()查找某个数据&#xff0c;如果数据存在返回对应的下标&#xff0c;否则报错&#xff0c;语法和列表、字符串的index方法相同3count()统计某…

第十七章jQuery中的事件与动画

一。常用事件&#xff1a; 1.鼠标事件&#xff1a; mouseover()&#xff1a;在鼠标进入内容后一直显示事件 mouseout()&#xff1a;在鼠标离开内容后一直显示事件 mouseenter()&#xff1a;在进入刹那间显示事件 mouseleave()&#xff1a;在退出刹那间显示事件 案例&#xf…

v-bind和v-model

目录 前言 v-bind 作用 语法格式 编译原理 简写 v-model 作用 使用方法 v-bind和v-model的区别和联系 前言 本文我们来了解一下模板语法之指令语法中的v-bind和v-model v-bind 作用 v-bind可以让html标签的某个属性的值产生动态的效果 语法格式 <html标签 v-bin…

终端安全/SOC安全/汽车信息安全大课来袭-共计204节课

在近两年的时间里&#xff0c;我投入了大量的心血和精力&#xff0c;不仅创作了数千篇精美的图片&#xff0c;还编写了超过1000篇文章&#xff0c;以及数百篇内容丰富的PPT。经过这番努力我终于成功地构建出两套系统化的学习课程&#xff0c;它们分别是“Trustzone/TEE/安全从入…

【Android】Android apk 逆向编译

链接&#xff1a;https://pan.baidu.com/s/14r5s9EJwQgeLK5cCb1Gq1Q 提取码&#xff1a;qdqt 解压jadx 在 lib 文件内找到 jadx-gui-1.4.7.jar 打开cmd 执行 &#xff1a;java -jar jadx-gui-1.4.7.jar示列&#xff1a;

U-Mail邮件中继,让海外邮件沟通更顺畅

在海外&#xff0c;电子邮件是人们主要的通信工具&#xff0c;尤其是商务往来沟通&#xff0c;企业邮箱是标配。这主要是因为西方国家互联网发展较早&#xff0c;在互联网早期&#xff0c;电子邮件技术较为成熟&#xff0c;大家都用电子邮件交流&#xff0c;于是这成了一种潮流…

【debug】解决Kali虚拟机开机黑屏,左上角光标一直闪动无法开机问题

做网络攻防实验时&#xff0c;突然Kali无法打开&#xff0c;遇到这个问题。。。。。。 遇到的问题 突然kali虚拟机变成如下黑屏&#xff0c;无法开机&#xff0c;左上角光标闪动&#xff0c;重启无效。 解决办法 在上图界面&#xff0c;按Ctrl F3&#xff08;不同电脑快捷键…

设计模式-工厂方法

工厂方法是一种创建型设计模式&#xff0c;其在父类中提供一个创建对象的方法&#xff0c;允许子类决定实例化对象的类型。 问题 假设你开设了一个汽车工厂。创业初期工厂只能生产宝马这一款车&#xff0c;因此大部分代码都位于名为宝马的类中。 工厂效益非常好&#xff0c;为…

Spring Cloud学习(七)【Docker 容器】

文章目录 初识 DockerDocker 介绍Docker与虚拟机Docker架构安装 Docker Docker 基本操作镜像相关命令容器相关命令数据卷 Dockerfile 自定义镜像镜像结构Dockerfile DockerComposeDockerCompose介绍安装DockerCompose Docker镜像仓库常见镜像仓库服务私有镜像仓库 初识 Docker …

CSS花边001:无衬线字体和有衬线字体

网站中我们看到过很多字体&#xff0c;样子各有千秋。通常针对结构&#xff0c;区分为有衬字体&#xff08;serif&#xff09; 和无衬字体&#xff08;sans-serif&#xff09;。今天我们聊一下这个话题。 什么是有衬字体&#xff0c;什么是无衬字体&#xff1f; 衬线字体&…

【c++随笔12】继承

【c随笔12】继承 一、继承1、继承的概念2、3种继承方式3、父类和子类对象赋值转换4、继承中的作用域——隐藏5、继承与友元6、继承与静态成员 二、继承和子类默认成员函数1、子类构造函数 二、子类拷贝构造函数3、子类的赋值重载4、子类析构函数 三、单继承、多继承、菱形继承1…

[ASP]数据库编辑与管理V1.0

本地测试&#xff1a;需要运行 ASP专业调试工具&#xff08;自己搜索下载&#xff09; 默认登陆口令&#xff1a;admin 修改口令&#xff1a;打开index.asp找到第3行把admin"admin"改成其他&#xff0c;如admin"abc123" 程序功能齐全&#xff0c;代码精简…