How to enable user custom domains in PHP
Asked Answered
H

3

6

I'm having a system where users can input their purchased domain into their profile, so when accessing their domain, it should replace their custom domain, e.g.

http://domain.com/custom-name to http://purchaseddomain.com.

So when they access their purchase domain, it should take them to their profile including their navigation links, such as links on their page will be replaced with their purchased domain, for example viewing their records would be:

http://domain.com/custom-name/records to http://purchaseddomain.com/records.

Tumblr enables this feature, however I have no idea how this all works:

enter image description here

This is exactly how I like to have a feature like this, I've searched on SO, but it didn't seem to help.

Now this is a problem, I'm not sure how I can validate, confirm and merge their purchased domain into my server without a problem using PHP - I'm using Codeigniter for this.

Is there a solid, stable plugin/library or detailed tutorial that can have the ability to enable custom domains masking a internal domain?

My server is running Ubuntu 11.10 on nginx 1.0.6.

The templating will be just fine for me, which I can do - all I need help on is how to safely accept and merge their domain to my server.


EDIT: Just looked into nginx VirtualHostExample, this looks good overall but how will I be able to dynamically add/remove those domain entries while the domain has an A record pointing to my server?

Hon answered 29/1, 2012 at 21:57 Comment(5)
Generally you'd programmatically generate your URLs in whatever templating setup you're using e.g. instead of <a href="http://foo"> you'd have <a href="{{ domain_url('foo') }}">.Delocalize
Well this would highly depend on your setup and how you create/setup their account, but dns_get_record() may be of use to you.Donica
On apache you would make a virtualhost for the domain & point to the ./custom-name folder plus an A check (backend nslookup)Pilcomayo
@LawrenceCherone Please carefully read my question, I am not using Apache.Hon
@lolwut yeah i know, but there must be similar process for nginx wiki.nginx.org/VirtualHostExamplePilcomayo
N
3

You won't merge their domain to your server.

In fact, when they will register their domains, they will make it point to your server.

On your server configuration, you'll have to dynamically create rules that implicitly redirect the page to the one they created on your server.

So, users will see http://purchaseddomain.com/on-uri but you serve the page http://domain.com/custom-name/one-uri

I.E: it's like if you added on an .htaccess - even if you don't use apache, it's just to explain what the "system" must be:

RewriteCond %{HTTP_HOST} purchaseddomain\.com$ [NC]
RewriteRule (.*) /custom-name/$1
Noelnoelani answered 29/1, 2012 at 22:10 Comment(3)
I'm not using Apache, I'm using nginx, look at my recent edit.Hon
I said " it's like ", i can't do it for you, i just " show you the way " you'll have to make some research. Try to search by yourself how to define rewriterule dynamically.Noelnoelani
maybe try to read this : serverfault.com/questions/332804/nginx-dynamic-virtual-hostsNoelnoelani
B
0

The accepted answer mentions customers pointing their DNS to your web server. But, that's not enough to make it work in this day and age.

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.

If you need more detail you can DM me on Twitter @dragocrnjac

Besom answered 9/10, 2022 at 16:30 Comment(0)
C
-1

This is what is working for me:

server {
    server_name *.mydomain.com
    root        /var/www/$host;

    ...
}

Then you need to make directories like: /var/www/user1.mydomain.com/, /var/www/user2.mydomain.com/, ...

I couldn't figure out how to leave the '.mydomain.com' out of the directory name. If anyone has any idea, pls let me know :)

Causey answered 30/1, 2012 at 9:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.