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)
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
- 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.