Nginx configuration does not work - linux

I have created few subdomains for my domain like api.example.com, dev.example.com and www.example.com. For every subdomain I created an virtualhost in Nginx.
But now the problem is when I visit a domain which does not exist it should be redirected to www.example.com. But this is not the exist instead I am getting an error page that the sub domain does not have an secure connection. Since I am using Let's Encrypt, I get this message all the time for sub domains which is incorrect. I contacted my DNS provider and they told me your settings are correct you have to correct your web server configuration. They added a CNAME.
Now I do not know how to add this in my nginx configuration.

So... you type the https ://incorrect.example.com in your browser?
If so, I think the problem cannot be solved.
In the article (https://community.letsencrypt.org/t/can-i-use-letsencrypt-in-more-than-one-subdomain/16588/8) they said
Let's Encrypt does not currently offer "wildcard" certificates. So you will need to be able to list all the domains you want a certificate for, you can't (as you can with some of the pricier paid certificates) get just one that works for every possible name in your domain. With Let's Encrypt you'd need to issue new certificates for any new names you needed.
That showed you can't set all the certificate of incorrect subdomains...
But if you just type "http ://incorrect.example.com", It can be success redirect without error page.
If error page continue occurring, please post your conf of nginx.

I see two separate questions -
security warning can be removed using a wildcard certificate from letsencrypt. Please see detailed instructions here
Redirect non-existent domains to www.domainname.com
You need multiple server sections in place -
Have server {} sections for each existent domain to port 443 (HTTPS port)
Have one server {} section for *.domainname.com to redirect to port 443 or www.domainname.com
If you are running an app that dynamically uses subdomains (for each customer) the app should also implement the redirection to www.domainname.com for non-existent subdomains.

Related

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 deal with naked domains when using azure managed certificates

I'm trying to use the recently announced (in preview) managed certificates for Azure app service. One of the limitations is that you can't get one for naked domains. eg.: you can get one for www.domain.com, but not domain.com.
In my (current) web.config, I'm redirecting from 'naked' to 'www' anyway using rewrite rules, so beeing limited to 'www' is not a real problem. However, as the redirect takes place at the web.config level, that is, after the request has hit the webserver, this is too late: when 'domain.com' gets hit and tries to redirect, the browser has already seen the insecure connection to the naked domain (depending on browser) will display a warning page.
So how is one supposed to do deal with the "naked" domains? No more redirects at all? Or are there other methods to do this besides web.config configurations? I did look, but did not find anything.
Adding to Jack's suggestions.
Currently, the preview offering only supports CNAME based validation. Thanks for the feedback and it is on our list of future improvements to consider however we do not have any ETA on this yet. So, request you to up-vote this feedback post on Uservoice-
https://feedback.azure.com/forums/169385-web-apps/suggestions/38981932-add-naked-domain-support-to-app-service-managed-ce
Alternatively, you may try to forward apex domains to subdomain such as www.
So based on your requirement, to redirect -
https://yourdomain.com -> https://www.yourdomain.com
If you are using App Service Domain, you can forward your domain by going to 'Advanced Management portal' of the domain resource.
So, after a long time, Azure finally supports this. One can simply use a managed cert for naked domains.
See here: https://azure.github.io/AppService/2021/03/02/asmc-apex-domain.html
In this scenario, I think a redirect is necessary.
We can get some clues from other international websites. For example: when I try to access http://google.com, actually I will get a 301 redirect which redirects me to http://www.google.com, and then I will get a 302 redirect which redirects me to https://www.google.com/?gws_rd=ssl
So, as managed certificate does not support naked domain. I suggest you directly add your www subdomain to your web app. And then create managed certificate to that www subdomain.
And, finally, you can add 301 and 302 redirect rules in your DNS provider, which will ensure all requests to naked domain will be redirected to www subdomain. This could be done in your DNS provider before your web app.
So after some time trying things, here's how i ended up dealing with this:
- Using managed domain certificates for all hostname.Domain.tld names
- Using the letsencrypt script (from extensions) to get a cert for the naked domain
Once azure will provide certs for the naked domain, i will retire the script.

Azure - Switch host name for ssl certificate

I have just bought an SSL Certificate for my website from azure. when setting up a certificate under "Naked domain hostname" i entered the domain name WITHOUT "www".
Currently if i were to view my website with https://xyz.ca, it works just fine and it says it is secure, but if enter www.xyz.ca i do not see anything.
To atleast view the website with www.xyz.ca, i have removed HTTPS:// only request. However now this makes website un-secure.
Question
1. what will be the best way to make www.xyz.ca secure using the same certificate that i have bought?
2. if there is any other solution available, that will be fine too.
I am attaching some screenshots to understand better:
In fact a cert CAN support MANY domains. Now, whether this is something that you can add for free with the SSL provider you have chose is a different question. Certificate Subject Alternate Name(s) are what is used for this. For example the cert for this site allows stackexchange.com AND stackoverflow.com and a number of others and sub-domains too.
A valid SSL certificate must match the access FQDN domain name.
One Standard certificate only could be used for one FQDN domain name, such as www.xyz.ca while one WildCard certificate could be used for all like *.xyz.ca FQDN domain name, so usually we use the same WildCard certificate for all different services. More information about SSL Certificate Names
As the comment point it out, instead of buying one via the Azure Portal, you can get a free one via letsencrypt.org
Update
When you purchase an app service certificate in Azure for a root domain, by default, Azure supports hostname as a root domain name and www subdomain. You do not need to purchase another certificate. In this case, you already have two hostnames assigned to the site. You just bind the certificate for each. If you don't see the domain name(s) in the Hostname dropdown, try refreshing the browser page or change another browser.

Redirect https URL to another https URL for the same Azure App Service

This might be a stupid question, and for that I'm sorry, I'm not well-versed in DNS configurations (so perhaps I shouldn't be meddling in this, lol), but anyhow..
I have a web app running in Azure that is currently undergoing a bit of a name change. Therefore, I want to redirect users trying to access my domain to another domain, let's say https://example.com to https://subdomain.anotherexample.com. I own both domains and have certificates for both of them, but I cannot for the life of me understand how (or if its even possible) to redirect users in this way?
I have both URLs configured as A records for the underlying IPv4 adress, and have tried to configure a re-direct in my cPanel to redirect the domain example.com to https://subdomain.anotherexample.com, but if I try to access https://example.com it just complains that the certificate is from another provider (not my Azure certificate, but instead my web hosting certificate used for other sites). Both URLs are set up as custom domains for the same app service in Azure with SNI SSL certificate bindings where example.com is bound to a standard certificate for that specific domain, while subdomain.anotherexample.com is bound to a wildcard certificate for *.anotherexample.com.
I assume there must be something that's not allowed in trying to redirect between two different domains where https is involved because trying to access http://example.com works (i.e. it re-directs to https://subdomain.anotherexample.com). Do I have to write some kind of script server-side that re-directs users manually?

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