Migrating from CloudFlare to AWS

Ryan St. Germain
4 min readDec 4, 2020

Just to have some fun, I decided to migrate my simple WordPress website from CloudFlare to AWS and document my experience. What drew me towards the AWS architecture was the Web Application Firewall (WAF) offering. While CloudFlare does offer a capable solution of their own, it is more geared towards ease and simplicity rather than customization. With AWS you have the ability to create advanced rulesets using regex and have the power to specify where in the web request to enforce these rules. With CloudFlare you are stuck with pre-created rules based on what they deem malicious.

The advanced customization capability is intriguing for people such as myself who create our own intrusion detection/prevention rules. This ability comes in handy when a new vulnerability or attack method is released. If you know the vector you can whip up a rule on your own before the vendors are able to release one. This ability can also come in handy if you simply want to block based on a certain string of text in a specific location within a packet, such as the header or body.

In order to mimic the service provided by CloudFlare, which serves as CDN, DNS and WAF, I utilized multiple offerings from AWS to achieve the same architecture. Below is a diagram of what I ended up implementing.

Service Comparison

Network Design

Using the diagram above, you can visualize the flow of data at which a request to the website takes. When a user makes a request to the server, he or she is provided with an CNAME pointing to my unique CloudFront hostname. When the client hits CloudFront a request is sent to the Application Load Balancer. This request is inspected by the WAF before arriving at the Application Load Balancer (ALB) and the traffic is dropped if any of the rules are hit. Once the request is accepted by the ALB the request is then sent to the EC2 instance, which is communicated with using a private IP address. The EC2 Instance itself is not actually on the internet and does not have a public IP address. A security group is placed on the EC2 instance only allowing traffic from the security group assigned to the ALB and not the ALB IP address itself. This is because a load balancer can change IP’s. Changes will only occur if AWS experiences an outage of some kind.

WAF

From an advanced user standpoint, I really like the AWS WAF. You can configure your own rules using regex. You can also create your own rule orders allowing you to set the order in which packets are inspected. When creating rules there are pre-configured rule conditions. You select a condition, set sub properties for this condition then set the condition match requirements. Condition match requirements allow you to specify where in the packet to inspect for a condition. For example, for a SQL Injection condition you can tell the rule where in the request to look for signs of SQL injection and any form of transformation you would want to perform on this location, such as URL normalization. The complete list of conditions includes SQL Injection, GEO location, XSS, IP address, request size, and string/regex.

In addition to creating your own rules, you can purchase pre-created rules from security vendors. Some of the offerings include rules that cover OWASP top 10, common content management system vulnerabilities and known bot signatures.

Free TLS

In addition to the CDN and WAF capabilities CloudFlare offers, one of my favorite features was the ability to allocate TLS certificates for free. This can also be accomplished on AWS! Using the service called Certificate Manager, you can generate a SSL/TLS certificate for the domain name you are fronting with either CloudFront or an ALB. You have to use one of these to take advantage of this feature, which makes sense because they are considered connection establishment points. In addition to generating certificates, you also have the power to enforce encryption algorithms if you would like. By default, I chose TLSv1.2 because I do not have any legacy requirements that force me to use an older encryption algorithm.

One downside to this offering is that unlike CloudFlare, if you want to encrypt the connection all the way to your server, you must use a legitimate certificate signed by a reputable CA. You cannot use a self-signed certificate. CloudFlare would work its magic and in the background accept the security warning of a self-signed certificate. AWS does not support this and will just error out. Without a certificate on the sever the connection between the ALB and EC2 instance will not be encrypted. You can be the judge of whether the risk associated with this is acceptable. To your visitors the connection is secure because they are seeing the connection between them and CloudFront but in the background the connection between the ALB and EC2 instance is clear-text over port 80. Luckily Lets Encrypt makes obtaining a “trusted” CA signed certificate very easy and free.

--

--