How do I enable custom domains for my users?
Asked Answered
X

4

28

I am looking to allow my users to use their own domain name to access my web service.

For example if I have a user with a profile at example.com/users/david how can I allow david to use exampledavid.com to access his profile page.

I don't want the users to see example.com in the address bar, but instead for david to see exampledavid.com.

Xenogenesis answered 29/1, 2016 at 19:14 Comment(13)
when you implement it, may I register user with name "google", I really want to have "google.com"?Happygolucky
@Lashane I'm not trying to register domain names. I want David to be able to use a domain he already owns and point it to his profile page. Services like blogger do this. So yeah, you could register a user with name "google" and you would get example.com/users/google.Xenogenesis
then he needs to point his domain name to your nameserver, do you have one?Happygolucky
@Lashane Yes I do. How do I control where his domain points?Xenogenesis
you cannot control his domain, depending on registar client should make different changesHappygolucky
@Lashane If he points his domain to my DNS, can't I control how his domain resolves when it hits my server?Xenogenesis
you can, but client should first point it somehow, and this somehow depends on original registratorHappygolucky
I Have modified your question to better explain what it is you are seeking. If you feel I have not explained it properly, or missed anything please feel free to roll it back.Kilah
What do you have on the server side? otherwise the answer give to you will have to be very "generic"... a little code example would be better dont you think?Oestrin
@hwd Please look into my answer & let me know if you still need any clarification.Grampus
I wonder how much you're going to spend on SSL certificates for each user domain nameKanaka
@Xenogenesis 4 years later am sure you solved this. what was your process?Philoprogenitive
@Philoprogenitive when I don't need to automate things I manually configure using CNAME and virtual hosts. When I do need to automate things, I use Apache Rewrite Maps httpd.apache.org/docs/2.4/rewrite/rewritemap.htmlXenogenesis
G
5

Your issue can be solved with URL rewrite and HTTP Header manipulation or reverse-proxy.

  • For apache http server: use ProxyPassReverse directive

The directive ProxyPassReverse lets Apache adjust the URL in the Location header on HTTP redirect responses. For instance this is essential when Apache is used as a reverse proxy to avoid by-passing the reverse proxy because of HTTP redirects on the backend servers which stay behind the reverse proxy.

Suppose the local server has address http://wibble.org/; then

ProxyPass /mirror/foo/ http://foo.com/
ProxyPassReverse /mirror/foo/ http://foo.com/

will not only cause a local request for the http://wibble.org/mirror/foo/bar to be internally converted into a proxy request to http://foo.com/bar (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client.

  • For MS(R) IIS use Re-Write Module:

Easily replace Web application URLs to produce user and search engine >friendly results. URL Rewrite permits Web administrators to easily replace the URLs >generated by a Web application in the response HTML with a more user friendly and search engine friendly equivalent. Links can be modified in the HTML markup generated by a Web application behind a reverse proxy. URL Rewrite makes things easier for outbound response content and headers rewriting with outbound rewrite rules that work with HTTP request and response headers and with IIS server variables.

Additionaly, you must make sure that exampledavid(dot)com is setup with DNS provider to pass all requests to example.com.

DNS Record Sample:

NAME                    TYPE   VALUE
--------------------------------------------------
exampleXYZ.com.         CNAME  example.com.
example.com.            A      192.0.2.23

Ref:

  1. https://en.wikipedia.org/wiki/CNAME_record

  2. http://www.akadia.com/services/apache_redirect.html

  3. http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

  4. http://www.iis.net/downloads/microsoft/url-rewrite

Grampus answered 8/2, 2016 at 18:39 Comment(2)
Do you feel that this would be an effective method given a system with hundreds of users with their own domains?Xenogenesis
As exampledavid.com is not a subdomain of example.com and .com is Top Level Domain so you have no other choice, AFAIK.Grampus
A
34

I see decent answers but no one here is giving 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

Ainslie answered 27/11, 2020 at 17:4 Comment(0)
K
5

You can easily enable this by telling your clients to configure a CNAME to point to your domain.

So if your server is located at www.example.com you tell 'david' to configure www.exampledavid.com to have a CNAME record pointing to www.example.com

At the server end you would have a configuration that detected the domain that was being requested and redirected and served the appropriate content to 'david'

If your clients want to use the naked domain i.e. exampledavid.com to your servers, you would need to provide them with an IP address, however before doing this you would need to be sure that your IP address wasn't going to change, and probably have a contract with whoever supplies it to ensure that.

Kilah answered 2/2, 2016 at 10:4 Comment(2)
I'm interested in what needs to happen on my server end. Can you give any specifics or examples of the "configuration" that I will need to detect and redirect the domain?Xenogenesis
That would very much depend on the software you are using, and there would be multiple ways of achieving the same depending on your configuration. It would probably be worth asking that as a separate question once you have a little understanding of what you need.Kilah
G
5

Your issue can be solved with URL rewrite and HTTP Header manipulation or reverse-proxy.

  • For apache http server: use ProxyPassReverse directive

The directive ProxyPassReverse lets Apache adjust the URL in the Location header on HTTP redirect responses. For instance this is essential when Apache is used as a reverse proxy to avoid by-passing the reverse proxy because of HTTP redirects on the backend servers which stay behind the reverse proxy.

Suppose the local server has address http://wibble.org/; then

ProxyPass /mirror/foo/ http://foo.com/
ProxyPassReverse /mirror/foo/ http://foo.com/

will not only cause a local request for the http://wibble.org/mirror/foo/bar to be internally converted into a proxy request to http://foo.com/bar (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client.

  • For MS(R) IIS use Re-Write Module:

Easily replace Web application URLs to produce user and search engine >friendly results. URL Rewrite permits Web administrators to easily replace the URLs >generated by a Web application in the response HTML with a more user friendly and search engine friendly equivalent. Links can be modified in the HTML markup generated by a Web application behind a reverse proxy. URL Rewrite makes things easier for outbound response content and headers rewriting with outbound rewrite rules that work with HTTP request and response headers and with IIS server variables.

Additionaly, you must make sure that exampledavid(dot)com is setup with DNS provider to pass all requests to example.com.

DNS Record Sample:

NAME                    TYPE   VALUE
--------------------------------------------------
exampleXYZ.com.         CNAME  example.com.
example.com.            A      192.0.2.23

Ref:

  1. https://en.wikipedia.org/wiki/CNAME_record

  2. http://www.akadia.com/services/apache_redirect.html

  3. http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

  4. http://www.iis.net/downloads/microsoft/url-rewrite

Grampus answered 8/2, 2016 at 18:39 Comment(2)
Do you feel that this would be an effective method given a system with hundreds of users with their own domains?Xenogenesis
As exampledavid.com is not a subdomain of example.com and .com is Top Level Domain so you have no other choice, AFAIK.Grampus
G
1

Hope this is still helpful in 2024.

I found 2 ways to work with this:

  1. If you are using Monolithic approach where all traffic will come to single or fleet of servers, you can use Cloudflare for SaaS and manage thousands of domains (0.1$ per domain) without lifting a finger.

  2. If you are going to use serverless architecture. You can use AWS Application load balancer with ACM. Only issue is you need to reach out to AwS support and ask for more quota as you grow. This is cheaper compared to cloudflare for SaaS but more complex to setup. With limitations based on the support from AWS.

  3. Build eveything yourself. Use Let's encrypt to get ssl certificate and keep adding Vhost entries as needed. Not sure how many Vhost can be supported by Apache but this works for quite large number without incurring any additional cost.

  4. There can be more complex and easy solutions but this is what I found to be working for me.

Greatgranduncle answered 3/3 at 18:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.