We use CloudFront for non-images CDN. For images CDN, we use Cloudimage.
Distribution Configuration
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
Accept-Encoding(instead, you check “Cache compressed objects” option)- Accept-Language
- Authorization
- Host
- Origin
- Access-Control-Request-Headers (Reference: https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/)
- Access-Control-Request-Method
- 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)
__utm*
_ga
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.
wordpress_*
wp-settings-*
- commenter_*
Query String Forwarding and Caching: All-Except:
utm_source
utm_medium
utm_campaign
utm_term
utm_content
Origin request policy: Managed-AllViewer
Smooth Streaming: No. (only set to Yes if streaming video from S3)
References:
- 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.
WordPress/WooCommerce requires 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 /wp-admin/*
.
WebSocket (and SSL)
CloudFront supports WebSocket by default. However be aware there is a potential issue with nginx-ingress.
AWS WAF
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 AWSManagedRulesCommonRuleSet
and AWSManagedRulesWordPressRuleSet
. But with the default rules you will get:
- 403 Error when accessing /wp-json (weDocs REST API) blocked by
GenericRFI_BODY
- 403 Error when accessing: /wp-admin/post.php?post=7733&action=edit blocked by
SizeRestrictions_BODY
- 403 Error when accessing: /wp-admin/async-upload.php blocked by
SizeRestrictions_BODY
- 403 Error when Publishing WooCommerce product: /wp-admin/post.php blocked by
AWS#AWSManagedRulesCommonRuleSet#CrossSiteScripting_BODY
- 403 Error for Xendit callback
/?xendit_mode=xendit_invoice_callback
blocked byAWS#AWSManagedRulesCommonRuleSet#NoUserAgent_HEADER
- 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
Solution:
- You need to exclude (i.e. “Override rules action”) in
AWS-AWSManagedRulesCommonRuleSet
:GenericRFI_BODY
,SizeRestrictions_BODY
,CrossSiteScripting_BODY
,NoUserAgent_HEADER
,GenericLFI_BODY
, GenericRFI_QUERYARGUMENTS - 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.