Is there a way to change the private DNS of an EC2 server?

I want to be able to communicate between my servers with something like myserver.example.com rather than ip-1.1.1.1-uswest-aws-internal. I'm new to the sysadmin role as well as networking. I tried to play around with DHCP options sets in the VPC but couldn't get it to work.

EDIT #1

To clarify what I'm trying to achieve...I'm setting up Jenkins that will run slaves on numerous servers. I wanted to be able to use my own assigned addresses instead of arbitrary ones so it makes more sense that it depends on which machine's a job is running on.

I'm also sure it would make other inter-server communications easier in the future as well. Like I said I'm new to sysadmin, so if there is an easier method I'm missing, let me know.


Solution 1:

If you want to access your servers by my-dns-name you'll need to setup your own DNS server.

By default AWS VPC handles DHCP for you and comes with Amazon's DNS server.

You can read up on the options for supplying your own DNS Server here: http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html

DHCP Option Name: domain-name-servers

The IP addresses of up to four domain name servers, or AmazonProvidedDNS. The default DHCP option set specifies AmazonProvidedDNS.

DHCP Option Name: domain-name

If you're using AmazonProvidedDNS in US East (Northern Virginia) Region, specify compute-1.amazonaws.com. If you're using AmazonProvidedDNS in another region, specify region.compute.amazonaws.com. Otherwise, specify a domain name (for example, MyCompany.com).

Other related notes:

If you want to use a FQDN (myserver.example.com) to communicate, you can do that without your own DNS server, your domains are already publicly accessible.

You can communicate with IP Address', Private or Public, you can change private IPs at the OS level, change hostnames at the OS level and take advantage of /etc/hosts to have a kind of poor-mans DNS.

You might always want to look into ElasticIPs, Elastic Network Interface, and Elastic Load Balancers which all play in the same space as your qestion.

It all depends on what you're trying to achieve, and how you want to do it!

Solution 2:

You can't change it, unless you deploy your own name servers, but you can easily reference it with another name, by creating a CNAME record, which will have the desired effect.

In your "example.com" DNS zone, whether it's in Route 53, or hosted with another DNS hosting provider, you should be able to create create CNAME records:

myserver IN CNAME ip-1.1.1.1-uswest-aws-internal.

When a machine tries to resolve "myserver.example.com" it will be, essentially, told by the "example.com" DNS servers that it should instead look up the "real" internal hostname (the "canonical name") . If the machine is inside your EC2 deployment, it will ask the EC2 dns resolver to look this up, and the EC2 resolver will in turn return the internal IP address... leading to the behavior that you want -- you can access your internal machines by your desired hostnames.

If a system outside your EC2 deployment looks up this hostname, it will fail, which is the correct behavior, since the machine isn't accessible from outside (if it only has a private IP).

Conversely, if you have a machine with a public IP and a corresponding public hostname, like ec2-x-x-x-x.us-west-2.compute.amazonaws.com using that hostname as the CNAME target will do the same thing. When queried from inside your EC2 deployment, the result will be the internal IP address via some DNS magic that EC2 does transparently... or from outside, it will return the external public IP address.

https://stackoverflow.com/a/19148569/1695906

Clarification:

There are two kinds of DNS server behavior -- "authoritative" servers will answer a request from any host for any resource record for which they are authoritative ... and recursive "resolvers," which query the global DNS on behalf of their authorized clients. It is also possible for a DNS server to perform both functions.

Your EC2 instances (by default) use the AWS resolver servers to look up any hostname, inside ir outside, that your instances try to access, and return an IP address... but the AWS resolver is also authoritative for the ".internal" pseudo-domain, so when instances try to look up ".internal" hosts, the correct internal IP is returned.

Now, suppose you configure internal hostnames as CNAME targets in the external "example.com" DNS servers, and then try to internally look up "myserver.example.com" ... the AWS resolver consults the global DNS hierarchy and ends up asking one of the authoritative name servers for "myserver.example.com." The response will essentially say "all I know is that to find myserver.example.com, you should look up ip-1.1.1.1-uswest-aws-internal" ... the AWS resolver realizes that it does not need to consult an external entity to answer this new question, because it is authoritative for the fake internal domain, simply responds with the correct answer, which it already knows.

The external "example.com" doesn't need to or try to validate the CNAME target, since that's not its job.

Now, if the CNAME refers to the external hostname, the process is the same and the result is the same, because the AWS resolver (which handles all DNS queries made by your internal machines) does not try to actually look up the true and correct IP address from the DNS servers that are authoritative for the "compute.amazonaws.com" domain... instead, it once again believes, because of its design, that it already knows the IP address of your external hostname... but the answer will again be your internal private IP address.

The AWS resolver I'm speaking of, above, is a virtual entity that is only accessible to your instances. The information it contains about public hostname to private IP mapping is only accessible to your instances when they query it. It is not externally accessible.

If you provision an internal hostname as a CNAME target, external queries will get the "internal" answer, which for them will be a dead end. If you provision external hostnames as the CNAME target, they will end up with the public IP, because finding the CNAME will direct them to the public authoritative DNS servers, not the private internal resolver that only your instances can access.

This is actually all very simple in practice, though not quite so simple to explain here, because so many of the fundamentals of DNS need to be understood, first... but this ultimately works because the "example.com" DNS servers simply don't care whether you configure them with a CNAME they understand. It isn't their problem to understand it -- the burden is on the resolver that's looking for an answer to make ultimate sense of the intermediate answer appearing in the CNAME.

Solution 3:

I had the exact same problem. Although my domains are managed outside of Amazon, I used Amazon Route 53 to create a private hosted name and added a CNAME record, pointing it towards the private AWS DNS name of the instance. The problem was although this solved things for subdomains, it did not work for the root "example.com" as that breaks CNAME rules.

I have since deleted the CNAME entry, and replaced it with two A-records (example.com and *.example.com) pointing towards my public IP. I used a public Elastic IP as in my usage case that will always be the same, but your situation may differ. You ought to be able to use your private IP but I did not test this.

I should point out my servers were Windows based, though this shouldn't make a difference. I found using NSLOOKUP example.com at a command prompt useful for monitoring changes as suggested by other posts here. I also considered it vital that any changes you make have a very low TTL value so that changes apply as quickly as possible... Amazon Route 53 smallest preset is 60 seconds but may go lower. I'm sure setting the A-record was one of the first things I tried, but it didn't propagate straight away so then spent hours going down blind alleys.

Solution 4:

You can easily achieve this with private hosted zone in route 53 http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html