Can /etc/hosts config reverse resolution? - dns

As we all known, we can add 'ip host' item in /etc/hosts to mock a DNS's name resolution, now comes the question, can I use /etc/hosts to do inverse resolution, form ip to hostname? Or is there any other handy way to do this? Thanks!

Maybe. It will depend on the tool you use to do the lookup and the configuration of resolving on your computer.
For example gethostbyaddr() will check /etc/hosts if "files" is in the hosts section of your /etc/nsswitch.conf
Note however that not all tools will do a local resolve, such as the "host" command for example, so it depends entirely on how you are attempting to do the lookup.

Yes. It does that automatically if the application uses Name Service Switch libraries (most applications do), and if /etc/nsswitch.conf is configured to resolve IPs from /etc/hosts with a line such as this:
hosts: files dns
You can test the reverse name resolution with either of the options below:
getent hosts 127.0.0.1
or
resolveip 127.0.0.1

No. That can only be done on a DNS server.

Yes you can. If you use dnsmasq, you can interfere in a number of ways to get a forward lookup going to 127.0.0.1 and the reverse lookup from 127.0.0.1 going to your host. For example, if your hostname is host1.mydomain.com with a real IP address of 192.168.1.12, then you can get 127.0.0.1 to resolve to it by doing the following in the dnsmasq configuration file:
host-record=host1.mydomain.com,127.0.0.1
The forward interference can be done in many ways, here is one:
alias=192.168.1.12,127.0.0.1
Obviously you need to set up the rest of dnsmasq properly to forward to your real DNS server ... but that is simple enough

Related

How do I configure DNS in ubuntu? Why is it displayed that the domain name resolution has failed temporarily?

I guess it's because my virtual machine is not connected to the Internet correctly, but I don't understand how to configure DNS? I tried a lot, but I don’t quite understand it. It’s the first time to learn computer, hoping to help me, thank you 🙏
The examples below use Cloudflare (1.1.1.1) and Google (8.8.8.8) DNS Servers. You might want to consider using a local DNS forwarder, or different, more privacy friendly public DNS servers, instead.
If using Ubuntu Server:
As per the documentation (https://ubuntu.com/server/docs/network-configuration), the resolver configuration file (/etc/resolv.conf), is dynamically generated by Netplan.
You can temporarily add nameserver entries to /etc/resolv.conf, for example:
nameserver 1.1.1.1
nameserver 8.8.8.8
However, those will be overwritten by Netplan. If the changes worked, make them permanent by looking for the Netplan configuration file, usually a .yaml in /etc/netplan. Add a nameserver block, or modify the existing one:
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
If using Ubuntu Desktop:
Assuming NetworkManager is installed:
Look for the connection name:
nmcli con
Add your DNS servers:
nmcli con mod <connectionName> ipv4.dns "1.1.1.1 8.8.8.8"
In the future, please consider using the https://askubuntu.com/ forums for these questions instead.

Alternative to glibc Library call res_ninit for getting DNS details over DHCP

Is there a good API alternative to res_ninit?
There are problems with this call because the res->_u.ext.nscount6 and res->nscount do not reflect correct numbers. Adding a IPv6 address to /etc/resolv.conf still results in the nscount increasing where you would have expected the nscount6 to increase.
An older glibc version seems to increase both nscount and nscount6 for a IPv6 address in /etc/resolv.conf.
I am currently parsing resolv.conf directly because i am unable to depend on the res_ninit call. But this is fine for Manual DNS.
When it comes to DHCP DNS, then i need an API to give me the result. There is no other way (that i can think of) to determine the DNS IP addresses over DHCP.
Tried posting in other places within the board but not of help so far. E.g.
Retrieve IPv4 and IPv6 nameservers programmatically
res_ninit and res_init only ever read name server information from /etc/resolv.conf. You can always get the same data name servers by parsing /etc/resolv.conf yourself and examining the nameserver lines. If there is no nameserver line, the default 127.0.0.1 will be used.
I don't think it is necessary to provide an API for that because the file format is so simple that is likely more difficult to use the API than to read the file instead.
Name server assignment over DHCP is implemented by rewriting /etc/resolv.conf if there is no local caching resolver running on the machine. The exact mechanism used for that is distribution-specific, e.g. Debian uses resolvconf if it is installed.
If a local caching resolver is running on the system (such as dnsmasq or Unbound), name servers over DHCP can be directly configured in that caching resolver. In this case, /etc/resolv.conf will keep pointing to the same name server, typically by listing nameserver 127.0.0.1 or no name server information at all (which is the default).

Reproduce `Temporary failure in name resolution`

How can I reproduce manually the Temporary failure in name resolution error, when doing ping google.com in linux?
Probably, I can add a broken DNS server by my own and specify it in /etc/resolv.conf?
I need this for testing my project.
You can try this in /etc/nsswitch.conf:
hosts: files
That is remove all traces of the dns service for the hosts case (a normal line is something more like hosts: files dns but have a look at yours before changing it).
Then, if a name/IP is in /etc/hosts the name resolution works, if it is not, it does not work as the DNS is not consulted.

It is safe to use lvh.me instead of localhost for testing?

I wonder whether is safe to use lvh.me instead of localhost when developing locally, since lvh.me must be resolved and the IP may change over time.
The goal of using lvh.me is to be able to handle subdomains, since localhost does not have top level domain.
Unless you are the maintainer of lvh.me, you can not be sure it will not disappear or change its RRs for lvh.me.
You can use localhost.localdomain instead of localhost, by adding the following lines in your hosts file:
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain
This is better than using lvh.me because:
you may not always have access to a DNS resolver, when developing
lvm.me does not answer with a local IPv6 address corresponding to your local host, only with the IPv4 address 127.0.0.1
some ISPs DNS resolvers block answers corresponding to private addresses space, for security purpose (to avoid leaking internal informations)
Since you said in a comment that you do not want to update the host file, you have no mean to be sure that lvh.me will always work for your developers. Therefore, to answer your question: it is not safe. You may register a domain for yourself, but as I said before, some resolvers will block answers corresponding to private addresses space.
lvh.me was not resolving to 127.0.0.1 on June 7, 2021. Depending on DNS names you don't control comes with this kind of risk. Although the domain name was reinstated by the end of the day, this answer offers some alternatives to depending on someone else's DNS configurations.
Both Firefox and Google Chrome now treat *.localhost names like localhost. They also do the right thing with port numbers.
To test it yourself, start a local http server listening to port 8000:
python -m http.server 8000
Then try these links
http://example.localhost:8000
http://other.localhost:8000
http://sub.subdomain.localhost:8000
This trick does not help for command line programs. For example, this command will fail to resolve the host:
curl http://example.localhost:8000
Curl itself offers a lot of other tricks that might work for you if you need custom subdomains on the command line. For example, this trick works:
curl --resolve example.localhost:127.0.0.1 \
http://example.localhost:8000
Also worth noting that a similar service is still available.
See https://readme.localtest.me.
One last alternative is to configure your own wildcard CNAME to resolve to 127.0.0.1. For example:
*.my.example.com. 1800 IN CNAME my.example.com.
my.example.com. 1800 IN A 127.0.0.1
No because as of right now http://lvh.me has an expired domain.😬
Services like lvh.me or localtest.me are just DNS services, so the only thing you're publishing to them is the names or the hosts you're using. They could resolve to any IP at any time, but providing you use use them only for local tests with fake data, you'll be safe.
But what if they shut down the service? Again, since you should only use them for local tests, you'll get immediate feedback and can easily go back to using localhost.
Quick fix if you don't want to rewrite your code is to open up hosts file
sudo nano /etc/hosts
paste in (replace yoursubdomain with what subdomain you're calling)
127.0.0.1 yoursubdomain.lvh.me
push ctrl-x
then y
then enter
Then you're good to go
It depends on what you're doing. If it's local development then most the time yes, you can always resolve it if you want to check:
For linux or osx you can run this in terminal:
dig X.nip.io
It should always return 127.0.0.1. So while it's not the "safest" way to do this (because you don't manage the DNS itself), I still use it frequently for some kind of resolving TLD when necessary. Here's some valid reputable sites that are still around:
https://nip.io/
https://sslip.io/
You can just point your browser at myproject.apps.localhost or www.example.net.localhost.

linux: adding hosts programmatically?

Is there a way to programmatically add hosts to the local name resolver under Linux?
I would rather avoid fiddling with /etc/hosts dynamically...
Example: add the name foo and bind it to the local port 127.1.2.3
Use Case: I have an application installed locally accessible through a web browser. I'd like the application to be accessible through a local URI.
add the name foo and bind it to the local port 127.0.0.1:9999
What is it that you want? You can add foo 127.0.0.1 to hosts or do the equivalent in your nameserver, but a connection to foo on port 1234 will always go to 127.0.0.1:1234 -- it's not possible to redirect that to port 9999 based on name, which is lost by the time connect is called.
On Linux you can add IPs to the loopback device (i.e. ip addr add 127.1.2.3 dev lo), and then use iptables to change all connections destined for 127.1.2.3:1234 to instead go to 127.0.0.1:9999, but I can't tell from your question if that the observable behavior you want.
If you'll only add hosts, a pretty safe way to do it is
echo -e "ip.add.re.ss\thostname" >> /etc/hosts
Now, if you want to remove them it starts getting hairy. I suspect you also want to remove them.
If this is the case you can use Dynamic DNS, for example, BIND has the nsupdate tool to update zone files:
$ nsupdate
> update delete oldhost.example.com A
> update add newhost.example.com 86400 A 172.16.1.1
> send
This does the following:
Any A records for oldhost.example.com
are deleted. And an A record for
newhost.example.com with IP address
172.16.1.1 is added. The newly-added record has a 1 day TTL (86400
seconds).
The google search term you want is "DDNS" for "Dynamic DNS". That's a technology for dynamically adding records to DNS servers, which sounds like exactly what you want. I'm pretty sure the bind in most lunix distros supports it, but you may need to read up on how to configure it.
I'll be going with a recent discovery: multicast-dns using the Avahi package. An example can be found here.

Resources