We use CloudFront for non-images CDN. For images CDN, we use Cloudimage.
Viewer Protocol Policy: Redirect HTTP to HTTPS. This is standard now that even .app domains requires it.
Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. Needed for CORS and REST API.
Create cache policy WordPressCachePolicy. Please ensure you whitelist these headers, otherwise apps will not work correctly:
Accept-Encoding(instead, you check “Cache compressed objects” option)
- Access-Control-Request-Headers (Reference: https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/)
- X-User-Id (used by Rocket.Chat REST API)
- X-Auth-Token (used by Rocket.Chat REST API)
- Check: Cache compressed objects (uses Accept-Encoding header)
Object Caching: Customize.
- Minimum TTL: 1.
- Maximum TTL: 31536000.
- Default TTL: 1 (was 86400). This is to prevent (or mask, duh!) problems caused by app servers not sending proper Cache-Control max-age / Expires header for dynamic responses.
Cache key contents > Cookies > All-Except: (will also need session affinity in Kubernetes nginx-ingress)
Below is a list of cookies that WordPress Core uses. However, other plugins especially WooCommerce, Dokan, etc. may use other cookies. That is why the default recommendation is to use All-Except for cookies cache key.
Query String Forwarding and Caching: All-Except:
Origin request policy: Managed-AllViewer
Smooth Streaming: No. (only set to Yes if streaming video from S3)
- Managing How Long Content Stays in an Edge Cache (Expiration)
- How CloudFront Processes and Caches HTTP 4xx and 5xx Status Codes from Your Origin
WordPress/WooCommerce Configuration & Visual Editor
To reduce chances of getting stuck in WordPress Maintenance Mode (“Briefly unavailable for scheduled maintenance. Check back in a minute.”):
- Go to AWS CloudFront, edit the origin
- Set Origin response timeout to 60 seconds.
Note that you will get stuck anyway if the update operation takes more than 60 seconds. A better way is to use WP CLI.
User-Agent header to be passed by CloudFront in order to enable the visual editor. There are several ways to work-around this, but our best practice is to add additional behavior for path pattern
WebSocket (and SSL)
CloudFront supports WebSocket by default. However be aware there is a potential issue with nginx-ingress.
Someday we will move to StackPath CDN and WAF. However, before that time, configuring AWS WAF is recommended as follows. (Note that the entire managed rule groups below costs $8/mo+WAF costs)
For WordPress/WooCommerce, use
AWSManagedRulesWordPressRuleSet. But with the default rules you will get:
- 403 Error when accessing /wp-json (weDocs REST API) blocked by
- 403 Error when accessing: /wp-admin/post.php?post=7733&action=edit blocked by
- 403 Error when accessing: /wp-admin/async-upload.php blocked by
- 403 Error when Publishing WooCommerce product: /wp-admin/post.php blocked by
- 403 Error for Xendit callback
- 403 Error when accessing: /wp-admin/admin-ajax.php blocked by
AWS-AWSManagedRulesCommonRuleSet > GenericLFI_BODY
- 403 Error when accessing: /wp-login.php?redirect_to=https%3A%2F%2Fprodukindo.com%2Fwp-admin%2F&reauth=1 blocked by AWS-AWSManagedRulesCommonRuleSet > GenericRFI_QUERYARGUMENTS
- You need to exclude (i.e. “Override rules action”) in
- You cannot use AdminProtectionRuleSet because it only has one rule (AWS#AWSManagedRulesAdminProtectionRuleSet#AdminProtection_URIPATH) and blocks WordPress Admin for editing posts.
Some issues with AWS WAF:
- Cost: $1/managed rule and $1/custom rule, plus AWS WAF capacity.
- Only sampling: It’s not possible to view latest blocked requests directly, just sampled requests. Logging can only be enabled by setting up Kinesis.
- Managed rules are opaque. We can’t know why they’re blocking the requests.
- The managed rules seem to be too strict.