AWSMiddleTechnical

Как дать доступ к S3 только из конкретной VPC?

Создайте VPC Endpoint типа Gateway для S3 и добавьте в Bucket Policy условие Deny с StringNotEquals aws:SourceVpc или aws:SourceVpce. Без Endpoint условие SourceVpc не сработает даже для инстансов внутри VPC.

Ограничение доступа к S3 только из конкретной VPC

Чтобы разрешить обращения к S3 только из определённой VPC, нужно сочетание двух механизмов: VPC Endpoint для S3 и Bucket Policy с условием aws:SourceVpc или aws:SourceVpce.

Шаг 1: создать VPC Endpoint для S3

VPC Endpoint типа Gateway направляет трафик к S3 через внутреннюю сеть AWS, не выходя в интернет. Без него запросы к S3 идут через NAT Gateway или Internet Gateway.

# Получить ID VPC и таблиц маршрутизации
VPC_ID=$(aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=my-vpc" \
  --query 'Vpcs[0].VpcId' --output text)

RTB_IDS=$(aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'RouteTables[*].RouteTableId' --output text)

# Создать Gateway Endpoint для S3
aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids $RTB_IDS

Шаг 2: Bucket Policy с запретом для запросов не из VPC

Условие aws:SourceVpc проверяет, что запрос пришёл из указанной VPC. Условие aws:SourceVpce ещё точнее — ограничивает до конкретного Endpoint ID.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyAccessOutsideVPC",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-private-bucket",
        "arn:aws:s3:::my-private-bucket/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-0a1b2c3d4e5f67890"
        }
      }
    }
  ]
}

Применение Bucket Policy через CLI

aws s3api put-bucket-policy \
  --bucket my-private-bucket \
  --policy file://bucket-policy.json

Альтернатива: ограничение по конкретному VPC Endpoint

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyIfNotVpce",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-private-bucket",
        "arn:aws:s3:::my-private-bucket/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-0123456789abcdef0"
        }
      }
    }
  ]
}

Важно: исключить административный доступ

Если применить чистый Deny без исключений, даже консоль AWS и IAM-роли с правами администратора потеряют доступ к бакету из-за пределов VPC. Добавьте исключение для IAM-роли управления:

{
  "Condition": {
    "StringNotEquals": {
      "aws:SourceVpc": "vpc-0a1b2c3d4e5f67890"
    },
    "ArnNotLike": {
      "aws:PrincipalArn": "arn:aws:iam::123456789012:role/S3AdminRole"
    }
  }
}

Подводные камни

  • Deny блокирует консоль AWS. При жёстком Deny по SourceVpc даже вы сами не сможете просмотреть содержимое бакета через браузер, если подключены не через VPN в ту VPC. Необходимо добавить исключение для административных ролей.
  • Gateway Endpoint не применяется автоматически. Нужно явно добавить его в таблицы маршрутизации всех нужных подсетей. Если забыли добавить подсеть — трафик пойдёт в обход Endpoint, и условие SourceVpce не выполнится.
  • aws:SourceVpc работает только при наличии Endpoint. Если VPC Endpoint не создан, условие SourceVpc не выполняется даже для запросов из EC2 той же VPC — они уходят через NAT без VPC-идентификатора.
  • Cross-account сценарии. При межаккаунтном доступе условие SourceVpc проверяет VPC в аккаунте источника. Нужно отдельно настраивать для каждого аккаунта-потребителя.
  • S3 Access Points не наследуют политику бакета. Если используете S3 Access Points, ограничение по VPC нужно настраивать и на уровне Access Point Policy, и на уровне Bucket Policy.
  • Block Public Access не заменяет Bucket Policy. Block Public Access блокирует только публичный доступ, но не ограничивает доступ из других VPC или через интернет для аутентифицированных IAM-пользователей.
  • Interface Endpoint vs Gateway Endpoint. Для некоторых S3-операций (например, S3 Object Lambda) нужен Interface Endpoint, а не Gateway. Они работают по-другому и имеют другой идентификатор.

Common mistakes

  • Путать SourceVpc/SourceVpce и обычный source IP.
  • Ломать доступ AWS services слишком широким deny.
  • Не иметь break-glass перед изменением bucket policy.

What the interviewer is testing

  • Предлагает VPC endpoint + bucket policy condition.
  • Учитывает IAM и endpoint policy.
  • Понимает риски блокировки console/service access.

Sources

Related topics