Serving HTTPS with Cloudfront but backing HTTP orgin - amazon-cloudfront

I have a Wordpress server running on EC2 and currently it's only running HTTP and I'd rather avoid the hassle of setting up SSL on it. What I'm hoping is that I can co-opt Cloudfront to serve all requests to clients using HTTPS (using an AWS Certificate Managed SSL cert) and then refresh it's cache with HTTP calls to the origin server. This type of configuration is quite straight forward with Cloudflare but it's more of a reverse-proxy than a traditional CDN. Is this a reasonable architecture for Cloudfront?
I had originally thought that the "Behavior" for Viewer Protocol Policy could be set to "Redirect HTTP to HTTPS" but at least initially I appear to be getting the page to load over HTTPS but all assets on the page fail to load because they're still pointed to HTTP. Possibly this a different issue but I'm having an issue grokking it all.
Just for reference, here's my Behaviors dashboard:
And my origin:

You can do it via Origin Protocol Policy option in AWS Console. Select HTTP Only.
To do this select your Cloudfront configuration > choose Origins and Origin Groups tab > Choose your origin > Click Edit button
Remember that you are doing changes for Origin. You have to keep Viewer Protocol Policy to Redirect HTTP to HTTPS as indicated in the question so that traffic between browser and Cloudfront remains HTTPS whereas Cloudfront connects to your Origin via HTTP
Edit: Question description does show that origin is set to HTTP Only which should be enough to do it. Double check if your distribution is in Deployed state.

After setting up CloudFront to deal with HTTPS, you also need to configure WordPress so it generates all the links and asset sources with HTTPS. You can follow the documentation for that.
In short:
Go to Settings -> General
Change http:// to https:// in WordPress Address (URL) and Site Address (URL).

Related

HTTP to HTTPS redirect for azure apim gateway url

I want to force HTTPS on the gateway url of the Azure API Management services but there are no configuration settings for that.
By default, HTTPS is used by the browser but when I change it manually in the URL and switch to HTTP, I don't have a redirection to HTTPS which is what I'm looking for.
I see this as a feedback request : https://feedback.azure.com/forums/248703-api-management/suggestions/37192618-block-http-and-or-force-https .
You may want to vote for it if it aligns with your requirement.
However, it is under review now and as workaround it is mentioned to use a policy at the global scope to check protocol and return a redirect if it’s http.

Naked domain in Azure CDN endpoint has wrong HTTPS certificate name

I have a site in Azure. Pages are generated by Azure Functions, but for a given URL generated page will always be identical, so I put it behind a CDN endpoint. I added custom domains to the endpoint: www.example.com is the main domain and there is also a naked domain version example.com, but any request to it is redirected to the www.example.com. Any http requests are also redirected to https. Both redirects are performed by returning redirect result from Azure Function.
So, both http://example.com and http://www.example.com properly redirected to https://www.example.com. The problem arises if someone tries to access https://example.com. The certificate served for this url is *.azureedge.net and the browser predictably displays a warning message (if instructed to proceed - it receives a redirect and works fine after that).
When I try to enable Custom HTTPS on example.com - I get an error Enabling Https with CDN Managed Certificate is not supported anymore for apex (root) domains.
Is there any way I can fix this, perhaps instruct a redirect from example.com to www.example.com on DNS level? I've seen suggestions to use alternative CDNs available in Azure, but I'm not ready to go down that route yet.
As you've discovered, as of April 2021 Managed certificates are not supported on Apex domains. The only supported way to get round this at present is to upload your own certificate (either free or purchased) or purchase one through KeyVault.
Having said that, Jack Tracey has put together a list of instructions to achieve this in an unsupported manner.

How to completely force https only for website including for requests outside a browser?

We have an azure website, where we have the https only setting turned on, and we also have url rewrite rules set up as well so that when you go to our site at http://example.com (we have a custom domain that is secured with a cert using IP SSL - both example.com and www.example.com), you get redirected to https://example.com. When using a web browser, this clearly works. However, when using a tool such as Postman or vulnerability scanning, such as ZAP, the server is clearly responding to http and not redirecting the request to https. We are currently failing a vulnerability scan due to this, and we cannot figure out what else to do to get the site to force https. As I said, it works when using a web browser, but not with direct web requests from non-browser tools. Thanks!

SSL Certificate Not Working for my Azure App Service

I choose to host my website in Azure.So I've created a App Service.Then Created a new domain for my App then created/bind the SSL certificate to my corresponding website.
After done with the SSL certificate .I'm still seeing my website url as http//: and not https://
Also i'm not seeing the Green URL for my Website ..!
It look like this
(P.s : My App Service Tier is AzureFreeTier (Basic: 1 Small)
My SSL Type is SNL SSL)
Please help to resolve my problem here
Thanks in Advance,
Jayendran
You need to do a redirect from HTTP to HTTPS. Installing a certificate just makes using HTTPS with your custom domain name possible.
You can either:
Configure your app to redirect to HTTPS when it receives a request over HTTP + enable HTTP Strict Transport Security
Or use an extension in Web Apps to do the first thing:
To install the extension, open your web app blade in Azure Portal. Go to Extensions, then click Add. Then you should find Redirect HTTP to HTTPS from the list and install it.
That will redirect any HTTP calls to HTTPS for you. I would still recommend adding Strict-Transport-Security headers to your responses to make sure your clients do not access your site insecurely the next time.
The reason you arrive to your site on HTTPS after AAD login is because the HTTPS version of your app's URL has been configured in AAD as the reply URL.
And this:
Your Connection to this site is not fully secure Attackers might be able to see the images
is a mixed content warning. It means you are loading content (e.g. images) using an HTTP URL in your pages. Change them to HTTPS and you will solve that problem.

How to serve custom domains pointing to a subdomain in Saas App

I want to create an example SaaS app, whereby users are able to signup, create web pages, use templates and/or customize them with custom css, serve their web pages off custom domains.
I was considering saving the templates on S3/other CDNs, along with media/stylesheets/js files. While all are technically possible (practical? that could be debatable). Anyways, I was having a hard time figuring out how websites would be served off custom domains in this case? For instance, when they sign up, they could get a subdomain.domain.com address. However, how do they point customerdomain.com so that when customerdomain.com is entered, it serves same content as customerdomain.domain.com, and URL remains customerdomain.com
Additionally, if I want to have a "feature" whereby, custom domains could be a paid feature. How would I restrict it to paid users only?
Normally when, we setup websites, we specify it in virtual host config file (apache), and give it aliases, so it looks for and serves those aliases. In this case, I do not want to have a separate vhost file for each person who signs up. Is there an alternative? How can I program this? Are there any gotchas to be aware of?
One solution that I have seen is to have the server serve a wildcard domain i.e *.domain.com, and a separate vhost for each custom domain, however I would prefer to avoid if I can.
Thanks.
The custom domain is usually done through a CNAME DNS record (sort of a symlink for DNS records). You tell your customer (who is usually in control of customerdomain.com) to create a CNAME record saying that customerdomain.com is an alias for customerdomain.domain.com. Then you need to set up your own server to interpret requests to customerdomain.com the same as it would treat requests to customerdomain.domain.com.
Depending on how you serve your subdomains, this can be done in a few different ways.
If you have a vhost file for every single customer, you need to add a "ServerAlias" directive for the custom domain your client has provided.
If you are coding the entry point through your own application server (say, reading the "Host" HTTP header from PHP and then setting the customer name from that) then you need to adjust that code accordingly to interpret requests for external domains according to your own database of custom domains. You can even use straight DNS for this!
Something on the lines of:
if http "host" header does not end in domain.com:
cname = get_cname_record(http "host" header value)
if cname does not end in domain.com:
return error 404
else:
site = first part of cname
else:
site = first part of http "host" header
Then you can use DNS as your "custom domain database". Make sure you are using a DNS cache though, as those queries will be performed on every single request.
The accepted answer is good but it doesn't show the full picture.
If your customers just CNAME to your domain or create the A record to your IP and you don't handle TLS termination for these custom domains, your app will not support HTTPS, and without it, your app won't work in modern browsers on these custom domains.
You need to set up a TLS termination reverse proxy in front of your webserver. This proxy can be run on a separate machine but you can run it on the same machine as the webserver.
CNAME vs A record
If your customers want to have your app on their subdomain, e.g. app.customer.com they can create a CNAME app.customer.com pointing to your proxy.
If they want to have your app on their root domain, e.g. customer.com then they'll have to create an A record on customer.com pointing to your proxy's IP. Make sure this IP doesn't change, ever!
How to handle TLS termination?
To make TLS termination work, you'll have to issue TLS certificates for these custom domains. You can use Let's Encrypt for that. Your proxy will see the Host header of the incoming request, e.g. app.customer1.com or customer2.com etc., and then it will decide which TLS certificate to use by checking the SNI.
The proxy can be set up to automatically issue and renew certificates for these custom domains. On the first request from a new custom domain, the proxy will see it doesn't have the appropriate certificate. It will ask Let's Encrypt for a new certificate. Let's Encrypt will first issue a challenge to see if you manage the domain, and since the customer already created a CNAME or A record pointing to your proxy, that tells Let's Encrypt you indeed manage the domain, and it will let you issue a certificate for it.
To issue and renew certificates automatically, I'd recommend using Caddyserver, greenlock.js, OpenResty (Nginx).
tl;dr on what happens here;
Caddyserver listens on 443 and 80, it receives requests, issues, and renews certificates automatically, proxies traffic to your backend.
How to handle it on my backend
Your proxy is terminating TLS and proxying requests to your backend. However, your backend doesn't know who is the original customer behind the request. This is why you need to tell your proxy to include additional headers in proxied requests to identify the customer. Just add X-Serve-For: app.customer.com or X-Serve-For: customer2.com or whatever the Host header is of the original request.
Now when you receive the proxied request on the backend, you can read this custom header and you know who is the customer behind the request. You can implement your logic based on that, show data belonging to this customer, etc.
More
Put a load balancer in front of your fleet of proxies for higher availability. You'll also have to use distributed storage for certificates and Let's Encrypt challenges. Use AWS ECS or EBS for automated recovery if something fails, otherwise, you may be waking up in the middle of the night restarting machines, or your proxy manually.
Alternatively, there have been a few services like this recently that allow you to add custom domains to your app without running the infrastructure yourself.
If you need more detail you can DM me on Twitter #dragocrnjac

Resources