首页 > 其他分享 >停止在 AWS 中使用 SSH!原因如下!DevSecOps 视角

停止在 AWS 中使用 SSH!原因如下!DevSecOps 视角

时间:2024-08-29 15:50:19浏览次数:14  
标签:管理器 DevSecOps AWS aws SSH bucket 日志 EC2

我们要解决什么问题?欢迎来到雲闪世界
我见过多少次安全组从 10.0.0.0/8 或更糟的 0.0.0.0/0 开放端口 22?太多次了!但为什么,为什么在有更好的替代方案的情况下,我们在 2024 年仍在使用 SSH?作为一名安全专家,我经常被要求说服人们“一种更好的工作方式”。我经常失败。人们喜欢快速简便的工作方式 (我不怪他们!)。但在安全事故数量不断上升的时代,我们必须找到一种更好的工作方式,一种在设计上就内置安全性的方式。
此外,如果您在 YouTube 上观看技术视频,您经常会看到面向公众的 EC2 实例,SSH 向“我的 IP”开放。我不会责怪内容创建者这样做,毕竟,他们只是想向人们展示如何执行特定任务。然而,许多开发人员认为这是唯一的工作方式,因此当安全专家告诉他们需要更改连接到 EC2 的方式时,他们通常会遭到抵制。
那么,如何在没有密钥对、没有公共 IP 地址、没有配置不当的安全组的情况下提供对 EC2 实例的安全访问,同时受益于增强的日志记录和安全性?!
答案是系统管理器和会话管理器。


什么是系统管理器 (SSM)?

我们要解决什么问题?
我见过多少次安全组从 10.0.0.0/8 或更糟的 0.0.0.0/0 开放端口 22?太多次了!但为什么,为什么在有更好的替代方案的情况下,我们在 2024 年仍在使用 SSH?作为一名安全专家,我经常被要求说服人们“一种更好的工作方式”。我经常失败。人们喜欢快速简便的工作方式 (我不怪他们!)。但在安全事故数量不断上升的时代,我们必须找到一种更好的工作方式,一种在设计上就内置安全性的方式。
此外,如果您在 YouTube 上观看技术视频,您经常会看到面向公众的 EC2 实例,SSH 向“我的 IP”开放。我不会责怪内容创建者这样做,毕竟,他们只是想向人们展示如何执行特定任务。然而,许多开发人员认为这是唯一的工作方式,因此当安全专家告诉他们需要更改连接到 EC2 的方式时,他们通常会遭到抵制。
那么,如何在没有密钥对、没有公共 IP 地址、没有配置不当的安全组的情况下提供对 EC2 实例的安全访问,同时受益于增强的日志记录和安全性?!
答案是系统管理器和会话管理器。

什么是系统管理器 (SSM)?

AWS Systems Manager 是您的 AWS 应用程序和资源的运营中心,也是混合和多云环境的安全端到端管理解决方案,可实现大规模安全运营。
Systems Manager 提供的一些服务包括:

  • 补丁管理
  • 软件分发
  • EC2 清单
  • 配置管理
  • 会话管理器

什么是会话管理器?
您可以使用交互式一键式基于浏览器的 shell 或 AWS 命令​​行界面 (AWS CLI) 连接到 AWS EC2 实例。会话管理器提供安全且可审计的节点管理,无需打开入站端口、维护堡垒主机或管理 SSH 密钥。会话管理器还允许您遵守公司政策,这些政策要求对托管节点进行受控访问、严格的安全实践以及包含节点访问详细信息的完全可审计日志,同时为最终用户提供对托管节点的简单一键式跨平台访问。


为什么使用会话管理器而不是 SSH?

  • 使用 IAM 策略对托管节点进行集中访问控制
  • 安全组中无需开放入站端口 22 或 3389 (Windows)
  • 无需管理堡垒主机或 SSH 密钥
  • 记录和审核会话活动。

日志记录功能分为两个级别,首先,所有会话都记录到 AWS CloudTrail,使活动审计与其他 AWS 服务和事件类型保持一致。这确保了会话处于活动状态时执行的活动不可否认。
其次,按键操作可以捕获到集中式日志记录设施,例如 CloudWatch 或 Amazon S3。这意味着,如果您有特定的监管要求,需要通过终端记录在 EC2 实例上执行的所有操作,您可以这样做。这对安全运营团队在进行事件调查时也非常有益,因为他们可以根据已知的可疑活动(例如特权升级)建立警报。

解决方案架构概述
为多帐户环境进行设计并不简单,尤其是当您涉及加密密钥时,但是可以通过在帐户配置过程中自动执行下面概述的配置来减轻复杂性。下面的设计应该有助于阐明我们如何解决 SSH 挑战,而不会给开发人员或平台工程师增加障碍。

多账户环境中会话管理器日志的高级设计多账户环境中会话管理器日志的高级设计

日志账户(S3 和 CloudWatch)
日志账户位于安全组织单位 (OU) 中。S3 存储桶和 CloudWatch 日志组在此账户中配置,并使用 KMS 密钥加密。
VPC 端点 (VPCe)
在 Workloads OU 中的每个 AWS 账户中,配置 VPC 端点以将流量保持在 AWS 云内部。这样就可以通过 VPCe 访问 S3 存储桶和 CloudWatch Log 组,而无需传出到 Internet。
EC2 实例
EC2 实例配置了自定义实例配置文件,具有将日志发送到 CloudWatch 和 S3 的权限,确保它们有权使用 KMS 密钥进行加密。此外,AWS 还提供了管理 IAM 策略,使 Systems Manager 能够运行;这也附加到实例配置文件中。
系统管理器和会话管理器
会话管理器首选项是存储上述配置的地方,确保使用相同的 S3 存储桶或 CloudWatch 组。
将日志导入 SIEM(可选)
安全信息和事件管理系统将从多个来源捕获日志,以进行分析并对潜在恶意活动发出警报。与在 CloudWatch 中配置警报相比,安全分析师在 SIEM 中配置规则可能更容易。这也意味着您可以快速使 CloudWatch 日志过期以节省成本,因为无论如何日志都会被提取到外部系统中。
会话记录的先决条件

  • 使用安装了 SSM 代理的 Amazon 系统映像 (AMI)(Amazon Linux 2023 默认安装了它)。
  • 按照AWS 的指南配置系统管理器(某些设置在我的 terraform 配置中)。
  • 确保已配置 ec2messages、ssm、ssmmessages、kms、logs 和 s3 的 VPC 端点。我还发现还需要 S3 的网关端点。

设置和使用会话管理器日志
Terraform 配置
下面是我用来配置此演示的核心方面的 Terraform。
ec2.tf — 配置 EC2 实例和相关设置
这将在您的 VPC 中创建 EC2,并创建一个允许所有 IP 地址出站的安全组。请注意,没有入站端口 22。还有一个 IAM 策略,用于向 CloudWatch、S3 和 KMS 提供权限;这确保我们可以发送日志并使用正确的加密密钥。
接下来,这将创建角色,附加我们的 IAM 策略以及所需的 AmazonSSMManagedInstanceCore 策略。(这是一个 AWS 托管策略,是 SSM 服务与 EC2 实例上的 SSM 代理通信所必需的)。
最后,将创建一个实例配置文件,并使用从 IAM 角色获取的权限将其附加到 EC2。

# Creates EC2 instance
resource "aws_instance" "ssm_recording_example" {
  ami                    = data.aws_ami.amazon_linux_2023.id
  instance_type          = "t2.micro"
  iam_instance_profile   = aws_iam_instance_profile.ec2_ssm_instance_profile.name
  subnet_id              = data.aws_subnet.subnet.id
  vpc_security_group_ids = ["${aws_security_group.session_manager_security_group.id}"]
  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required" # This enforces the use of IMDSv2
    http_put_response_hop_limit = 1
  }
  tags = {
    Name        = "Session Manager Demo"
    Environment = "Development"
    Owner       = "Medium Article"
  }
}
# Creates Security Group
resource "aws_security_group" "session_manager_security_group" {
  name        = "Session Manager Security Group"
  description = "Session Manager Security Group"
  vpc_id      = data.aws_vpc.main.id
  tags = {
    Name : "Session Manager Security Group"
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
# Creates EC2 IAM Policy
resource "aws_iam_policy" "session_manager_recording_policy" {
  name        = "SSM-SessionManager-S3-KMS-Logging"
  description = "Policy for SSM Session Manager logging to S3 with KMS encryption"
  policy      = <<EOF
  {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PutObjectsBucket",
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Effect": "Allow",
      "Resource": "${aws_s3_bucket.log_bucket.arn}/*"
    },
    {
      "Sid": "ListBucketAndEncryptionConfig",
      "Action": [
        "s3:GetEncryptionConfiguration"
      ],
      "Effect": "Allow",
      "Resource": "${aws_s3_bucket.log_bucket.arn}"
    },
    {
      "Sid": "S3KMSSessionManagerKMS",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey*"
      ],
      "Resource": [
        "${aws_kms_key.log_key.arn}"
      ]
    },
        {
            "Sid": "cloudwatch",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams"
            ],
            "Resource": "*"
        }
  ]
}
EOF
}
# Creates IAM role
resource "aws_iam_role" "ec2_ssm_role" {
  name = "ec2_ssm_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })
  managed_policy_arns = ["${aws_iam_policy.session_manager_recording_policy.arn}", "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"]
}
# Creates instance profile
resource "aws_iam_instance_profile" "ec2_ssm_instance_profile" {
  name = "ec2_ssm_instance_profile"
  role = aws_iam_role.ec2_ssm_role.name
}

s3.tf - 存储桶配置

在这里创建存储桶、启用版本控制(推荐)、定义 KMS 密钥以及存储桶策略。为 S3、KMS 和 EC2 定义资源和身份策略似乎很复杂,但请记住,这是一个多帐户配置,因此需要多做一些工作才能获得正确的权限。

resource "aws_s3_bucket" "log_bucket" {"aws_s3_bucket" "log_bucket" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket_versioning" "log_bucket_versioning" {
  bucket = aws_s3_bucket.log_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "log_bucket_encryption" {
  bucket = aws_s3_bucket.log_bucket.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.log_key.arn
    }
    bucket_key_enabled = true
  }
}
resource "aws_s3_bucket_policy" "log_bucket_policy" {
  bucket = aws_s3_bucket.log_bucket.id
  policy = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetEncryptionConfiguration",
            "Resource": "${aws_s3_bucket.log_bucket.arn}",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "${var.organization_id}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "${aws_s3_bucket.log_bucket.arn}/*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "${var.organization_id}"
                }
            }
        }
    ]
}
POLICY
}


cloudwatch.tf — 日志组
这将创建一个日志组并使用 KMS 密钥进行加密。(在生产环境中,最好为 CloudWatch 和 S3 使用专用的 KMS 密钥。

resource "aws_cloudwatch_log_group" "session_manager_logs_group" {"aws_cloudwatch_log_group" "session_manager_logs_group" {
  name              = "session_manager_logs"
  kms_key_id        = aws_kms_key.log_key.arn
  log_group_class   = "STANDARD"
  retention_in_days = 30
  tags = {
    Environment = "Sandbox"
  }
}

data.tf — 填充输入以供稍后使用
这是我们指定 VPC 的标签名称的地方,因此我们可以使用 terraform 查询 AWS API 并检索其属性,即 VPC ID。如果您知道 VPC ID,则不需要此数据源,只需将 VPC ID 引用为变量,或者如果它作为资源存在于您的 terraform 配置中,请从那里引用它。(子网 ID 类似)
最后,我们查询最新的 AMI,如果您使用的是 Amazon Linux 2023 映像,这将很有用。我们输出 AMI ID 以供稍后使用。

data "aws_vpc" "main" {"aws_vpc" "main" {
  filter {
    name   = "tag:Name"
    values = ["INSERT VPC NAME"]
  }
}

data "aws_subnet" "subnet" {
  filter {
    name   = "tag:Name"
    values = ["INSERT SUBNET NAME"]
  }
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-kernel-5.10-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }
}

output "ami_id" {
  value = data.aws_ami.amazon_linux_2023.id
}


变量
这里的变量是存储桶的名称、组织 ID、帐户 ID 和区域。您的 Terraform 中可能不需要其中的部分或全部,具体取决于您的 Terraform 状态中已有的内容。同样,您可以选择使用其他方法来输入这些值,以使代码更具可重用性,例如 CI 管道变量。

variable "bucket_name" {"bucket_name" {
  type    = string
  default = "medium-session-manager-article"
}

variable "organization_id" {
  type    = string
  default = "INSERT ORG ID"
}

variable "account_id" {
  type    = string
  default = "INSERT ACCOUNT ID"
}

variable "region" {
  type    = string
  default = "eu-west-1"
}


请注意,在撰写本文时,AWS Terraform 提供程序中没有用于会话管理器首选项的原生 Terraform 资源。但是,如果您想自动执行此过程,可以使用自定义模块,可在此处找到。在接下来的几个步骤中,我将改为显示来自 AWS 控制台的屏幕截图。

  1. 访问 AWS 中的 Systems Manager 服务,在 Node Management 下,您将找到 Session Manager。单击Preferences,然后单击 Edit

2. 在常规首选项中,您可以指定多个选项,包括(如果愿意,您可以将这些选项保留为默认选项):

  • 会话超时
  • 最大会话时长——您可以选择在 SSM 中恢复会话,因此这需要与您的团队讨论
  • 使用 KMS 代替 TLS
  • 为 Linux EC2 实例指定运行方式 — 如果您拥有具有特定用户的自定义 AMI,则这可能会很有用。

3. 日志选项——重要!
这是我们指定日志发送目的地的地方。我们可以指定 CloudWatch、S3 或两者。

4. 我们可以在这里指定几个选项,在本例中我们保留默认设置。选择要将日志发送到的 CloudWatch 日志组,然后单击“保存”。

5. 如果需要,我们还可以将日志发送到 S3;如果您有日志保留要求并且希望将 CloudWatch 成本降至最低,这可能会很有用。
选择要将日志发送到的存储桶,并指定选项前缀。我建议使用AccountID/session-logs/前缀,这样您就可以轻松识别日志来自哪个 AWS 帐户。提醒一下,没有用于此目的的 Terraform 资源,因此您需要手动完成此部分或作为帐户销售流程的一部分。

CloudWatch 中的示例日志
下面是我在 EC2 实例中输入一些命令的示例。

以下是 CloudWatch 中的相应活动。

值得注意的是,会话记录在 AWS CloudTrail 中,提供审计功能,以实现问责和不可否认性。
会话管理器如何通过将活动记录到 CloudWatch 和 S3 来增强安全态势
通过捕获 EC2 实例的按键,它将帮助安全团队提高检测和响应能力,因为他们可以为输入特定命令(例如提升到 root 权限)的情况建立规则。此外,通过将日志发送到 SIEM,可以使用威胁情报(包括入侵指标 (IOC))来丰富日志,这可能会揭示试图连接到可疑域(命令和控制流量)的行为,无论是窃取数据还是用作加密挖掘队列的一部分。
该解决方案的第二个好处是它增加了一层审计和合规性,使安全团队能够记录已发生的变更。这允许外部审计员批准有足够的控制措施来检测未经授权的活动。此外,由于 SSM 使用 IAM 权限授予对 Session Manager 的访问权限,因此如果通过公司安全策略限制控制台访问,它可以用作预防性控制。应该注意的是,还有其他解决方案可以提供更复杂的特权访问,其中之一就是Teleport
需要注意的是,如果 EC2 以其他方式受到攻击(例如导致远程执行命令的 RCE 攻击),会话管理器将不会捕获日志,因此始终有必要实施多种安全控制措施来检测和应对威胁。示例包括将 Linux 操作系统日志从 EC2 实例集中到 CloudWatch 和部署端点传感器(如eBPF)
最后的想法
AWS 一直在努力寻找更安全的方式来提供对其服务的访问,但让大家接受这些新的工作方式往往是一个挑战。人们已经习惯了自己的工作方式,很难改变他们的工作方式;通过终端或使用堡垒进行连接是一种便捷的做法,这种做法已经存在了 25 年多。
虽然有一些像 Teleport 这样的第三方供应商做得很好,但有时使用原生 AWS 工具更容易,使用 Wiz 之类的工具集中审核配置并将其注销到 CloudWatch 或 S3 之类的一致存储解决方案。
我可能应该在本文开头就说明一个免责声明;这假设您的环境中已经存在高水平的一致性和护栏;如果您允许开发人员在没有正确 IAM 角色的情况下启动 EC2 实例,SSM 根本无法工作。因此,您需要有权限边界或服务控制策略等控制措施来强制遵守上述护栏。您甚至可以强制实施基础设施即代码扫描,以防止在没有此解决方案运行所需的先决条件的情况下部署配置。

感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)

标签:管理器,DevSecOps,AWS,aws,SSH,bucket,日志,EC2
From: https://blog.csdn.net/2401_85233349/article/details/141679503

相关文章

  • OpenSSH 存在输入验证错误漏洞(CVE-2019-16905) 解决
    1、下载文件:zlib-1.2.11.tar.gzopenssh-8.3p1.tar.gzopenssl-1.1.1g.tar.gz 2、解压升级包tar--no-same-owner-zxvfzlib-1.2.11.tar.gztar--no-same-owner-zxvfopenssh-8.3p1.tar.gztar--no-same-owner-zxvfopenssl-1.1.1g.tar.gz 3、编译安装zlibcdzli......
  • SSH 与 Telnet 的区别
     和SSH协议类似,它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个tel......
  • Multipass虚拟机ssh登录(密码方式)
    Multipass虚拟机ssh登录(密码方式)[!NOTE]以Ubuntu24,04LTS为例准备工作为了演示新建一个示例虚拟机。multipasslaunch--namevm01-c4-m4G-d100G--networkbridged操作步骤进入虚拟机multipassshellvm01设置密码multipass默认会给所有实例生......
  • SSH弱口令爆破服务器
    一、实验背景1、概述使用kali的hydra进行ssh弱口令爆破,获得服务器的用户名和口令,通过ssh远程登录服务器。2、实验环境kali攻击机:192.168.1.107centos服务器:192.168.1.105二、前置知识1、centos设置用户并设置弱口令centos查看用户名cat/etc/passwdcentos查看密码ca......
  • POLIR-Society-Organization-Lawsuits: (2020)粤0303民初16184号判决书
    (2020)粤0303民初16184号判决书深圳市罗湖区人民法院送达公告页:https://guanwang.szlhfy.gov.cn/news/14209.cshtml送达公告列表页(第162页):https://guanwang.szlhfy.gov.cn/sdgg/162/20240827_163138GMT+0800......
  • 使用AWS DMS迁移数据,大概核对数据是否相同
    #!/bin/bashecho"scriptstart...."Source='/data/dba/mysql8/bin/mysql-uadmin_dba-ppassword-hxxx'Target='/data/dba/mysql8/bin/mysql-uadmin_dba-ppassword-hxxxxx'#showdatabases过滤出数据库名echo$Sourcedbs=`$Source......
  • [1050] Website endpoints in AWS
    ref:WebsiteendpointsWebsiteendpointexamplesThefollowingexamplesshowhowyoucanaccessanAmazonS3bucketthatisconfiguredasastaticwebsite.Example—RequestinganobjectattherootlevelTorequestaspecificobjectthatisstored......
  • [1047] AWS S3 bucket owner granting cross-account bucket permissions
    ref:Bucketownergrantingcross-accountbucketpermissionsPreparingforthewalkthroughStep1:DotheAccountAtasksStep2:DotheAccountBtasksStep3:(Optional)TryexplicitdenyStep4:Cleanup......
  • [1046] Different permissions in the AWS S3 policy
    Thes3:GetObjectpermissioninanAWSS3policyallowsausertoretrieveobjects(files)fromanS3bucket.Thispermissioniscrucialforreadaccess,enablinguserstodownloadorviewthecontentsoftheobjectsstoredinthebucket123.Here’sanexam......
  • xshell使用跳板机ssh连结远程后使用SFTP
    xshell连结跳板机后,再使用ssh连结到真实机器,SFTP只能显示原跳板机的目录,不能显示真实目录.可以使用隧道,代理来显示真实目标机器的目录.参考:https://blog.csdn.net/qq_43797186/article/details/1236690711.在原跳板机的ssh连结,增加隧道ssh连结属性->连结->SSH->隧道......