6.3 Infrastructure Security #
🎯 Цель изучения #
Научиться обеспечивать безопасность инфраструктуры на всех уровнях: от сетевой безопасности до управления секретами и compliance мониторинга.
🏗️ Infrastructure as Code Security #
Безопасность Terraform #
# ❌ Небезопасная конфигурация
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
# Public access!
acl = "public-read"
}
resource "aws_security_group" "web" {
# Открыт для всех
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Hardcoded secrets
resource "aws_db_instance" "example" {
password = "hardcoded_password_123"
}
# ✅ Безопасная конфигурация
resource "aws_s3_bucket" "example" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_acl" "example" {
bucket = aws_s3_bucket.example.bucket
acl = "private"
}
resource "aws_s3_bucket_public_access_block" "example" {
bucket = aws_s3_bucket.example.bucket
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_security_group" "web" {
name_prefix = "web-"
# Только HTTPS
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [var.allowed_cidr]
}
# Explicit egress
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Secrets from AWS Secrets Manager
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/password"
}
resource "aws_db_instance" "example" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
# Security best practices
encrypted = true
backup_retention_period = 7
backup_window = "03:00-04:00"
maintenance_window = "sun:04:00-sun:05:00"
# Network security
db_subnet_group_name = aws_db_subnet_group.private.name
vpc_security_group_ids = [aws_security_group.db.id]
}
🔍 IaC Security Scanning #
Checkov #
# Установка
pip install checkov
# Сканирование Terraform
checkov -d /path/to/terraform --framework terraform
# Сканирование Kubernetes manifests
checkov -d /path/to/k8s --framework kubernetes
# В CI/CD
checkov -d . --framework terraform --output json --quiet > checkov-report.json
# GitHub Actions
- name: Run Checkov action
uses: bridgecrewio/checkov-action@master
with:
directory: .
quiet: true
soft_fail: true
framework: terraform,kubernetes
output_format: sarif
output_file_path: reports/results.sarif
Terraform Sentinel (Enterprise) #
# sentinel/require-s3-encryption.sentinel
import "tfplan/v2" as tfplan
# Rule: All S3 buckets must be encrypted
main = rule {
all tfplan.resource_changes as _, resource_changes {
resource_changes.type is "aws_s3_bucket" and
resource_changes.change.after.server_side_encryption_configuration is not null
}
}
TFSec #
# Установка
go install github.com/aquasecurity/tfsec/cmd/tfsec@latest
# Сканирование
tfsec .
# Исключения
tfsec --exclude AWS002,AWS017 .
# В формате SARIF
tfsec --format sarif . > tfsec-results.sarif
☁️ Cloud Security Posture Management #
AWS Security Best Practices #
IAM Security #
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT:role/DevOpsRole"
},
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroups"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": ["us-east-1", "us-west-2"]
},
"DateGreaterThan": {
"aws:CurrentTime": "2023-01-01T00:00:00Z"
}
}
}
]
}
# Terraform IAM с принципом least privilege
resource "aws_iam_role" "devops_role" {
name = "DevOpsRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
Condition = {
StringEquals = {
"sts:ExternalId" = var.external_id
}
}
}
]
})
}
resource "aws_iam_policy" "devops_policy" {
name = "DevOpsPolicy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ec2:DescribeInstances",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "*"
}
]
})
}
VPC Security #
# Secure VPC configuration
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
Environment = var.environment
}
}
# Private subnets for databases
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = {
Name = "private-subnet-${count.index + 1}"
Type = "Private"
}
}
# Public subnets for load balancers
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = false # Explicit public IP assignment
tags = {
Name = "public-subnet-${count.index + 1}"
Type = "Public"
}
}
# Network ACLs for additional security
resource "aws_network_acl" "private" {
vpc_id = aws_vpc.main.id
subnet_ids = aws_subnet.private[*].id
# Deny all by default, explicit allow rules
ingress {
protocol = "tcp"
rule_no = 100
action = "allow"
cidr_block = aws_vpc.main.cidr_block
from_port = 3306
to_port = 3306
}
egress {
protocol = "tcp"
rule_no = 100
action = "allow"
cidr_block = aws_vpc.main.cidr_block
from_port = 32768
to_port = 65535
}
tags = {
Name = "private-nacl"
}
}
AWS Config Rules #
{
"ConfigRuleName": "s3-bucket-ssl-requests-only",
"Description": "Checks whether S3 buckets have policies that require SSL requests",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "S3_BUCKET_SSL_REQUESTS_ONLY"
},
"Scope": {
"ComplianceResourceTypes": [
"AWS::S3::Bucket"
]
}
}
Azure Security Center #
# Azure Security Center
resource "azurerm_security_center_subscription_pricing" "main" {
tier = "Standard"
resource_type = "VirtualMachines"
}
resource "azurerm_security_center_contact" "main" {
email = var.security_contact_email
phone = var.security_contact_phone
alert_notifications = true
alerts_to_admins = true
}
🔐 Secrets Management #
HashiCorp Vault #
Установка и настройка #
# Установка Vault
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install vault
# Запуск dev сервера
vault server -dev
# Настройка переменных
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN="dev-token"
Vault конфигурация #
# vault-config.hcl
storage "consul" {
address = "127.0.0.1:8500"
path = "vault/"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = false
tls_cert_file = "/etc/vault/tls/vault.crt"
tls_key_file = "/etc/vault/tls/vault.key"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
ui = true
# Audit logging
audit {
type = "file"
path = "/var/log/vault/audit.log"
}
Vault Policies #
# Database secrets policy
path "database/creds/readonly" {
capabilities = ["read"]
}
path "database/creds/readwrite" {
capabilities = ["read"]
allowed_parameters = {
"ttl" = ["1h", "2h", "4h"]
}
}
# KV secrets policy
path "secret/data/myapp/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/metadata/myapp/*" {
capabilities = ["list"]
}
AWS Secrets Manager Integration #
# Terraform AWS Secrets Manager
resource "aws_secretsmanager_secret" "db_password" {
name = "prod/database/password"
description = "Database password for production"
rotation_rules {
automatically_after_days = 30
}
tags = {
Environment = "production"
Service = "database"
}
}
resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = random_password.db_password.result
}
resource "random_password" "db_password" {
length = 32
special = true
}
Kubernetes Secrets Integration #
# External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
namespace: default
spec:
provider:
vault:
server: "https://vault.example.com:8200"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "myapp-role"
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-secrets
namespace: default
spec:
refreshInterval: 30s
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: app-secrets
creationPolicy: Owner
data:
- secretKey: database-url
remoteRef:
key: secret/myapp
property: database_url
- secretKey: api-key
remoteRef:
key: secret/myapp
property: api_key
🌐 Network Security #
Micro-segmentation #
Kubernetes Network Policies #
# Default deny all policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Allow specific communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-netpol
namespace: production
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to: [] # Allow DNS
ports:
- protocol: UDP
port: 53
Istio Security Policies #
# Istio AuthorizationPolicy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: web-authz
namespace: production
spec:
selector:
matchLabels:
app: web
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/frontend"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
when:
- key: request.headers[user-role]
values: ["admin", "user"]
---
# Istio PeerAuthentication (mTLS)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
Web Application Firewall (WAF) #
# AWS WAF
resource "aws_wafv2_web_acl" "main" {
name = "main-waf"
scope = "CLOUDFRONT"
default_action {
allow {}
}
# Rate limiting
rule {
name = "rate-limit"
priority = 1
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "rate-limit-rule"
sampled_requests_enabled = true
}
}
# OWASP Top 10
rule {
name = "owasp-top-10"
priority = 2
action {
block {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesOWASPTop10RuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "owasp-top-10-rule"
sampled_requests_enabled = true
}
}
}
🛡️ Runtime Security #
Falco для Kubernetes #
# Falco DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: falco
namespace: falco-system
spec:
selector:
matchLabels:
app: falco
template:
metadata:
labels:
app: falco
spec:
serviceAccountName: falco
hostNetwork: true
hostPID: true
containers:
- name: falco
image: falcosecurity/falco:0.35.1
securityContext:
privileged: true
env:
- name: FALCO_K8S_AUDIT_ENDPOINT
value: "http://localhost:8765/k8s-audit"
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket
- mountPath: /host/proc
name: proc-fs
- mountPath: /host/boot
name: boot-fs
- mountPath: /etc/falco
name: falco-config
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
- name: proc-fs
hostPath:
path: /proc
- name: boot-fs
hostPath:
path: /boot
- name: falco-config
configMap:
name: falco-config
# Custom Falco Rules
apiVersion: v1
kind: ConfigMap
metadata:
name: falco-config
namespace: falco-system
data:
custom_rules.yaml: |
- rule: Suspicious Network Activity
desc: Detect suspicious network connections
condition: >
spawned_process and container and
proc.name in (nc, ncat, netcat, wget, curl) and
proc.args contains "http://"
output: >
Suspicious network activity detected
(user=%user.name container=%container.name
image=%container.image.repository command=%proc.cmdline)
priority: WARNING
- rule: Privilege Escalation Attempt
desc: Detect attempts to escalate privileges
condition: >
spawned_process and container and
(proc.name in (sudo, su) or
proc.args contains "chmod +s")
output: >
Privilege escalation attempt
(user=%user.name container=%container.name command=%proc.cmdline)
priority: CRITICAL
📊 Compliance Monitoring #
CIS Benchmarks #
# Kube-bench для CIS Kubernetes Benchmark
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
# Результат
kubectl logs job/kube-bench
# Custom kube-bench job
apiVersion: batch/v1
kind: Job
metadata:
name: kube-bench
spec:
template:
metadata:
labels:
app: kube-bench
spec:
hostPID: true
containers:
- name: kube-bench
image: aquasec/kube-bench:latest
command: ["kube-bench"]
args: ["--version", "1.23"]
volumeMounts:
- name: var-lib-etcd
mountPath: /var/lib/etcd
readOnly: true
- name: var-lib-kubelet
mountPath: /var/lib/kubelet
readOnly: true
- name: etc-kubernetes
mountPath: /etc/kubernetes
readOnly: true
restartPolicy: Never
volumes:
- name: var-lib-etcd
hostPath:
path: "/var/lib/etcd"
- name: var-lib-kubelet
hostPath:
path: "/var/lib/kubelet"
- name: etc-kubernetes
hostPath:
path: "/etc/kubernetes"
Open Policy Agent (OPA) Gatekeeper #
# Constraint Template - Required Labels
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
required := input.parameters.labels
provided := input.review.object.metadata.labels
missing := required[_]
not provided[missing]
msg := sprintf("Missing required label: %v", [missing])
}
---
# Constraint Instance
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: must-have-environment-label
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels: ["environment", "team", "app"]
🎯 Практические задания #
🟢 Задание 1: IaC Security Scanning #
# 1. Создать уязвимую Terraform конфигурацию
cat > main.tf << 'EOF'
resource "aws_s3_bucket" "example" {
bucket = "my-public-bucket"
acl = "public-read"
}
resource "aws_security_group" "web" {
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
EOF
# 2. Сканирование с Checkov
pip install checkov
checkov -f main.tf
# 3. Исправить проблемы
cat > main.tf << 'EOF'
resource "aws_s3_bucket" "example" {
bucket = "my-private-bucket"
}
resource "aws_s3_bucket_acl" "example" {
bucket = aws_s3_bucket.example.bucket
acl = "private"
}
resource "aws_security_group" "web" {
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
}
EOF
🟡 Задание 2: Secrets Management #
# 1. Запустить Vault dev server
vault server -dev &
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN="dev-token"
# 2. Создать секреты
vault kv put secret/myapp \
database_password="super_secure_password" \
api_key="secret_api_key_123"
# 3. Создать policy
vault policy write myapp-policy - << 'EOF'
path "secret/data/myapp" {
capabilities = ["read"]
}
EOF
# 4. Создать token с policy
vault token create -policy=myapp-policy
🟠 Задание 3: Network Policies #
# 1. Создать test namespace
kubectl create namespace test-security
# 2. Применить default deny policy
cat << 'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: test-security
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
# 3. Создать test pods
kubectl run web --image=nginx -n test-security --labels="app=web"
kubectl run client --image=busybox -n test-security --labels="app=client" -- sleep 3600
# 4. Проверить connectivity (должен быть заблокирован)
kubectl exec -n test-security client -- wget -qO- --timeout=2 web
# 5. Создать allow policy
cat << 'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-client-to-web
namespace: test-security
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- protocol: TCP
port: 80
EOF
# 6. Проверить connectivity (должен работать)
kubectl exec -n test-security client -- wget -qO- --timeout=2 web
📚 Полезные ресурсы #
🛠️ Инструменты #
- IaC Security: Checkov, TFSec, Terrascan, Terraform Sentinel
- Secrets Management: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault
- Runtime Security: Falco, Twistlock, Aqua Security, Sysdig
- Compliance: Kube-bench, Docker Bench, CIS-CAT
📖 Стандарты и Frameworks #
🎯 Результаты изучения #
После изучения этого раздела вы:
- ✅ Умеете обеспечивать безопасность Infrastructure as Code
- ✅ Знаете как настроить cloud security posture management
- ✅ Можете управлять секретами с помощью Vault и cloud providers
- ✅ Понимаете принципы network security и micro-segmentation
- ✅ Умеете настраивать runtime security мониторинг
Следующий раздел: 6.4 Container и Kubernetes Security