创建你的RedTeam基础架构

news2024/11/15 21:28:20

随着RedTeaming行业的发展,我们对构建可靠环境的需求也越来越高。至关重要的是要拥有维护健壮的基础架构的能力,该基础架构要保证一旦出现问题就可以重新创建,更重要的是,我们需要确保环境在部署时不会出现问题。

 

今天,我开始发布一系列文章中的第一篇,我们将采用DevOps团队流行的一些做法,并希望使用这些技术来帮助我们构建稳定且经过测试的基础架构。在本文中,我将快速回顾一下如何在代码中定义RedTeam基础架构,这些代码放在Git仓库中。但是,更重要的是,我们将继续研究环境不断变化和复杂性增加的测试方法,并逐步介绍如何将CI管道引入混合流程以帮助实现此测试的自动化。

管理我们的基础架构

长期以来,典型的RedTeam基础架构部署的构建都使用redirectors的概念进行了标准化。最基本的C2部署如下所示:

到目前为止,我们都了解了在选择C2框架之前使用重定向器的优势,使我们能够通过团队服务器控制客户敏感数据,并掩盖了真正的流量来源,同时允许快速重新创建这些一次性重定向器而无需需要拆除后端服务器。

那么,这一切如何管理?多年来,我已经看到了许多种不同的方式来部署环境。最常见的设置是手动部署每个组件的位置。对于AWS用户,这意味着需要通过管理控制台来创建EC2实例,通过SSH进入,为反向隧道配置SSH等。当然,一旦BlueTeam找到重定向器,实例就会被拆除,然后我就要重新配置新实例,依此类推...

这显然很烦人且容易出错,因此诞生自动化RedTeam基础架构部署的想法。我将从awsaz shell命令包装到脚本中,再到通过配置文件使用Terraform管理环境。

但是,在开始测试基础架构之前,我们实际上需要一些基础架构进行测试。

Terraform

首先,我们将专注于创建容纳我们资源的基础结构的过程。可能许多人都熟悉Terraform,它是Hashicorp的工具,Terraform允许您在云服务(例如AWS,Azure和DigitalOcean)上创建,更新和销毁基础架构。基础结构在HCL脚本中进行了描述,并在进行了设计之后,我们将其交给Terraform及其提供者来“ 实现 ”。

出于本文的目的,我们将创建一个非常简单的环境,其中包含2个充当重定向器的EC2实例。用于执行此操作的Terraform脚本通常如下所示:

provider "aws" {
  region = "eu-west-2"
}
variable "INSTANCE_NAMES" {
  default = {
    "0" = "Redirector-ShortHaul"
    "1" = "Redirector-LongHaul"
  }
}
variable "PUBLIC_KEY" {
  default = "./keys/terraformkey.pub"
}
variable "MANAGEMENT_IP" {
  default = "1.2.3.4/32"
}
resource "aws_key_pair" "terraformkey" {
  key_name   = "${terraform.workspace}-terraform-key"
  public_key = file("${var.PUBLIC_KEY}")
}
resource "aws_security_group" "redirector-sg" {
  name = "redirector-sg"
  # Allow HTTP inbound
  ingress {
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 80
    to_port     = 80
  }
  # Allow HTTPS inbound
  ingress {
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 443
    to_port     = 443
  }
  # Allow management from our management IP
  ingress {
    protocol    = "tcp"
    cidr_blocks = ["${var.MANAGEMENT_IP}"]
    from_port   = 22
    to_port     = 22
  }
  # Allow global outbound
  egress {
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
  }
}
data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["099720109477"]
}
resource "aws_instance" "redirector" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  count         = length(var.INSTANCE_NAMES)
  key_name      = aws_key_pair.terraformkey.key_name
  vpc_security_group_ids = [
    "${aws_security_group.redirector-sg.id}",
  ]
  tags = {
    Name    = "${var.INSTANCE_NAMES[count.index]}"
    JobName = "${terraform.workspace}"
  }
}
output "redirector_ips" {
    description = "Public IP addresses of created redirectors"
    value = aws_instance.redirector.*.public_ip
}

为了确保我们可以运行基础架构的多个实例并且不会与其他参与资源冲突,我们通常通过以下方式创建新的Terraform工作空间:

terraform workspace new InsecureBank

但是在部署之前,让我们通过执行terraform plan来测试一切是否正常:

一旦我们对所有内容进行了检查,就可以移至terraform apply命令:

Terraform完成后,我们可以查询AWS并验证是否已创建服务器:

aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value,InstanceType,PublicIpAddress]' --output json

接下来我们需要配置它们。这里不需要使用SSH,无需手动配置任何内容。相反,让我们看一下如何使这一步骤自动化。

Ansible

尽管有诸如Chef和Puppet之类的其他工具,但是Ansible仍然是我最喜欢的工具之一

因此,我们知道现在有2台在线服务器要配置。我们也知道它们的功能将是相同的,这意味着一个写得很好的Ansible脚本应该能够应用于每个环境。

让我们从创建工作区开始。我发现以下布局对此类项目很有用:

.
├── ansible.cfg
├── playbooks
│   └── 10_example.yml
├── roles
│   ├── requirements.yml
│   └── ubuntu-nginx
│       ├── ...
└── site.yml

这种布局的想法是提供存储我们的脚本和角色的位置,同时包括一个Ansible配置文件,该文件将提供存储规则的位置。

我尝试坚持创建Ansible角色来封装相似的配置区域,例如,对于这样的项目,我们将为以下区域创建单独的角色:

加强基础安装

安装Nginx以公开HTTP(S)C2

配置SSH以从我们的团队服务器进行访问

添加任何日志记录功能

显然,您可以根据需要自定义重定向器,但是在此示例中,我们将重点放在Web服务器角色上。我们的角色将非常简单,并涉及以下任务:

确保添加了所需的用户和组

安装NGINX

通过配置文件配置NGINX以进行反向代理

综上所述,我们的Ansible角色YAML可能看起来像这样:

---
- name: Ensure group "nginx" exists
  group:
    name: nginx
    state: present
- name: Add the user nginx
  user:
    name: nginx
    shell: /bin/nologin
    groups: nginx
- name: Install NGINX
  apt:
    name: nginx
    state: present
    update_cache: yes
- name: Add NGINX configuration from template
  template:
    src: default.conf.j2
    dest: /etc/nginx/conf.d/default.conf
    owner: root
    group: root
    mode: 0644
  notify: restart nginx

在这里,我们采取了一些简单的步骤来添加我们的nginx用户,安装NGINX并添加从模板制作的配置文件。我们可以使用脚本来应用它,例如:

---
 - hosts: redirector*
   become: yes
   gather_facts: no
   pre_tasks:
        - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
        - setup: # aka gather_facts
   roles:
        - redirector-nginx

构建角色和脚本后,通过terraform-inventory工具可以轻松地将Ansible角色应用于重定向器的过程,该工具使我们能够解析Terraform状态文件并动态构建Ansible库存。例如,通过上面的Ansible项目,我们可以使用以下方法来应用角色:

TF_STATE=../terraform ansible-playbook --inventory-file=/usr/local/bin/terraform-inventory -u ubuntu --private-key ../terraform/keys/terraformkey site.yml

我们将要测试两个方面。首先将是我们的Ansible角色,负责实际配置重定向器。第二个将是包含重定向器的AWS基础架构的部署,以及部署后实际AWS重定向器的状态。

使用Molecule测试Ansible

建立Ansible可能会很难,对我们来说幸运的是,有工具可以帮助测试Ansible,这也使我们可以从提高的开发速度。为此,我们将使用一个名为Molecule的框架。这个框架已经存在了一段时间,并且实质上允许您隔离地部署Ansible角色(例如,在Docker容器内),并在应用角色后使用TestInfra测试容器的状态。

首先,我们需要使用pip安装Molecule:

# Create our venv
python -m venv env
source ./env/bin/activate
# Install molecule
pip install --user molecule

安装完成后,我们将为Ansible角色构建一些测试。Molecule使用“scenarios”的概念来描述测试用例的**。让我们使用以下方法创建默认场景以测试NGINX角色:

cd rolename; molecule init scenario -r rolename

我们看一下内部,将会看到类似以下的内容:

.
└── default
    ├── Dockerfile.j2
    ├── INSTALL.rst
    ├── molecule.yml
    ├── playbook.yml
    └── tests
        ├── test_default.py
        └── test_default.pyc

对于这种情况,我们的测试将添加到test_default.py Python脚本中,并将使用TestInfra框架。但是在开始之前,我们应该花一些时间通过Molecular.yml文件配置场景。由于我通常偏爱基于Ubuntu的服务器,因此我想确保测试在相似的环境中运行。为此,我们只需将“平台”部分更新为:

platforms:
  - name: instance
    image: ubuntu:18.04

接下来,让我们创建一些简单的测试来展示此框架的功能。我们知道此角色将部署NGINX,因此,作为一个很好的起点,我们可以进行测试以确保在我们的角色运行后实际安装了NGINX,如下所示:

def test_nginx_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed

我们还想确保在应用角色时NGINX实际上正在运行:

def test_nginx_running(host):
    nginx = host.service("nginx")
    assert nginx.is_running

带有反向代理信息的自定义配置又如何呢?好吧,让我们添加一些检查以确保一旦应用角色,我们的配置实际上就存在:

def test_nginx_configuration(host):
    passwd = host.file("/etc/nginx/conf.d/default.conf")
    assert passwd.contains("proxy_pass")
    assert passwd.user == "nginx"
    assert passwd.group == "nginx"
    assert passwd.mode == 0o644

将此添加到我们的Molecule测试用例后,让我们开始快速测试以确保所有功能都适用:

molecule test

现在,在我们的情况下,我们可能会看到以下内容:

这意味着测试失败了,因为我们的NGINX配置文件是root拥有的,并且我们的测试正在寻找nginx的用户,所以让我们更新测试以反映这一点:

def test_nginx_configuration(host):
    passwd = host.file("/etc/nginx/conf.d/default.conf")
    assert passwd.contains("proxy_pass")
    assert passwd.user == "root"
    assert passwd.group == "root"
    assert passwd.mode == 0o644

希望当我们重新运行测试时,我们将看到如下所示:

在我们继续测试Ansible角色之前,值得一提的是在开发工作流程中使用Molecule的另一个优势。我发现,使用Ansible开发的痛苦之一是您必须进行许多调整才能使工作按预期进行,然后清理环境并重复进行。幸运的是,Molecule公开了Molecular converge命令,该命令使您可以在不运行任何测试的情况下将Ansible角色应用于Docker容器。这意味着您可以继续将角色应用于容器,以确保其在开发过程中按预期进行。

InSpec

InSpec是Chef的创造者提供的一个很棒的工具,它使我们能够根据所需状态测试已部署的基础架构。从可用的CIS基准测试到验证某个环境中已修补了漏洞,InSpec有许多用途。我们想使用InSpec来确保我们部署的基础架构满足许多简单的要求:

1.我们只公开HTTP和HTTPS端口吗?

2.SSH是否可用于我们的管理IP?

3.NGINX是否已在两个重定向器上启动并运行?

4.我们的反向代理配置是否应用于重定向器?

在确定了这些简单的测试用例之后,让我们创建一组InSpec测试以验证我们部署的基础架构是否符合我们的期望。

首先,我们需要初始化我们的AWS测试,我们可以使用以下方法进行测试:

inspec init profile --platform aws aws_tests

这将创建一个模板,其布局如下:

.
├── README.md
├── attributes.yml
├── controls
│   └── example.rb
├── inspec.lock
└── inspec.yml

在本文中,我们将使用example.rb来介绍Terraform构建的AWS环境的一些测试。

如果我们专注于确保重定向器处于联机状态,并且我们的安全组仅公开公开HTTP/S,而隐藏SSH,则最终会出现一系列测试用例,例如:

title "AWS"
describe aws_ec2_instance(name: 'Redirector-LongHaul') do
  it { should exist }
end
describe aws_ec2_instance(name: 'Redirector-ShortHaul') do
  it { should exist }
end
describe aws_security_group(group_name: 'redirector-sg') do
  it { should exist }
  it { should allow_in(port: 80, ipv4_range: '0.0.0.0/0') }
  it { should allow_in(port: 443, ipv4_range: '0.0.0.0/0') }
  it { should allow_in(port: 22, ipv4_range: '1.2.3.4/32') }
end

确保通过aws configure命令或环境变量配置了您的AWS配置文件,并且我们可以使用我们的默认配置文件运行InSpec测试,其中包括:

cd test-aws; inspec exec . -t aws://

希望一切顺利,我们应该看到我们收到了InSpec的确认,确认所有内容都输出:

但是我们的重定向器配置又如何呢?我们怎么知道我们的Ansible角色实际上已被应用?这很容易检查,我们可以使用以下方法创建模板:

inspec init profile redirectors

并添加一些测试用例,类似于上面的测试:

title "Service Config"
describe service('nginx') do
  it { should be_installed }
  it { should be_enabled }
  it { should be_running }
end
describe service('ssh') do
  it { should be_installed }
  it { should be_enabled }
  it { should be_running }
end
describe file('/etc/nginx/conf.d/default.conf') do
    its('content') { should match %r{proxy_pass } }
end

并通过以下方式运行:

inspec exec . -t ssh://ubuntu@HOST -i ./keys/remotekey

这里有一个与我们的预期测试不匹配的NGINX配置文件的示例。快速修复Ansible角色或InSpec测试,我们应该看到所有内容都可以输出:

太好了,让我们确认到目前为止的内容...我们拥有可创建基础架构的Terraform脚本。我们有Ansible脚本和角色,可以提供重定向程序。我们进行了分子测试,以使我们能够快速开发和验证我们的角色,最后,我们进行了InSpec测试,以确保完全按照我们的期望来创建基础架构。

将管道和内容联动

我们现在可以解决所有问题,并且我们相信我们的角色和基础架构将按期望的方式工作。但是,我们如何确保每次有人对这些组件中的任何一个进行更改时,下次我们启动或重新启动环境时,一切都能顺利运行?在开发环境中,CI已成为控制代码的有用实践。通过强制在推送到Git服务器时运行测试,我们可以确保将代码更改合并到Master中不会在下次部署时造成中断。

为了创建我们的CI管道,我们将使用Gitlab,这是我当前选择的托管Git服务器。Gitlab不仅是托管我们的Git仓库的好地方,而且还充当CI / CD平台,使我们能够通过Gitlab Runners执行测试,构建和部署。

那么CI到底是什么?CI的意思是“持续集成”,这是一种通过大量自动化测试不断将开发人员所做的更改合并到稳定分支中的实践,以确保推送的提交不会破坏任何内容。这个想法是,通过使用测试在合并期间保持质量水平。

为了将测试的每个阶段联系在一起,我们需要在gitlab-ci.yml文件中描述每个阶段,该文件位于项目的根目录中。这将使我们能够构建流水线,可用于通过Git推送进行测试,过渡到暂存环境,并通过一系列验证步骤来确保基础结构完全符合我们的期望。

我们管道的每个阶段将定义为:

测试–通过Molecule测试Ansible

测试– Terraform HCL验证

阶段–部署到测试环境

预配–使用Ansible预配已部署的服务器

验证–测试环境的InSpec验证

清理–拆除基础设施

让我们从定义各个管道阶段开始,将每个阶段分解为如何在gitlab-ci.yml文件中表示:

stages:
  - test
  - stage
  - provision
  - validate
  - cleanup

在这里,我们定义了管道的每个阶段,我们可以将它们匹配到上面定义的步骤。接下来,我们需要从Terraform开始,告诉Gitlab在每个阶段做什么:

terraform_validate:
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: test
  script:
    - cd terraform 
    - terraform init
    - terraform validate

这里的想法很简单,如果基本的Terraform配置没有输出,我们不想继续进行其他步骤,因此我们在继续之前执行一个简单的验证步骤。

完成此阶段后,我们将开始为Ansible运行测试:

molecule_tests:
  image: docker:latest
  stage: test
  before_script:
    - apk update && apk add --no-cache docker
      python3-dev py3-pip docker gcc git curl build-base
      autoconf automake py3-cryptography linux-headers
      musl-dev libffi-dev openssl-dev openssh
    - docker info
    - python3 --version
  script:
    - pip3 install ansible molecule docker
    - cd ansible/roles/ubuntu-nginx
    - molecule test

在这里,我们将使用docker:latest映像以及“ Docker-in-Docker”服务,以允许Molecule启动运行Molecule测试所需的其他容器。值得注意的是,在此阶段,我们正在管道阶段执行过程中安装Molecule框架。我不建议您在自己的管道中执行此操作,因为这样做是为了演示执行Molecule所需的操作。实际上,您将托管具有所有预配置内容的Docker映像,以加快测试速度。

一旦我们的管道达到了这个阶段,我们就已经验证了Terraform文件在语法上是正确的,并且我们的Ansible角色通过了每个创建的测试,因此接下来,我们将把基础架构部署到AWS作为过渡环境进行进一步测试:

deploy_stage:
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: stage
  script:
    - cd terraform
    - terraform init
    - terraform apply --auto-approve
  artifacts:
    paths:
      - terraform/terraform.tfstate
    expire_in: 1 day

与之前的Terraform阶段相似,我们只是使用Hashicorp的Terraform Docker映像来提供Terraform工具,但是在Terraform运行之后,我们希望将状态文件保留为工件。工件可以使我们从一个阶段公开文件,并提供将创建的文件传递到管道的后续阶段的能力,这意味着在这种情况下,我们可以将Terraform tfstate文件传递给以后进行清理。

现在,我们已在重定向环境中部署了重定向器,我们需要使用Ansible进行配置:

provision_stage:
  stage: provision
  when: delayed
  start_in: 30 seconds
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - apk add ansible
    - wget https://github.com/adammck/terraform-inventory/releases/download/v0.9/terraform-inventory_0.9_linux_amd64.zip -O /tmp/terraform-inventory_0.9_linux_amd64.zip
    - unzip /tmp/terraform-inventory_0.9_linux_amd64.zip -d /usr/bin/; chmod 700 /usr/bin/terraform-inventory
  script:
    - cd terraform; terraform init; cd ..
    - cd ansible; chmod 600 .
    - chmod 600 ../terraform/keys/terraformkey
    - ANSIBLE_HOST_KEY_CHECKING=False TF_STATE=../terraform ansible-playbook --inventory-file=/usr/bin/terraform-inventory -u ubuntu --private-key ../terraform/keys/terraformkey site.yml

同样,您通常将创建一个Docker映像以加快此阶段,并根据需要添加“ terraform-inventory”工具。

在配置了重定向器之后,我们将针对AWS环境运行我们先前设计的InSpec测试:

inspec_tests:
  stage: validate
  image: 
    name: chef/inspec:4.18.51
    entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - apk add jq
  script:
    - inspec --chef-license=accept-silent
    - cd inspec
    - inspec exec redirectors -t "ssh://ubuntu@$(jq '.redirector_ips.value[0]' -r ../terraform/output.json)" -i ../terraform/keys/terraformkey
    - inspec exec redirectors -t "ssh://ubuntu@$(jq '.redirector_ips.value[1]' -r ../terraform/output.json)" -i ../terraform/keys/terraformkey

最后,一旦一切完成,我们将自己清理环境:

cleanup:
  when: always
  image: 
    name: hashicorp/terraform:light
    entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: cleanup
  script:
    - cd terraform
    - terraform init
    - terraform destroy --auto-approve

您可能会在这里注意到when:always语句。这仅表示即使上一个阶段失败,该阶段也将运行。即使测试失败,这也使我们有机会清理过渡环境,以避免积累不必要的AWS费用。

当我们将gitlab-ci.yml文件放在一起时,会得到如下所示的内容:

image: docker:latest
services:
  - docker:dind
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
  - terraform/.terraform
stages:
  - test
  - stage
  - provision
  - validate
  - cleanup
terraform_validate:
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: test
  script:
    - cd terraform 
    - terraform init
    - terraform validate
molecule_tests:
  image: docker:latest
  stage: test
  before_script:
    - apk update && apk add --no-cache docker
      python3-dev py3-pip docker gcc git curl build-base
      autoconf automake py3-cryptography linux-headers
      musl-dev libffi-dev openssl-dev openssh
    - docker info
    - python3 --version
  script:
    - pip3 install ansible molecule docker
    - cd ansible/roles/ubuntu-nginx
    - molecule test
deploy_stage:
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: stage
  script:
    - cd terraform
    - terraform init
    - terraform apply --auto-approve
    - terraform output --json > output.json
  artifacts:
    paths:
      - terraform/terraform.tfstate
      - terraform/output.json
    expire_in: 1 day
provision_stage:
  when: delayed
  start_in: 30 seconds
  image: 
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: provision
  before_script:
    - apk add ansible
    - wget https://github.com/adammck/terraform-inventory/releases/download/v0.9/terraform-inventory_0.9_linux_amd64.zip -O /tmp/terraform-inventory_0.9_linux_amd64.zip
    - unzip /tmp/terraform-inventory_0.9_linux_amd64.zip -d /usr/bin/; chmod 700 /usr/bin/terraform-inventory
  script:
    - cd terraform; terraform init; cd ..
    - cd ansible; chmod 600 .
    - chmod 600 ../terraform/keys/terraformkey
    - ANSIBLE_HOST_KEY_CHECKING=False TF_STATE=../terraform ansible-playbook --inventory-file=/usr/bin/terraform-inventory -u ubuntu --private-key ../terraform/keys/terraformkey site.yml
inspec_tests:
  stage: validate
  image: 
    name: chef/inspec:4.18.51
    entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - apk add jq
  script:
    - inspec --chef-license=accept-silent
    - cd inspec
    - inspec exec test-aws -t aws:// 
    - inspec exec redirectors -t "ssh://ubuntu@$(jq '.redirector_ips.value[0]' -r ../terraform/output.json)" -i ../terraform/keys/terraformkey
    - inspec exec redirectors -t "ssh://ubuntu@$(jq '.redirector_ips.value[1]' -r ../terraform/output.json)" -i ../terraform/keys/terraformkey
cleanup_stage:
  when: always
  image: 
    name: hashicorp/terraform:light
    entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  stage: cleanup
  script:
    - cd terraform
    - terraform init
    - terraform destroy --auto-approve

提交到项目后,我们将看到现在可以使用我们的管道,该管道将在每次推送时执行。一旦有人向您的基础架构提交提交,您将收到一个消息,表明一切都已正常:

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,需要点击下方链接即可前往获取 

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

同时每个成长路线对应的板块都有配套的视频提供: 

 大厂面试题

视频配套资料&国内外网安书籍、文档

当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料

所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~  

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

特别声明:

此教程为纯技术分享!本教程的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本教程的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失。

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

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

相关文章

git@gitee.com: Permission denied (publickey)

1、报错信息 $ git clone gitgitee.com:你的用户名/项目名.git Cloning into 项目名... gitgitee.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository exists.、 2、…

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

Unity 权限 之 Android 【权限 动态申请】功能的简单封装 目录 Unity 权限 之 Android 【权限 动态申请】功能的简单封装 一、简单介绍 二、Android 权限 动态申请 三、实现原理 四、注意事项 五、案例实现简单步骤 附录: 一、进一步优化 二、多个权限申请…

AI日报|苹果将在iOS 18中引入ChatGPT,联想或成AI PC最大受益者

文章推荐 AI日报|阿里8亿美元购入月之暗面36%股份,Meta首席杨立昆建议不要研究大模型 阿里通义降价,百度文心免费,一图对比谁是最具性价比大模型? 苹果与OpenAI达成协议:将在iOS 18中提供ChatGPT聊天机器…

服务器数据恢复—EVA存储异常断电重启后虚拟机无法启动如何恢复数据?

服务器存储数据恢复环境: 某品牌EVA8400,服务器上安装VMware ESXi虚拟化平台,虚拟机的虚拟磁盘包括数据盘(精简模式)快照数据盘,部分虚拟机中运行oracle数据库和mysql数据库。 服务器存储故障&检测&…

精准数据提取:提升业务分析与决策效率

在当今信息爆炸的时代,数据已经成为企业运营和决策的核心驱动力。然而,面对海量的数据,如何快速、准确地提取出有价值的信息,成为了摆在众多企业面前的一大挑战。本文将探讨如何通过精准数据提取来提升业务分析与决策的效率。 一…

数据中台建设方案(Word版源文档)

建设大数据管理中台,按照统一的数据规范和标准体系,构建统一数据采集﹣治理﹣共享标准、统一技术开发体系、统一接口 API ,实现数据采集、平台治理,业务应用三层解耦,并按照统一标准格式提供高效的…

有趣的css - 双开门按钮

大家好,我是 Just,这里是「设计师工作日常」,今天分享的是一个双开门的按钮,交互效果比较强,但是实现很简单,快学起来吧。 最新文章通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码cs…

【Redis】 关于 Redis 集合类型

文章目录 🍃前言🌳普通命令🚩sadd🚩smembers🚩sismember🚩scard🚩spop🚩smove🚩srem 🌲集合间操作🚩sinter🚩sinterstore&#x1f6a9…

Serpens3通过 运行脚本,向python传参

def main(a):print(a)#pid等变量名,需要和serpens中同名 main(pid)若.py文件要运行更多的逻辑,可以传参定义执行哪个函数 如何将执行完成的python返回参数给serpens3

2024年湖北水平能力测试能搞定吗?

武汉中级职称报名正式高一段落,意味着今年武汉市中级职称报名除开东湖高新区之外,其余地方都已经正式截止了,那么接下来大家都在准备6月中下旬的水平能力测试考试。 水平能力测试分为两种:面试答辩或者笔试机考试卷,面…

嵌入式进阶——温湿度传感器

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 DHT11温湿度模块原理图官方参考电路数据线通讯协议单总线传送数据位定义数据格式:校验位数据定义 协议实现 DHT11温湿度模块 DHT1…

哇!数据中台竟是企业数字化转型的关键力量!

在当今数字化浪潮席卷的时代,数据中台正成为企业实现数字化转型的关键力量。那么,究竟什么是数据中台呢?它乃是一种持续让企业数据活跃起来的机制,能够将企业内各部分数据汇聚至一个平台,达成数据的统一化管理。 数据中…

idea中快速找到当前git地址

idea中快速找到当前git地址 然后双击就可以看到地址了

apexcharts数据可视化之饼图

apexcharts数据可视化之饼图 有完整配套的Python后端代码。 本教程主要会介绍如下图形绘制方式: 基础饼图单色饼图图片饼图 基础饼图 import ApexChart from react-apexcharts;export function SimplePie() {// 数据序列const series [44, 55, 13, 43, 22]// …

IEEE Account个人姓名修改方法,5分钟解决!

一、背景 之前在注册IEEE Account时,最基础的first name是名,last name是姓都搞错了,太粗心了。然后发现IEEE账户的姓名不能随便修改,需要联系IEEE support center,然后经过一系列探索,发现下面两种方法可…

微软如何打造数字零售力航母系列科普11 - 什么是Microsoft Fabric中的数据工程?

什么是Microsoft Fabric中的数据工程? 目录 1. Lakehouse(湖边小屋) 2. Apache Spark Job Definition (作业定义) 3. Notebook(笔记本) 4. Data Pipeline (数据管道) Microsoft Fabric中的数据工程使用户能够设计、构建和维护基础架构和系统,使其组…

电机控制系列模块解析(24)—— 飞车转速跟踪

转速跟踪启动:又名顺风&&逆风启动、或者飞车启动、或者启动前转速检测。应用背景见附录。 转速跟踪 也可以理解为 对正在高速运行的电机 进行初始位置辨识。 一、转速跟踪方案 转速跟踪是电机控制中的一项关键技术,尤其在变频驱动、伺服系统等…

WebGIS 智慧城市三维可视化综合管控

智慧城市可视化建设不仅提升了城市管理的科技含量和效率,还促进了城市可持续发展,提升了居民的生活质量。随着技术的不断发展和应用,智慧城市可视化建设将会更加丰富和完善,为城市发展带来更加广阔的前景。 图扑应用自研 HT for W…

推荐一个实用的ETF短线交易策略

就短线交易策略来说,ETF是一种很好的工具,流动性充足,交易成本低廉,没有印花税,买卖一个回合的手续费0.02%就够了,甚至更低,而股票卖出时,光印花税就要收0.1%,买卖一个回…

MyBatis多数据源配置与使用,基于ThreadLocal+AOP

导读 MyBatis多数据源配置与使用其一其二1. 引依赖2. 配置文件3. 编写测试代码4. 自定义DynamicDataSource类5. DataSourceConfig配置类6. AOP与ThreadLocal结合7. 引入AOP依赖8. DataSourceContextHolder9. 自定义注解UseDB10. 创建切面类UseDBAspect11. 修改DynamicDataSourc…