cjke7777
By:
cjke7777

Can domain records exist in both the original registrar and also in Digital Oceans network pane?

February 6, 2017 719 views
Networking DNS

I have a client that wants to maintain control of his domain (fair enough) - he also wants to maintain control of his MX records (fair enough). He is with CrazyDomains and the current records kind of look like this:

Before
CrazyDomains:

  • A Name: @ 111.222.333.444
  • MX: 1ASPMX.L.GOOGLE.COM
  • MX: 2ASPMX.L.GOOGLE.COM
  • DS: ns1.crazydomains.com
  • DS: ns2.crazydomains.com

After
CrazyDomains:

  • MX: 1ASPMX.L.GOOGLE.COM
  • MX: 2ASPMX.L.GOOGLE.COM
  • DS: ns1.crazydomains.com (for MX records)
  • DS: ns2.crazydomains.com ( "" )
  • DS: ns1.digitalocean.com. (for AName records)
  • DS: ns2.digitalocean.com. ( "" )

DO:

  • A Name: @ 666.777.888.999

Essentially I can maintain the A Name records (via DO) and he can maintain the MX records (via CrazyDomain)

6 Answers
jtittle February 7, 2017
Accepted Answer

@cjke7777

NGINX can work as a load balancer and/or a proxy, which is the beauty of it all :-).

For the purpose of this example, let's say we have 3 clients we need to manage (i.e. host their sites).

clientdomain01.com
clientdomain02.com
clientdomain03.com

Also for the purpose of this example, I'll be setting up 3x 1GB Droplets. Once live, I'll SSH in to each and run:

sudo apt-get update \
&& sudo apt-get -y upgrade \
&& sudo apt-get -y install nginx

Once finished, NGINX is installed on all three Droplets.

Now, for the purpose of identifying the servers, when I reference Droplet #, you'll know which one I'm talking about by looking at the below.

Droplet 01 = Load Balancer/Proxy (lb01.mydomain.com)
Droplet 02 = Web Server (nginx01.mydomain.com)
Droplet 03 = Web Server (nginx02.mydomain.com)

On Droplet 01

cd /etc/nginx/sites-available

Inside this directory you'll find a file called default. We'll delete that and start fresh.

rm default

Now, we'll create files for each of our client domains:

touch clientdomain01.com.conf \
&& touch clientdomain02.com.conf \
&& touch clientdomain03.com.conf

Now we'll modify each one, for each client.

nano clientdomain01.com.conf

Inside clientdomain01.com.conf, paste:

upstream backendOne  {
    server nginx01.mydomain.com;
}

server {
    server_name clientdomain01.com www.clientdomain01.com;

    location / {
        proxy_pass http://backendOne;
    }
}

Inside of clientdomain02.com.conf, paste:

upstream backendTwo  {
    server nginx02.mydomain.com;
}

server {
    server_name clientdomain02.com www.clientdomain02.com;

    location / {
        proxy_pass http://backendTwo;
    }
}

Inside of clientdomain03.com.conf, paste:

upstream backendOne  {
    server nginx01.mydomain.com;
}

server {
    server_name clientdomain03.com www.clientdomain03.com;

    location / {
        proxy_pass http://backendOne;
    }
}

What the above does is send requests for:

clientdomain01.com
clientdomain03.com

... to Droplet 01 -- it'll send requests for clientdomain02.com to Droplet 02.

Droplet 02 and Droplet 03

The configuration on both of these Droplets will be minimal to start as this is just an example, but you will configure these two as you would any standard NGINX web server.

To get started here, we'll delete the default file again and start fresh on both, but we'll need to add in specifics to our server blocks to handle the proxied requests from Droplet 01.

So since Droplet 02 is going to handle two domains, we'll start there.

cd /etc/nginx/sites-available
rm default \
&& touch clientdomain01.com.conf \
&& touch clientdomain03.com.conf

We'll start with clientdomain01.com.conf

nano clientdomain01.com.conf

Paste in:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    server_name clientdomain01.com www.clientdomain01.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

Now for clientdomain03.com.conf

nano clientdomain03.com.conf

Paste in:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    server_name clientdomain03.com www.clientdomain03.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

Now we can move on to Droplet 03 and do the same:

cd /etc/nginx/sites-available \
&& rm default
nano clientdomain02.com.conf

Paste in:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    server_name clientdomain02.com www.clientdomain02.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

Restart NGINX

Now, on all 3 servers, restart NGINX:

systemctl restart nginx

With the above configuration, requests for clientdomain01.com and clientdomain03.com will hit Droplet 02 while requests for clientdomain02.com will hit Droplet 03.

Where to Point A Entries

All A entries for the three domains would point to the IP of the load balancer (Droplet 01). Now the only IP that clients are aware of is the one associated with the load balancer.

So for example, if you move clientdomain01.com from Droplet 02 to Droplet 03, you'd simply modify your configuration on the load balancer to point them to the other server and:

systemctl reload nginx

and it's live again. They don't need to know about the IP's for Droplet 02 or Droplet 03.

This is an Example

Obviously, PHP, MySQL, etc isn't installed here. You'd need to install those on Droplet 02 and Droplet 03 just as we did NGINX.

This can get even more complex, though for the purpose of showing what you can do, I hope this helps a bit. If you have any questions, feel free to ask.

  • This is an unbelievably amazing answer - thank you so much for putting that all down.

    Simply amazing, thank you.

    • @cjke7777

      No problem at all, always happy to help.

      As a general note, since I can't edit that response now that it's considered to be "old", when configuring the server blocks on Droplet 02 and Droplet 03 (the web server Droplets), you'll need to remove the default_server lines next to the ports.

      That was a copy and paste error on my part and if you attempt to restart or reload NGINX with that on every server block, it'll fail.

      They aren't needed unless you want to specify another server block for a default HTML file should someone try to access the Droplet by IP.

      You could do this by adding another server block file:

      nano /etc/nginx/sites-available/default.conf
      

      and paste in:

      server {
          listen 80 default_server;
          listen [::]:80 default_server;
      
          root /var/www/html;
      
          server_name _;
      
          location / {
              try_files $uri $uri/ =404;
          }
      }
      

      Then create /var/www/html (or change it to another directory) and drop in a blank HTML file. The if someone does visit Droplet 02 or 03 by IP, all they get is a blank page.

      • No worries, and thanks for the follow up :)
        You should work for DO, or write about your experiences in this field on a blog or similar.

        • @cjke7777

          I actually put an app in a few days ago, so funny you should mention that :-).

          As for the guide, things can get way more advanced than this and I've set up some pretty crazy clusters. This should get you off to a jumpstart though.

          Beyond the above, if you want to setup a true cluster, then you'd setup as DB cluster so that you're not installing and handling the physical database connections on Droplet 02 or Droplet 03, but instead offloading them to a master-slave type cluster that offers failover (one server dies, you're still up).

          The same could be done with the above, though for that to happen, it'd require a little more configuration and data syncing to make sure that two servers have the same data at all times -- then should one die, it's dropped from the cluster until it's back online and another picks up. Once both are online, the previous syncs back and continues the process.

          To do the above though, you'd be adding another 3-6 Droplets to the mix on top of the 3 I just used as examples.

          • I probably don't have any client applications that justify the seperate DB clusters (at this stage). Hopefully as the business grows I can larger and larger clients so I can move more into that space.

            I wish you every piece of luck for your application - and if you need a reference, I'm happy to give one :) :)

@cjke7777

What are you trying to achieve at the end of the day?

Are you just wanting control over what A entries resolve to the Droplet?

If A entries are the only concern, as in you need to be able to setup sub, sub1, sub2, etc -- without requiring your client to set them up on his/her end, then you could simply create a WildCard DNS entry at CrazyDomains and route it to the same IP as the domain.

For example:

A          @          PUBLIC_DROPLET_IP
A          *          PUBLIC_DROPLET_IP

Using the above, the client can keep the DNS set to CrazyDomains and now anything will resolve to the DROPLET_PUBLIC_IP, i.e.

domain.com
www.domain.com
sub1.domain.com
sub2.domain.com
sub3.domain.com
another1.domain.com

To get the sub-domains to resolve to their own sites, you'd simply setup server or virtual host blocks for each.

For example, with NGINX, if you wanted the base domain to accept everything, you could use:

server {
    listen 80;
    server_name domain.com *.domain.com

    ....
}

If you need a sub-domain to resolve to a specific location, you'd simply setup another server block to handle that sub-domain:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com

    ....
}

If you need a sub-domain to resolve to a different IP, then you would, of course, need to edit DNS again, though if base-level A entries are what you're needing to ultimately handle, this is one option.

@cjke7777

To get around the need for assigning an physical IP, the provider that handles the DNS would need to support zone apex -- most don't.

The reason for this is because of RFC1033 specifies that the zone apex must be an A entry. That's an issue in cases like this, but there's a few options -- neither of them allow the client to continue to use CrazyDomain's DNS though.

1). Use CloudFlare (free)
2). Use Amazon Route 51 (cost is based on queries)

Using such services would allow you to setup, a clients domain (we'll use customer.com) and point it to customer.company.com which resolves on your server. Your web server would then handle the rest.

From what I'm seeing, CrazyDomains doesn't support it and I know DigitalOcean doesn't (I just tested it), so the above would be the best options if this is absolutely what you need.

The other option would be to let them run with an IP and use a Floating IP, though you'd need to weigh you options there too as moving a client from one server to another would still require an IP change (even if it's to another floating IP) unless you setup a load balanced solution that can accept a request on the floating IP and push it to the correct server.

  • Thanks for the detailed response @jtittle !

    I've been doing similar research this morning (ruling out Crazy and DO at the provider level). Route53 is an option but limits alias's to only internal instances (ec2, s3, etc). There are a few tricks like the s3 bucket redirect trick R53 -> S3 (static) -> All traffic to www DO. But it feels hacky, using a bucket to "manage" redirects.

    I've been looking at http://wwwizer.com/naked-domain-redirect as well. So give the client the IP of wwwizer, and a CNAME of say www.customer.com -> customer.servers.mycompany.com. If their users hit customer.com wwwizer would redirect to www.customer.com which in turn redirects to customer.servers.mycompany.com which is a domain I manage and can set the A records.

    Its a few hoops but nothing crazy, especially if they are all Perm301's. The onyl catch is relying on an external service wwwizer. I could also run a micro NGINX on debian on DO, with some very light weight redirects, like mentioned here: http://stackoverflow.com/questions/7947030/nginx-no-www-to-www-and-www-to-no-www
    Which would be the same as wwwizer

@cjke7777

I saw the details on the wwwizer site but didn't mention it because it'd introduce a point of failure in to the mix -- one that you have less control over than in other areas.

Ideally, what I would recommend -- coming from someone who's setup numerous linux clusters over the past 15 years -- is setup a load balanced cluster and use Floating IP's. No, it won't allow you to do what you're looking to do in terms of routing customer.com -> customer.company.com, but it's going to be far less to manage and less of a headache.

NGINX works as a load balancer, or a proxy, or a web server, or a caching web server -- so you can use NGINX across the board. No need to swap around unless you have a specific need to use something else (i.e. HAProxy).

In doing so, you'd create two A entries or one A entry and one CNAME (I tend to create A entries for both domain.com and www.domain.com -- no need to CNAME www -> domain.com), point it to the load balancer and let the load balancer filter the request to the correct server.

That's my recommendation / two cents :-). Again, I know it's not what you want to do, but it does put everything in your control.

You can rely on CNAME'ing www and managing redirects, and that may work if you're just worried about a single client, but handling a handful or more clients and I can't say I'd be thrilled to have to set that up for every one of them.

  • Dude, I'm here looking for "two cents" so absolutely appreciate it. Yeah I am liking what you are putting down - so one more question - do you have a recommend load balancer, or do you simply manage it off the back of an NGINX instance?

You cannot do this, the nameservers of the domain determine which DNS servers are used.

@Woet Thanks for the quick reply!

Is there an alternative to this? I've been thinking something like a static ip that I can map onto a server, then give the IP to the client, and I can repoint the static IP (almost like a floating IP). The only reason I am not using a floating IP is because there are few services not running on DO (gasp).

  • You could use a CNAME and point it to an A-record on a domain you control yourself.

    • Ah of course, thats a great idea! Thanks!

      I've just been playing with something similar just now - the only hiccup I am hitting is Crazy doesn't allow root CNAME records (I think, I am trying to contact their tech support).

      The existing site is example.org, not www.example.org sadly

      • If you use a CNAME for the root record it will CNAME everything, including MX and NS.

        • Ah yeah, damn. Hmmm, I think (*think) some DNS providers allow automatic root forwarding, I might need to explore that maybe?

Have another answer? Share your knowledge.