linux: adding hosts programmatically? - linux

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.

Related

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.

Is there any linux command to get host name from ip?

I want to get host name from ip. I know a few command who does the work like host, nslookup and dig but they are not completely reliable. In many of the cases they fail to give the host name. So, is there any command who can always give me the host name.
For ex: If I check "host stackoverflow.com" then it gives me a list of five different ip addresses. But when I check "host ip_address (each of the five different ip addresses)" than it's not able to find the host name.
DNS has a forward and reverse zones and what are you going to get by requesting a domain name for an IP-address depends on reverse DNS-zone configuration of that domain name, that's not an application malfunction or something - it's just asking DNS-servers. So no, there's no such command that you're looking for.
If you are not getting IP to hostname resolution, this means that the reverse lookup is either not allowed or not configured properly at the dns server (you are pointing to). In other words, PTR record does not exist, or you are not allowed access to it.
All the dns commands use the same or similar methods and underlying system calls to get the name; they search for the PTR record.
Without going into too much detail. If this is something you really want to do, you can look at other options like looking at the reconnaissance tools in Kali.

How to assign an external ip to linux server at gcloud?

Last several days I'm struggling with a problem.
I have two instances(ubuntu server) on gcloud and I want to assign them their external IP.
And I can ping and ssh to my instances but when I try to do telnet it is not performed.
On gcloud all instances have one internal ip and one external IP.
And they does not know their ip. I get it from gcloud console.
How could I assign it to them?
Also I've tried sudo ifconfig eth0:0 130.211.95.1 up
You can do something like this to add the external IP to a local interface:
ip addr add 130.211.95.1/32 dev eth0 label eth0:shortlabel
Replace 'add' with 'del' to remove it once you are done with it.
shortlabel can be any string up to a certain (short) length.
Update: also see this GCE support issue for related information.
A feature request for this is already filed on GCE public issue tracker, however it is not yet implemented. You can star it to get notification if any update posted on the thread.
May you also mention what's your use case? so I can probably provide you with a workaround.

Is there a way to use DNSMasq and BIND on the same computer?

I like the idea of running my own nameserver (BIND) but if I do that, I can't get the benefit of blocking nasty websites by putting them in /etc/hosts
DNSMasq is able to refer to /etc/hosts but rather than specifying an "upstream" dnsserver, I'd like it to be able to use BIND on the same machine. However, they both need to use the same port.
Is this possible? I couldn't find anything about this in regular searching.
I suppose an alternative would be to run another Linux instance in a VM and run DNSMasq there (say) but I'd like to not have to do this.
you could assign multiple ip addresses to the same interface, either with
ip addr add <address>/32 dev eth0
or using
ifconfig eth0:1 <address>
then bind one server to one address, the other server to the second address.
Which server is queried depends now on the ip address your queries are sent to.
The examples assume that your eth interface is eth0.

Can /etc/hosts config reverse resolution?

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

Resources