在網路安全日益重要的今天,將 HTTP 流量重新導向至 HTTPS 已成為網站佈署的標準實務。透過應用程式負載平衡器(ALB),我們可以輕鬆地將所有 HTTP 請求重新導向至 HTTPS,有效提升網站安全性,保護使用者資料。本文將逐步說明如何使用 AWS CLI 設定 ALB,實作 HTTP 到 HTTPS 的自動重新導向。首先,建立安全群組允許 80 和 443 埠的流量,接著建立 ALB 並設定 HTTP 和 HTTPS 監聽器。建立目標群組並將後端應用程式例項註冊到目標群組中,確保流量能正確導向。最後,設定 HTTP 監聽器的重新導向規則,將所有 HTTP 請求(80 埠)重新導向至 HTTPS(443 埠)。

使用應用程式負載平衡器重新導向 HTTP 流量至 HTTPS

問題

您的容器化應用程式執行在私有子網路中,網際網路上的使用者需要存取該應用程式。為了提高安全性,您希望將所有從 HTTP 發出的請求重新導向至 HTTPS。

解決方案

建立一個應用程式負載平衡器(ALB)。接下來,在 ALB 上建立針對 80 和 443 連線埠的監聽器,以及針對您的容器化應用程式的目標群組,並設定監聽器規則,如圖 2-9 所示。最後,設定一個動作,使用 HTTP 301 回應程式碼將連線埠 80(HTTP)的流量重新導向至連線埠 443(HTTPS),同時保留請求中的 URL(見圖 2-10)。

準備工作

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

步驟

  1. 建立一個新的私鑰,用於憑證:
openssl genrsa 2048 > my-private-key.pem

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

Generating RSA private key, 2048 bit long modulus
................................................................+++
.........................................................................+++
e is 65537 (0x10001)

內容解密:

這段指令用於產生一個2048位元的RSA私鑰,並將其儲存到名為my-private-key.pem的檔案中。私鑰是SSL/TLS憑證的重要組成部分,用於加密和解密資料。

  1. 使用 OpenSSL CLI 產生自簽憑證:
openssl req -new -x509 -nodes -sha256 -days 365 \
-key my-private-key.pem -outform PEM -out my-certificate.pem

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

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
---
--
Country Name (2 letter code) []:US
State or Province Name (full name) []:Pennsylvania
Locality Name (eg, city) []:Scranton
Organization Name (eg, company) []:AWS Cookbook Inc
Organizational Unit Name (eg, section) []:Cloud Team
Common Name (eg, fully qualified host name) []:mytest.com
Email Address []:you@youremail.com

內容解密:

這段指令用於產生一個自簽的X.509憑證,有效期為365天。過程中會提示輸入一些識別資訊,如國家程式碼、省市名稱、組織名稱等,這些資訊將被納入憑證中。自簽憑證在大多數瀏覽器中會被視為不安全,因此在生產環境中建議使用由受信任的憑證授權單位頒發的憑證。

  1. 將產生的憑證上傳至 IAM:
CERT_ARN=$(aws iam upload-server-certificate \
--server-certificate-name AWSCookbook207 \
--certificate-body file://my-certificate.pem \
--private-key file://my-private-key.pem \
--query ServerCertificateMetadata.Arn --output text)

內容解密:

這段指令用於將之前產生的憑證和私鑰上傳至AWS Identity and Access Management(IAM)。CERT_ARN變數將儲存上傳憑證的ARN,用於後續的ALB組態。

討論

本配方演示瞭如何使用應用程式負載平衡器(ALB)將HTTP流量重新導向至HTTPS,以提高應用程式的安全性。透過組態ALB的監聽器和規則,可以實作流量的無縫重新導向,同時保留原始請求的URL。

挑戰

嘗試在您的VPC中新增一個網際網路閘道,並測試從一個執行個體對該閘道的存取。

使用應用程式負載平衡器(ALB)將HTTP流量重新導向至HTTPS的技術

在現代的雲端架構中,確保應用程式的安全性和可存取性至關重要。其中一個關鍵步驟是組態應用程式負載平衡器(Application Load Balancer, ALB)以將HTTP流量重新導向至HTTPS,從而保障資料傳輸的安全。本文將詳細介紹如何使用AWS CLI命令來實作這一目標。

建立安全群組(Security Group)

首先,我們需要為ALB建立一個安全群組,並新增允許HTTP和HTTPS流量的規則。

ALB_SG_ID=$(aws ec2 create-security-group --group-name Cookbook207SG \
--description "ALB Security Group" --vpc-id $VPC_ID \
--output text --query GroupId)

內容解密:

  • aws ec2 create-security-group:此命令用於建立一個新的安全群組。
  • --group-name Cookbook207SG:指定安全群組的名稱。
  • --description "ALB Security Group":提供安全群組的描述。
  • --vpc-id $VPC_ID:指定安全群組所屬的VPC ID。
  • --output text --query GroupId:輸出新建立的安全群組ID。

接著,新增允許HTTP和HTTPS流量的規則:

aws ec2 authorize-security-group-ingress \
--protocol tcp --port 443 \
--cidr '0.0.0.0/0' \
--group-id $ALB_SG_ID

aws ec2 authorize-security-group-ingress \
--protocol tcp --port 80 \
--cidr '0.0.0.0/0' \
--group-id $ALB_SG_ID

內容解密:

  • aws ec2 authorize-security-group-ingress:此命令用於授權安全群組的入站規則。
  • --protocol tcp --port 443--protocol tcp --port 80:分別允許TCP協定的443(HTTPS)和80(HTTP)埠流量。
  • --cidr '0.0.0.0/0':允許來自任何IPv4地址的流量。
  • --group-id $ALB_SG_ID:指定要修改的安全群組ID。

建立應用程式負載平衡器(ALB)

LOAD_BALANCER_ARN=$(aws elbv2 create-load-balancer \
--name aws-cookbook207-alb \
--subnets $VPC_PUBLIC_SUBNETS --security-groups $ALB_SG_ID \
--scheme internet-facing \
--output text --query LoadBalancers[0].LoadBalancerArn)

內容解密:

  • aws elbv2 create-load-balancer:建立一個新的應用程式負載平衡器。
  • --name aws-cookbook207-alb:指定ALB的名稱。
  • --subnets $VPC_PUBLIC_SUBNETS:指定ALB所屬的子網。
  • --security-groups $ALB_SG_ID:指定ALB所使用的安全群組。
  • --scheme internet-facing:設定ALB為導向網際網路。

建立目標群組(Target Group)並註冊目標

TARGET_GROUP=$(aws elbv2 create-target-group \
--name aws-cookbook207-tg --vpc-id $VPC_ID \
--protocol HTTP --port 80 --target-type ip \
--query "TargetGroups[0].TargetGroupArn" \
--output text)

TASK_ARN=$(aws ecs list-tasks --cluster $ECS_CLUSTER_NAME \
--output text --query taskArns)

CONTAINER_IP=$(aws ecs describe-tasks --cluster $ECS_CLUSTER_NAME \
--task $TASK_ARN --output text \
--query tasks[0].attachments[0].details[4] | cut -f 2)

aws elbv2 register-targets --targets Id=$CONTAINER_IP \
--target-group-arn $TARGET_GROUP

內容解密:

  • aws elbv2 create-target-group:建立一個新的目標群組。
  • aws ecs list-tasksaws ecs describe-tasks:用於取得容器例項的IP。
  • aws elbv2 register-targets:將容器例項註冊到目標群組。

組態HTTPS監聽器和重新導向規則

HTTPS_LISTENER_ARN=$(aws elbv2 create-listener \
--load-balancer-arn $LOAD_BALANCER_ARN \
--protocol HTTPS --port 443 \
--certificates CertificateArn=$CERT_ARN \
--default-actions Type=forward,TargetGroupArn=$TARGET_GROUP \
--output text --query Listeners[0].ListenerArn)

aws elbv2 create-rule \
--listener-arn $HTTPS_LISTENER_ARN \
--priority 10 \
--conditions '{"Field":"path-pattern","PathPatternConfig":{"Values":["/*"]}}' \
--actions Type=forward,TargetGroupArn=$TARGET_GROUP

aws elbv2 create-listener --load-balancer-arn $LOAD_BALANCER_ARN \
--protocol HTTP --port 80 \
--default-actions \
"Type=redirect,RedirectConfig={Protocol=HTTPS,Port=443,Host='#{host}',Query='#{query}',Path='/#{path}',StatusCode=HTTP_301}"

內容解密:

  • aws elbv2 create-listener:建立一個新的監聽器。
  • --protocol HTTPS--protocol HTTP:分別設定HTTPS和HTTP監聽器。
  • RedirectConfig:組態HTTP到HTTPS的重新導向規則。

驗證目標健康狀態和測試ALB

aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP \
--query TargetHealthDescriptions[*].TargetHealth.State

LOAD_BALANCER_DNS=$(aws elbv2 describe-load-balancers \
--names aws-cookbook207-alb \
--output text --query LoadBalancers[0].DNSName)

echo $LOAD_BALANCER_DNS

curl -v http://$LOAD_BALANCER_DNS
curl -vkL http://$LOAD_BALANCER_DNS

內容解密:

  • aws elbv2 describe-target-health:檢查目標群組中目標的健康狀態。
  • curl 命令:測試HTTP到HTTPS的重新導向是否正常工作。

使用Prefix Lists簡化安全群組中CIDR的管理

問題描述

您在公有子網中託管了兩個應用程式,分別執行在不同的EC2例項上,並有特定的存取需求。通常情況下,這些應用程式需要從另一個區域的虛擬桌面存取。然而,在測試期間,您需要暫時允許從家用電腦存取這些應用程式。

解決方案

利用AWS提供的IP位址範圍清單,建立一個受管理的Prefix List,其中包含us-west-2區域中WorkSpaces閘道的CIDR範圍,並將其與每個安全群組關聯。在測試期間更新Prefix List,加入您家用電腦的IP位址,測試完成後再將其移除(如圖2-11所示)。

準備工作

  • 具備公有子網的VPC,分佈在兩個可用區域,並有關聯的路由表。
  • 在每個公有子網中有兩個執行個體(EC2 instances),並在80埠上執行Web伺服器。
  • 兩個安全群組,分別與兩個EC2例項相關聯。

步驟

  1. 下載AWS IP位址範圍JSON檔案

    curl -o ip-ranges.json https://ip-ranges.amazonaws.com/ip-ranges.json
    

    如果您的工作站尚未安裝jq工具,請先安裝,例如使用brew install jq

  2. 產生us-west-2區域中Amazon WorkSpaces閘道的CIDR範圍清單

    jq -r '.prefixes[] | select(.region=="us-west-2") | select(.service=="WORKSPACES_GATEWAYS") | .ip_prefix' < ip-ranges.json
    
  3. 使用來自ip-ranges.json的Amazon WorkSpaces IP範圍建立受管理的Prefix List

    PREFIX_LIST_ID=$(aws ec2 create-managed-prefix-list \
    --address-family IPv4 \
    --max-entries 15 \
    --prefix-list-name allowed-us-east-1-cidrs \
    --output text --query "PrefixList.PrefixListId" \
    --entries Cidr=44.234.54.0/23,Description=workspaces-us-west-2-cidr1 Cidr=54.244.46.0/23,Description=workspaces-us-west-2-cidr2)
    

    目前您的工作站無法存取任何一個例項。嘗試以下命令將會收到“Connection timed out”錯誤:

    curl -m 2 $INSTANCE_IP_1
    curl -m 2 $INSTANCE_IP_2
    
  4. 取得您工作站的公有IPv4位址

    MY_IP_4=$(curl myip4.com | tr -d ' ')
    
  5. 更新您的受管理Prefix List並加入您工作站的公有IPv4位址(如圖2-12所示):

    aws ec2 modify-managed-prefix-list \
    --prefix-list-id $PREFIX_LIST_ID \
    --current-version 1 \
    --add-entries Cidr=${MY_IP_4}/32,Description=my-workstation-ip
    
  6. 為每個應用程式的安全群組新增入站規則,允許來自Prefix List的TCP 80埠存取

    aws ec2 authorize-security-group-ingress \
    --group-id $INSTANCE_SG_1 --ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,PrefixListIds="[{Description=http-from-prefix-list,PrefixListId=$PREFIX_LIST_ID}]"
    
    aws ec2 authorize-security-group-ingress \
    --group-id $INSTANCE_SG_2 --ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,PrefixListIds="[{Description=http-from-prefix-list,PrefixListId=$PREFIX_LIST_ID}]"
    

驗證檢查

從您的工作站測試對兩個例項的存取:

curl -m 2 $INSTANCE_IP_1
curl -m 2 $INSTANCE_IP_2

清理

請參照本章節程式碼倉函式庫中的清理步驟進行操作。

討論

使用Prefix List可以簡化對多個安全群組中CIDR的管理。當需要更新允許進入例項的CIDR區塊清單時,您只需更新Prefix List,而不必逐一修改相關的安全群組。這大大減少了維護工作量。此外,Prefix List還可以用於出口安全群組授權、與路由表關聯,以及實施流量黑洞(blackholing)等場景。它們還提供了一個強大的版本控制機制,允許您快速回復到先前已知的工作狀態。

Prefix List版本控制範例

首先,描述Prefix List以取得目前的版本號:

aws ec2 describe-prefix-lists --prefix-list-ids $PREFIX_LIST_ID

挑戰

還原Prefix List的有效版本,以移除您的工作站IP,使您無法再存取任一應用程式。(提示:參見程式碼倉函式庫中的相關步驟。)

相關主題:使用VPC端點控制從VPC到S3的網路存取

問題描述

您的VPC內的資源應該只能存取特定的S3儲存桶。出於安全性和降低頻寬成本的考慮,這些S3流量不應透過網際網路傳輸。