ECR Repo and images for osquery in dogfood-free (#15516)

This commit is contained in:
Robert Fairburn 2023-12-13 11:52:57 -06:00 committed by GitHub
parent 6353849004
commit e064b58724
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 305 additions and 0 deletions

View file

@ -148,3 +148,25 @@ provider "registry.terraform.io/hashicorp/tls" {
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/kreuzwerker/docker" {
version = "3.0.2"
constraints = "3.0.2"
hashes = [
"h1:XjdpVL61KtTsuPE8swok3GY8A+Bu3TZs8T2DOEpyiXo=",
"zh:15b0a2b2b563d8d40f62f83057d91acb02cd0096f207488d8b4298a59203d64f",
"zh:23d919de139f7cd5ebfd2ff1b94e6d9913f0977fcfc2ca02e1573be53e269f95",
"zh:38081b3fe317c7e9555b2aaad325ad3fa516a886d2dfa8605ae6a809c1072138",
"zh:4a9c5065b178082f79ad8160243369c185214d874ff5048556d48d3edd03c4da",
"zh:5438ef6afe057945f28bce43d76c4401254073de01a774760169ac1058830ac2",
"zh:60b7fadc287166e5c9873dfe53a7976d98244979e0ab66428ea0dea1ebf33e06",
"zh:61c5ec1cb94e4c4a4fb1e4a24576d5f39a955f09afb17dab982de62b70a9bdd1",
"zh:a38fe9016ace5f911ab00c88e64b156ebbbbfb72a51a44da3c13d442cd214710",
"zh:c2c4d2b1fd9ebb291c57f524b3bf9d0994ff3e815c0cd9c9bcb87166dc687005",
"zh:d567bb8ce483ab2cf0602e07eae57027a1a53994aba470fa76095912a505533d",
"zh:e83bf05ab6a19dd8c43547ce9a8a511f8c331a124d11ac64687c764ab9d5a792",
"zh:e90c934b5cd65516fbcc454c89a150bfa726e7cf1fe749790c7480bbeb19d387",
"zh:f05f167d2eaf913045d8e7b88c13757e3cf595dd5cd333057fdafc7c4b7fed62",
"zh:fcc9c1cea5ce85e8bcb593862e699a881bd36dffd29e2e367f82d15368659c3d",
]
}

View file

@ -0,0 +1,41 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
variable "osquery_tag" {
description = "The osquery tag to take from dockerhub to your ecr repo."
type = string
}
variable "ecr_repo" {
description = "The ecr repo to push to"
type = string
}
resource "docker_image" "dockerhub" {
name = "osquery/osquery:${var.osquery_tag}"
}
resource "docker_tag" "osquery" {
source_image = docker_image.dockerhub.name
# We can't include the sha256 when pushing even if they match
target_image = "${var.ecr_repo}:${split("@sha256", var.osquery_tag)[0]}"
}
resource "docker_registry_image" "osquery" {
name = docker_tag.osquery.target_image
keep_remotely = true
}
output "ecr_image" {
value = docker_tag.osquery.target_image
}

View file

@ -0,0 +1,6 @@
apiVersion: v1
kind: config
spec:
features:
detail_query_overrides:
system_info: "select case when (select count(value) from process_envs where key = 'FAKE_HOSTNAME') > 0 then (select value from process_envs where key = 'FAKE_HOSTNAME' limit 1) else hostname end as hostname, uuid, cpu_type, cpu_subtype, cpu_brand, cpu_physical_cores, cpu_logical_cores, cpu_microcode, physical_memory, hardware_vendor, hardware_model, hardware_version, hardware_serial, board_vendor, board_model, board_version, board_serial, case when (select count(value) from process_envs where key = 'FAKE_HOSTNAME') > 0 then (select value from process_envs where key = 'FAKE_HOSTNAME' limit 1) else computer_name end as computer_name, case when (select count(value) from process_envs where key = 'FAKE_HOSTNAME') > 0 then (select value from process_envs where key = 'FAKE_HOSTNAME' limit 1) else local_hostname end as local_hostname from system_info;"

View file

@ -0,0 +1,232 @@
## Linux hosts in ECS
locals {
osquery_hosts = {
"5.8.2-ubuntu22.04@sha256:b77c7b06c4d7f2a3c58cc3a34e51fffc480e97795fb3c75cb1dc1cf3709e3dc6" = "Skys-laptop"
"5.8.2-ubuntu20.04@sha256:3496ffd0ad570c88a9f405e6ef517079cfeed6ce405b9d22db4dc5ef6ed3faac" = "Cloud-City-server"
"5.8.2-ubuntu18.04@sha256:372575e876c218dde3c5c0e24fd240d193800fca9b314e94b4ad4e6e22006c9b" = "Mists-laptop"
"5.8.2-ubuntu16.04@sha256:112655c42951960d8858c116529fb4c64951e4cf2e34cb7c08cd599a009025bb" = "Ethers-laptop"
"5.8.2-debian10@sha256:de29337896aac89b2b03c7642805859d3fb6d52e5dc08230f987bbab4eeba9c5" = "Breezes-laptop"
"5.8.2-debian9@sha256:47e46c19cebdf0dc704dd0061328856bda7e1e86b8c0fefdd6f78bd092c6200e" = "Aero-server"
"5.8.2-centos8@sha256:88a8adde80bd3b1b257e098bc6e41b6afea840f60033653dcb9fe984f36b0f97" = "Stratuss-laptop"
"5.8.2-centos7@sha256:ff251de4935b80a91c5fc1ac352aebdab9a6bbbf5bda1aaada8e26d22b50202d" = "Zephyrs-Laptop"
"5.8.2-centos6@sha256:b56736be8436288d3fbd2549ec6165e0588cd7197e91600de4a2f00f1df28617" = "Halo-server"
}
}
# ECR to store the images
resource "aws_iam_role" "osquery" {
name = "fleet-free-osquery-execution"
description = "IAM Execution role for osquery containers"
assume_role_policy = data.aws_iam_policy_document.osquery_assume_role.json
}
data "aws_iam_policy_document" "osquery_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
identifiers = ["ecs.amazonaws.com", "ecs-tasks.amazonaws.com"]
type = "Service"
}
}
}
resource "aws_iam_role_policy_attachment" "osquery_execution_attachment" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
role = aws_iam_role.osquery.name
}
resource "aws_iam_role_policy_attachment" "osquery" {
policy_arn = aws_iam_policy.osquery.arn
role = aws_iam_role.osquery.name
}
resource "aws_iam_policy" "osquery" {
name = "osquery-ecr-policy"
description = "IAM policy that Osquery containers use to define access to AWS resources"
policy = data.aws_iam_policy_document.osquery.json
}
data "aws_iam_policy_document" "osquery" {
statement {
actions = [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:GetAuthorizationToken"
]
resources = ["*"]
}
statement {
actions = [ #tfsec:ignore:aws-iam-no-policy-wildcards
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
]
resources = [aws_kms_key.osquery.arn]
}
statement {
actions = [ #tfsec:ignore:aws-iam-no-policy-wildcards
"secretsmanager:GetSecretValue"
]
resources = [aws_secretsmanager_secret.osquery_enroll.arn]
}
}
resource "aws_ecr_repository" "osquery" {
name = "osquery"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.osquery.arn
}
}
resource "aws_kms_key" "osquery" {
deletion_window_in_days = 10
enable_key_rotation = true
}
resource "aws_secretsmanager_secret" "osquery_enroll" {
name = "osquery-enroll-secret"
}
output "osquery_repo" {
value = aws_ecr_repository.osquery
}
output "osquery_iam_policy" {
value = aws_iam_policy.osquery
}
data "aws_region" "current" {}
data "aws_ecr_authorization_token" "token" {}
provider "docker" {
# Configuration options
registry_auth {
address = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com"
username = data.aws_ecr_authorization_token.token.user_name
password = data.aws_ecr_authorization_token.token.password
}
}
module "osquery_docker" {
for_each = local.osquery_hosts
source = "./docker"
ecr_repo = aws_ecr_repository.osquery.repository_url
osquery_tag = each.key
}
resource "random_uuid" "osquery" {
for_each = local.osquery_hosts
}
resource "aws_ecs_task_definition" "osquery" {
for_each = local.osquery_hosts
// e.g. 5-8-2-ubuntu22-04 to match naming requirements
family = "osquery-${replace(split("@sha256", each.key)[0], ".", "-")}"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
execution_role_arn = aws_iam_role.osquery.arn
cpu = 256
memory = 512
# Needed to run hostname command
container_definitions = jsonencode(
[
{
name = "osquery"
image = module.osquery_docker[each.key].ecr_image
cpu = 256
memory = 512
mountPoints = []
volumesFrom = []
essential = true
ulimits = [
{
softLimit = 999999,
hardLimit = 999999,
name = "nofile"
}
]
networkMode = "awsvpc"
logConfiguration = {
logDriver = "awslogs"
options = module.free.byo-db.byo-ecs.logging_config
}
environment = [
{
name = "FAKE_HOSTNAME"
value = each.value
}
]
secrets = [
{
name = "ENROLL_SECRET"
valueFrom = aws_secretsmanager_secret.osquery_enroll.arn
}
]
workingDirectory = "/",
command = [
"osqueryd",
"--tls_hostname=free.fleetdm.com",
"--force=true",
# Ensure that the host identifier remains the same between invocations
"--host_identifier=specified",
"--specified_identifier=${random_uuid.osquery[each.key].result}",
"--verbose=true",
"--tls_dump=true",
"--enroll_secret_env=ENROLL_SECRET",
"--enroll_tls_endpoint=/api/osquery/enroll",
"--config_plugin=tls",
"--config_tls_endpoint=/api/osquery/config",
"--config_refresh=10",
"--disable_distributed=false",
"--distributed_plugin=tls",
"--distributed_interval=10",
"--distributed_tls_max_attempts=3",
"--distributed_tls_read_endpoint=/api/osquery/distributed/read",
"--distributed_tls_write_endpoint=/api/osquery/distributed/write",
"--logger_plugin=tls",
"--logger_tls_endpoint=/api/osquery/log",
"--logger_tls_period=10",
"--disable_carver=false",
"--carver_start_endpoint=/api/osquery/carve/begin",
"--carver_continue_endpoint=/api/osquery/carve/block",
"--carver_block_size=8000000",
]
}
])
lifecycle {
create_before_destroy = true
}
}
resource "aws_ecs_service" "osquery" {
for_each = local.osquery_hosts
# Name must match ^[A-Za-z-_]+$ e.g. 5-8-2-ubuntu22-04
name = "osquery_${replace(split("@sha256", each.key)[0], ".", "-")}"
launch_type = "FARGATE"
cluster = module.free.byo-db.byo-ecs.service.cluster
task_definition = aws_ecs_task_definition.osquery[each.key].arn
desired_count = 1
# Spin down before spin up since we are specifying the host identifier manually
deployment_minimum_healthy_percent = 0
deployment_maximum_percent = 100
network_configuration {
subnets = module.free.byo-db.byo-ecs.service.network_configuration[0].subnets
security_groups = module.free.byo-db.byo-ecs.service.network_configuration[0].security_groups
}
}

View file

@ -21,6 +21,10 @@ terraform {
source = "hashicorp/aws"
version = "~> 5.0"
}
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}