Custom domain feature for saas product customers - apache

I have build a saas product with angular 4 integrated with golang rest api and uploaded the build on aws ec2 instance. My project is a multi-tenant based app which loads customers dashboard on merchant-name.mystore.com subdomain but some of the customers asking for custom domain feature like they should be able to load the app on mydomain.com .
I have done the the subdomain part with following code in apache2.conf file so all subdomain loads from apps folder where the angular app files located
<VirtualHost *:80>
ServerAlias *.mystore.com
DocumentRoot /var/www/html/apps
<Directory "/var/www/html/apps">
AllowOverride All
Require all Granted
</Directory>
</VirtualHost>
For custom domain feature I have a section in admin to save custom domain but not sure how should I implement it.
possible method I thought about are
Create virtual host file and update it on each merchant signup with his custom domain
Do it somehow with htaccess file and mod_rewrite
Shopify do it but not sure how they load merchant specific store. Another point kept me busy thinking about is what values should I ask to update
IP address on domain registrar
Name servers ( not sure what it will be for my on aws )
Ask to create CNAME or A record as some of the article suggest

I have a similar setup on a number of SaaS platforms I develop and manage. This type of setup is certainly desirable, as your clients suggest. You should plan to serve each customer site on its own domain, probably also with *SSL, from the begining. In my opinion, this is best practice for a well architected Saas service today.
In reading your question, I think you are over engineering it a little.
For a custom domain Saas app on the same server, you simply open port 80 to all traffic, regardless of domain name. Point all customer domains to app.mystore.com, which is a CNAME to your app endpoint.
The app then reads the HTTP request header, and in that way determines the host name that was requested.
Finally the app looks up the host name in its client database, and locates the client record for the give customer domain.
For example, in Nginx all you need is:
server {
listen 80 default_server;
server_name _;
root /var/www/myservice/htdocs;
}
This server configuration provides a catch all for any domain that points to this endpoint.
That is all the web server should need to allow it to answer to any customer domain. The app must do the rest.
* When you serve a custom domain on an app on this domain, you should plan to serve the SSL endpoint for the domain, eg https://www.mycustomdomain.com. Consider this in your architecture design. Consider also the DNS issues also if your app fails over to a new IP.

The accepted answer is satisfactory but it only skims over the most important part, and that is enabling HTTPS by issuing certificates for third-party domains.
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 Caddy, greenlock.js, OpenResty (Nginx).
tl;dr on what happens here;
Caddy server listens on 443 and 80, receives requests, issues, and renews certificates automatically, and proxies traffic to your backend.
How to handle it on the 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

Related

How to run custom domain under https?

I need some help to develop this solution in my application.
I have a domain https://my-app-api.com with SSL and there is running my application API.
Every customer who using my application can enter their own Custom Domain for example customer-domain.com and points his domain CNAME to my-app-api.com.
Additional info
My API running on Kubernetes cluster and using DigitalOcean services.
Problem
There is a problem with SSL certificates. Custom Domain that points to my-app-api.com runs only under HTTP not HTTPS. Everything must be done automatically over API. If customer enters a new custom domain and points CNAME to my app domain then I need to provide connection over HTTPS.
How can I get it to run on HTTPS?
Is zerossl.com solves that problem for me?
Do I have to use Caddy or smth else?
customer domain --> CNAME --> your api
Is that correct?
your API has SSL.
Is that correct?
customer domain no SSL.
Is that correct?
If all answer is 'yes', the problem is, your customers.
Your customers need an SSL certificate for their domain, your had done all you need to do about SSL (for your API).
Your customers can use a service such as zerossl.com.

Ant-Media-Server + SSL without Domain

Ant-Media-Server is running on an IPAdress without any domains. We just set up this server to be used for streaming in order to use it from different domains pointing to different servers.
Since all of our domains use ssl, we face the typical connection problem:
mixed Content: The page at 'https://SOMEDOMAIN.com/QUERY' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://1.2.3.4:56'. This request has been blocked; this endpoint must be available over WSS.
Ant-Media already offers tutorials on how to install a Let's Encrypt SSL Certificate but sadly it is not available for pure IP-Addresses.
Apart from the Ant-Media Service, the server doesn't has any NGINX, NodeJS, Apache or other http Servers installed - the plan was just to use it for streaming by calling the IP-Address.
Do you have any ideas on how to solve that problem?
Unfortunately, this is not possible.
The goal of having a SSL is ensure you are requesting the right domain name besides encrypting the content between your users and your server.
Here are some alternatives:
create an endpoint in your own app that proxies data to your server.
Instead of playing the IP address, you can play:
/your-proxy-url?stream=http://yourIp.com:port/....
Note that using a proxy will make all the traffic pass through your web app.
As a reference, if you are using PHP on your website, you can have some ideas from here: https://gist.github.com/iovar/9091078
Create a reverse-proxy in front of your web app that redirects the traffic to your IP address.
Both solutions does not change your Ant Media Server, just adds a new resource between your users and your streaming server - adding the SSL on it.

Subdomain working fine with http and not working with https

Recently I have installed ssl certificate on my website. After the ssl certificates have been installed ,I found that my subdomain is not working properly. I will address my subdomain as 'xxxx'and main domain as 'primary'. The main domain works well with http as well as https. Now the subdomain works well with http, but with https://xxxx.primary.com delivers me the main site content and not the content of subdomain. I'm using apache server, linux operating system.
Can anyone please help to solve this issue?
Thanks in advance.
This is how SSL protocol works with the browsers. Whenever browsers receive HTTPS request for domain name, it first checks with the server then delivers the site's content. If a website on server has enabled SSL accessed with HTTPS, browser will try to make secure connection and send request to the server.
In your case, your main website is working properly with HTTP as well as HTTPS and delivers proper content, but your sub-domain is not showing proper content for HTTPS. In order to deliver proper content you should consult with your development team. You can better host your sub-domain on another server or you can protect your sub-domain with valid separate SSL certificate.
Suggestion: If you own multiple sub-domains then it is advisable to use Wildcard SSL, that can protect unlimited number of sub-domains with single certificates. Please note, this unlimited does secure first level (blog.domain.com), doesn't second-third-fourth-etc. level (news.blog.domain.com, 1.news.blog.domain.com or abc.1.news.blog.domain.com).

Manage SSL Certificates for multi-tenant app

I have developed a multi tenant app, using PHP and Apache. By default each client has a free subdomain like customer.app.com. But they can point their custom domain to the application, For this they needs to change the A record of their domain to point to the IP of the app.
One of our users, wants to use his custom ssl certificate, to run the app via https in his custom domain.
My question, is how i can make to allow all customers, can use their custom ssl certificate in their domains.
The only way to make this work is to make an entry into Apache for each subdomain, so it knows what certificate to load. You could make one giant .conf, or you could make one .conf per subdomain. Make sure you're using a version of Apache that supports Server Name Indication (Apache 2.2.12 or later), or you'll have to have an IP per certificate.

How to access localhost via https with a valid certificate

We have a Web-Application that should interact with a desktop application that has a helper tool character (e.g. no setup, no need for admin privileges). The helper is listening via http/https on a simple port bound to localhost.
The Web-Application uses a SSL certificate. Every customer has a machine on its own for his data. For claryfication: The Web-Application is running on a server, serving one customer but multiple people.
The problem is, the Web-Application cannot reach the helper tool via https (using image or iframe). The main issue is, that the local webserver listening on localhost has no signed certificate. So the web browser is blocking the interaction.
Is there any way to get around this trouble? I think, I cannot get a certificate for localhost, because no one would sign it.
I know, that I cannot use XMLHttpRequest for this, but that's not the point.
The goal is to have a customer friendly - no install - just works - solution. The customer should not do ANY configuration. Just downloading and starting the tool. We'd like to have a direct communication to the tool (e.g. no outbound direction to the web server).
Is the any solution for this?
If it is Active-directory environment , you can create your own CA and sign certificates and distribute them across the domain. also you can add to trusted sites through domain policies this way client side you don't need to configure anything .