AWS环境下CloudFront到LoadBalancer的WordPress 301重定向问题求助
问题描述
访问example.com域名时,会触发301重定向至LoadBalancer地址(loadbalancer.xx.xx.com),但网站应通过原域名提供服务。
基础设施架构
ECS(Dockerfile)(端口80) -> LoadBalancer(端口80) -> CloudFront(端口443) -> example.com
示例重定向场景:
example.com/wp-admin/install.php ->301-> loadbalancer.xx.xx.com/wp-admin/install.php
已尝试的解决方法
- 完全清理.htaccess文件,但无效;
- 在wp-config-docker.php中添加以下配置:
define('WP_HOME', getenv_docker('WP_HOME', ''));
define('WP_SITEURL', getenv_docker('WP_SITEURL', ''));
此时访问example.com会正确重定向至example.com/wp-admin/install.php,但填写安装表单后,再次触发301重定向到LoadBalancer地址:
https://example.com -> http://loadbalancer.xx.xx.com - 检查数据库导出文件file.sql,未发现loadbalancer.xx.xx.com相关条目。
相关代码
使用官方WordPress php8.2/apache版本镜像
ECS任务定义(Terraform)
# ECS Task Definition resource "aws_ecs_task_definition" "woocommerce_task" { depends_on = [ aws_efs_access_point.wp_content ] family = var.task_family network_mode = var.network_mode requires_compatibilities = var.task_compatibilities cpu = var.task_cpu memory = var.task_memory execution_role_arn = aws_iam_role.ecs_execution_role.arn task_role_arn = aws_iam_role.ecs_task_role.arn container_definitions = jsonencode([ { name = var.container_name, image = "${var.ecr_repository_url}:${var.container_image_tag}", # user = "33:33", user = "0:0", essential = true, mountPoints: [{ "sourceVolume": "wp-content", "containerPath": "/var/www/html/" # "containerPath": "/var/www/html/wp-content/" }], environment = [ { name = "WORDPRESS_DB_NAME", value = var.db_name }, { name = "WORDPRESS_DB_HOST", value = "${var.db_host}:3306" }, { name = "WORDPRESS_DB_USER", value = "XXXX" }, { name = "WORDPRESS_DB_PASSWORD", value = "XXXX" }, { name = "TAR_OPTIONS", value = "--no-same-owner" }, # { # name = "WP_HOME", # value = "https://example.com" # }, # { # name = "WP_SITEURL", # value = "https://example.com" # } ], portMappings = [{ containerPort = var.container_port, hostPort = var.container_port, protocol = "tcp" }], logConfiguration = { logDriver = "awslogs", options = { "awslogs-group" = aws_cloudwatch_log_group.ecs_logs.name, "awslogs-region" = var.aws_region, "awslogs-stream-prefix" = "ecs" } } } ]) }
LoadBalancer定义(Terraform)
resource "aws_lb" "nan_lb" { name = var.lb_name internal = false # Set to false if you want to expose the load balancer to the internet. Cloudfront need it. load_balancer_type = "application" security_groups = [aws_security_group.allow_all.id] enable_deletion_protection = false subnets = [var.subnet_a_id, var.subnet_b_id] access_logs { bucket = aws_s3_bucket.lb_logs.id enabled = true } }
CloudFront定义(Terraform)
# CloudFront Distribution Configuration resource "aws_cloudfront_distribution" "cloudfront_dist" { depends_on = [aws_wafv2_web_acl.nan_web_acl] provider = aws.east aliases = [var.domain_name, "www.${var.domain_name}"] http_version = "http2and3" web_acl_id = aws_wafv2_web_acl.nan_web_acl.arn # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PriceClass.html price_class = "PriceClass_100" origin { domain_name = aws_lb.nan_lb.dns_name origin_id = "nan_lb" custom_origin_config { http_port = 80 https_port = 80 origin_protocol_policy = "http-only" origin_ssl_protocols = ["TLSv1.2"] origin_keepalive_timeout = 5 origin_read_timeout = 30 } } enabled = true is_ipv6_enabled = true comment = "CloudFront distribution for nan-woocommerce" default_root_object = "index.php" # default_root_object = "index.html" default_cache_behavior { allowed_methods = ["GET", "HEAD", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"] cached_methods = ["GET", "HEAD", "OPTIONS"] target_origin_id = "nan_lb" compress = true forwarded_values { query_string = true query_string_cache_keys = ["*"] headers = ["Origin"] cookies { forward = "whitelist" whitelisted_names = ["comment_*", "wordpress_*", "wp-settings-*"] } } viewer_protocol_policy = "redirect-to-https" min_ttl = 0 default_ttl = 300 max_ttl = 31536000 } .......... .............. }
问题根源与解决方法
问题根源
- Host头未正确转发:CloudFront默认不会将用户访问的原始
Host头传递给后端LoadBalancer,导致WordPress识别的请求域名是LoadBalancer的地址,进而生成该域名的重定向链接。 - 反向代理配置缺失:WordPress运行在CloudFront和LoadBalancer组成的反向代理之后,未配置识别真实请求的协议与域名,导致用后端地址生成URL。
- 环境变量未启用:wp-config-docker.php中配置了读取WP_HOME和WP_SITEURL环境变量,但ECS任务中未启用这些配置,安装过程中WordPress仍会基于请求Host设置站点地址。
解决步骤
1. 配置CloudFront转发Host头
修改CloudFront的forwarded_values部分,添加Host到转发头列表:
forwarded_values { query_string = true query_string_cache_keys = ["*"] headers = ["Origin", "Host"] # 新增Host头转发 cookies { forward = "whitelist" whitelisted_names = ["comment_*", "wordpress_*", "wp-settings-*"] } }
2. 启用ECS中的WP_HOME和WP_SITEURL环境变量
取消ECS任务定义中WP_HOME和WP_SITEURL的注释:
{ name = "WP_HOME", value = "https://example.com" }, { name = "WP_SITEURL", value = "https://example.com" }
3. 添加反向代理识别配置到wp-config-docker.php
添加以下代码让WordPress识别CloudFront传递的真实请求信息:
// 识别HTTPS协议 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; } // 设置真实请求Host if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; } // 强制后台使用HTTPS define('FORCE_SSL_ADMIN', true);
4. 重新部署并验证
- 应用Terraform配置变更,重新部署ECS任务、CloudFront和LoadBalancer。
- 清空浏览器缓存,重新访问example.com完成安装,验证重定向是否正常。
内容的提问来源于stack exchange,提问作者debek
相关产品推荐
相关产品推荐

