返回文章列表

S3 Bucket 與 CloudFront 安全組態實踐

本文探討如何強化 AWS S3 Bucket 和 CloudFront 的安全設定。首先,透過 Access Analyzer 驗證 S3 Bucket 的存取許可權,並啟用封鎖公開存取功能,確保資料安全。接著,示範如何利用 CloudFront 安全地提供來自 S3 的網頁內容,包含設定 Origin Access

網路安全 雲端服務

在雲端環境中,保護資料安全至關重要。本文將探討如何設定 S3 Bucket 的封鎖公開存取功能,並結合 CloudFront 建立安全的網頁內容傳遞機制。同時,也將介紹 VPC 和子網路的建立,為雲端資源提供穩固的網路基礎。透過 Access Analyzer 掃描 S3 Bucket,可以快速識別潛在的公開存取風險,並據此調整設定,確保資料的機密性。此外,使用 CloudFront 作為 S3 的反向代理,並搭配 OAI 和 Bucket Policy,能有效限制直接對 S3 的存取,提升安全性。最後,建立 VPC 和子網路,可以將資源邏輯地隔離,並實施更精細的存取控制策略。

對 S3 Bucket 啟用封鎖公開存取功能

步驟一:建立 Access Analyzer 以驗證存取權

首先,建立一個 Access Analyzer 以驗證 S3 Bucket 的存取權。

ANALYZER_ARN=$(aws accessanalyzer create-analyzer \
  --analyzer-name awscookbook109 \
  --type ACCOUNT \
  --output text --query arn)

內容解密:

  • 建立一個名為 awscookbook109 的 Access Analyzer。
  • Analyzer 的型別設定為 ACCOUNT

步驟二:掃描 S3 Bucket 並檢索結果

對您的 S3 Bucket 執行掃描,並檢索 Access Analyzer 的結果。

aws accessanalyzer start-resource-scan \
  --analyzer-arn $ANALYZER_ARN \
  --resource-arn arn:aws:s3:::awscookbook109-$RANDOM_STRING
aws accessanalyzer get-analyzed-resource \
  --analyzer-arn $ANALYZER_ARN \
  --resource-arn arn:aws:s3:::awscookbook109-$RANDOM_STRING

內容解密:

  • 對指定的 S3 Bucket 啟動資源掃描。
  • 檢索掃描結果,以確認 Bucket 是否公開可存取。

設定封鎖公開存取並驗證結果

設定 S3 Bucket 的封鎖公開存取組態,並再次驗證結果。

aws s3api put-public-access-block \
  --bucket awscookbook109-$RANDOM_STRING \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

內容解密:

  • 對指定的 S3 Bucket 設定封鎖公開存取組態。
  • 組態包括封鎖公開 ACL、忽略公開 ACL、封鎖公開政策和限制公開 Bucket。

使用CloudFront安全地從S3提供網頁內容

問題

您在S3中有非公開的網頁內容,希望組態CloudFront來提供這些內容。

解決方案

建立一個CloudFront分配,並將來源設定為您的S3儲存桶。然後,組態一個來源存取身份(OAI),以要求儲存桶只能透過CloudFront存取(參見圖1-12)。

準備工作

  • S3儲存桶中包含靜態網頁內容

步驟

  1. 建立CloudFront OAI:用於在S3儲存桶政策中參照。

    OAI=$(aws cloudfront create-cloud-front-origin-access-identity \
    --cloud-front-origin-access-identity-config \
    CallerReference="awscookbook",Comment="AWSCookbook OAI" \
    --query CloudFrontOriginAccessIdentity.Id --output text)
    
  2. 替換distribution-config-template.json檔案中的值:使用sed命令替換CloudFront OAI和S3儲存桶名稱。

    sed -e "s/CLOUDFRONT_OAI/${OAI}/g" \
    -e "s|S3_BUCKET_NAME|awscookbook110-$RANDOM_STRING|g" \
    distribution-template.json > distribution.json
    
  3. 建立CloudFront分配:使用剛才建立的distribution組態JSON檔案。

    DISTRIBUTION_ID=$(aws cloudfront create-distribution \
    --distribution-config file://distribution.json \
    --query Distribution.Id --output text)
    
  4. 檢查分配狀態:分配需要幾分鐘時間來建立,使用此命令檢查狀態。等待狀態達到“Deployed”。

    aws cloudfront get-distribution --id $DISTRIBUTION_ID \
    --output text --query Distribution.Status
    
  5. 組態S3儲存桶政策:只允許來自CloudFront的請求,使用類別似以下的儲存桶政策。

    {
      "Version": "2012-10-17",
      "Id": "PolicyForCloudFrontPrivateContent",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity CLOUDFRONT_OAI"
          },
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*"
        }
      ]
    }
    
  6. 替換bucket-policy-template.json檔案中的值:使用sed命令替換CloudFront OAI和S3儲存桶名稱。

    sed -e "s/CLOUDFRONT_OAI/${OAI}/g" \
    -e "s|S3_BUCKET_NAME|awscookbook110-$RANDOM_STRING|g" \
    bucket-policy-template.json > bucket-policy.json
    
  7. 應用儲存桶政策:將儲存桶政策應用於包含靜態網頁內容的S3儲存桶。

    aws s3api put-bucket-policy --bucket awscookbook110-$RANDOM_STRING \
    --policy file://bucket-policy.json
    
  8. 取得分配的網域名稱

    DOMAIN_NAME=$(aws cloudfront get-distribution --id $DISTRIBUTION_ID \
    --query Distribution.DomainName --output text)
    

驗證檢查

  • 直接存取S3儲存桶:使用HTTPS直接存取S3儲存桶,驗證儲存桶不直接提供內容。

    curl https://awscookbook110-$RANDOM_STRING.s3.$AWS_REGION.amazonaws.com/index.html
    

    您應該會看到類別似以下的輸出,表明存取被拒絕。

    <?xml version="1.0" encoding="UTF-8"?>
    <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>0AKQD0EFJC9ZHPCC</RequestId><HostId>gfld4qKp9A93G8ee7VPBFrXBZV1HE3jiOb3bNB54fPEPTihit/OyFh7hF2Nu4+Muv6JEc0ebLL4=</HostId></Error>
    
  • 透過CloudFront存取:使用curl觀察您的index.html檔案是否透過CloudFront從私有S3儲存桶提供。

    curl $DOMAIN_NAME
    

    您應該會看到類別似以下的輸出,表明內容已成功透過CloudFront提供。

    AWSCookbook
    

清理

按照本章程式碼倉函式庫中本配方資料夾中的步驟進行清理。

討論

此組態允許您保持S3儲存桶私有,並且只允許CloudFront分配存取儲存桶中的物件。您建立了一個來源存取身份,並定義了一個儲存桶政策,以只允許CloudFront存取您的S3內容。這為您提供了一個堅實的基礎,以保持您的S3儲存桶安全,並具有CloudFront全球CDN的額外保護。

CDN對分散式拒絕服務(DDoS)攻擊的保護是值得注意的,因為對您的內容的終端使用者請求被定向到CloudFront網路上具有最低延遲的存在點。這也保護您免受針對託管在S3儲存桶中的靜態內容的DDoS攻擊的成本,因為從CloudFront提供請求通常比直接從S3提供請求更便宜。

預設情況下,CloudFront在您的分配的預設主機名上附帶一個HTTPS憑證,用於保護流量。使用CloudFront,您可以關聯自定義網域名稱,附加來自Amazon Certificate Manager(ACM)的自定義憑證,從HTTP重定向到HTTPS,強制HTTPS,自定義快取行為,呼叫Lambda函式(Lambda @Edge)等。

挑戰

為您的CloudFront分配新增地理限制。

網路基礎建設

2.0 簡介

許多令人興奮的技術話題,如電腦視覺、物聯網(IoT)和人工智慧聊天機器人等,佔據了頭條新聞。然而,這些新技術的發展離不開可靠且安全的連線作為基礎。資料處理只有在結果能夠可靠地傳遞並在網路上被存取時才有意義。容器是一種極佳的應用程式佈署方法,但當它們能夠彼此連線時,才能為使用者提供最佳體驗。

AWS 中的網路服務和功能是本文所涵蓋的大多數重要服務的骨幹。AWS 提供了許多強大的功能,讓您可以根據需求連線所需的資源。要更好地理解網路,將有助於您更舒適地使用雲端服務。

2.1 在雲端定義您的私有虛擬網路:建立 Amazon VPC

問題

您需要一個網路基礎來託管雲端資源。

解決方案

您將建立一個 Amazon Virtual Private Cloud(VPC),並為其組態一個無類別域間路由(CIDR)區塊,如圖 2-1 所示。

圖 2-1:在一個區域中佈署的 VPC

步驟

  1. 建立 VPC:使用 IPv4 CIDR 區塊建立一個 VPC。這裡我們使用 10.10.0.0/16 作為位址範圍,但您可以根據需求進行修改:

VPC_ID=$(aws ec2 create-vpc –cidr-block 10.10.0.0/16
–tag-specifications ‘ResourceType=vpc,Tags=[{Key=Name,Value=AWSCookbook201}]’
–output text –query Vpc.VpcId)

   建立 VPC 時,檔案指出 VPC IPv4 CIDR 的最大區塊大小是 `/16` 網路遮罩(65,536 個 IP 位址),最小的是 `/28` 網路遮罩(16 個 IP 位址)。

2. **驗證檢查**:使用以下命令驗證 VPC 的狀態是否為 `available`:
   ```bash
aws ec2 describe-vpcs --vpc-ids $VPC_ID

您應該會看到類別似以下的輸出:

{
"Vpcs": [
    {
        "CidrBlock": "10.10.0.0/16",
        "DhcpOptionsId": "dopt-<<snip>>",
        "State": "available",
        "VpcId": "vpc-<<snip>>",
        "OwnerId": "111111111111",
        "InstanceTenancy": "default",
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-<<snip>>",
                "CidrBlock": "10.10.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "IsDefault": false,
        <<snip>>
    }
]
}

清理

按照本章程式碼儲存函式庫中本配方資料夾中的步驟進行清理。

討論

選擇 VPC 的 CIDR 區塊時,有兩個重要的原因需要謹慎:

  • 一旦 CIDR 區塊與 VPC 相關聯,就無法修改(儘管可以擴充套件)。如果您希望修改 CIDR 區塊,則需要刪除它(以及其中的所有資源)並重新建立。
  • 如果 VPC 透過對等連線(見配方 2.11)或閘道(例如,Transit 和 VPN)連線到其他網路,則具有重疊的 IP 範圍將導致不必要的問題。

您可以透過使用 aws ec2 associate-vpc-cidr-block 命令指定額外的 IPv4 空間來將 IPv4 空間新增至 VPC。當 IP 空間因使用和供應不足而變得稀缺時,瞭解您不需要為 VPC 專門分配一個大區塊,尤其是在不確定是否會全部使用的情況下,是很有用的。

以下是將額外的 IPv4 CIDR 區塊與您的 VPC 相關聯的範例:

aws ec2 associate-vpc-cidr-block \
--cidr-block 10.11.0.0/16 \
--vpc-id $VPC_ID

除了 IPv4 之外,VPC 也支援 IPv6。您可以透過指定 --amazon-provided-ipv6-cidr-block 選項來組態 Amazon 提供的 IPv6 CIDR 區塊。以下是建立具有 IPv6 CIDR 區塊的 VPC 的範例:

aws ec2 create-vpc --cidr-block 10.10.0.0/16 \
--amazon-provided-ipv6-cidr-block \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=AWSCookbook201-IPv6}]'

挑戰

使用不同的 CIDR 範圍建立另一個 VPC。

2.2 使用子網路和路由表在 VPC 中建立網路層

問題

您已經有了一個 VPC,需要建立一個由個別 IP 空間組成的網路佈局,以實作分割和冗餘。

解決方案

在您的 VPC 中建立一個路由表。在 VPC 中的不同可用區中建立兩個子網路。將路由表與子網路相關聯(見圖 2-2)。

圖 2-2:隔離的子網路層和路由表

前提條件

  • 一個 VPC

準備工作

按照本章程式碼儲存函式庫中本配方資料夾中的步驟進行準備。

步驟

  1. 建立路由表:這將允許您為與其相關聯的子網路建立自定義的流量路由:
    # 建立路由表的命令範例
    

詳細解說:

此步驟涉及在 AWS 中建立一個路由表,該表將用於定義子網路之間的流量流動規則。首先,您需要在 AWS CLI 中執行命令以建立路由表。假設您已經設定好了 AWS CLI 環境,以下是建立路由表的範例命令:

ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID \
--query 'RouteTable.RouteTableId' --output text)

此命令建立了一個新的路由表,並將其 ID 儲存在 ROUTE_TABLE_ID 變數中。接下來,您可以建立子網路並將它們與此路由表相關聯。

建立子網路的命令如下所示:

SUBNET_ID_1=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.10.1.0/24 \
--availability-zone <<AZ1>> \
--query 'Subnet.SubnetId' --output text)

SUBNET_ID_2=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.10.2.0/24 \
--availability-zone <<AZ2>> \
--query 'Subnet.SubnetId' --output text)

請用適當的可用區名稱替換 <<AZ1>><<AZ2>>

然後,將子網路與路由表相關聯:

aws ec2 associate-route-table --subnet-id $SUBNET_ID_1 --route-table-id $ROUTE_TABLE_ID
aws ec2 associate-route-table --subnet-id $SUBNET_ID_2 --route-table-id $ROUTE_TABLE_ID

#### 內容解密:

  1. 建立路由表:首先,我們需要在 VPC 中建立一個路由表。這是透過 AWS CLI 命令完成的,該命令指定了要在哪個 VPC 中建立路由表。

  2. 建立子網路:接下來,我們在不同的可用區中建立了兩個子網路。這樣做是為了實作冗餘和分割。子網路的 CIDR 區塊應該在 VPC 的 CIDR 範圍內,並且不能重疊。

  3. 將子網路與路由表相關聯:最後,我們將建立的子網路與路由表相關聯。這樣,子網路就可以使用路由表中定義的路由規則來引導流量。

這種設定有助於在 AWS 中實作一個安全且可擴充套件的網路架構。透過使用路由表和子網路,您可以控制流量如何在 VPC 內流動,並實作不同層級的隔離和冗餘。