0

I am looking for a way to have a script on a client machine automatically find the servers IP on the same network.

I have several media extender clients running ubuntu 14.04.1 and a server running the same on a single LAN. I want the clients to at startup to search the network for the server. Setting a static IP is NOT a solution I can utilize from the server or dhcp.

Searching by hostname might be useable but I would really like if there was something on the server that would broadcast and allow the clients to find it that way, incase two devices have the same hostname (unlikely but possible), or the hostname changes. Also the LAN may not always be the same ether. (eg, 192.168.1., 10.0.0., etc)

The clients are ultimately looking for the mysql server running on the server but I really only need the IP so the script can configure the software to use the database on the server.

Thanks in advance for any help.

EDIT: Third party programs are fine. Clients could be connecting to any server on any subnet at any time. When I have something to find the server I will likely use a keepalive of somesort to restart the search once connection to the server is lost. Keeping a list of MAC's or other hardware identifiers is not an option.

  • So the IP can change, the hostname can change and the subnet itself can also change? What remains stable? What can we use to search? – terdon Feb 17 '15 at 15:30
  • Thats why I thought there might be a broadcasting server I could run on the server that the clients could detect. I don't mind using non standard programs. – JpaytonWPD Feb 17 '15 at 16:05
  • 1
    Maybe use Avahi. – Mark Plotnick Feb 17 '15 at 19:04
  • Maybe use IPv6 so you have automatic neighbor detection.. – SailorCire Feb 18 '15 at 20:27
3

From your requirements I think this is exactly what Multicast DNS (i.e. Bonjour) was defined for. If you are using Ubuntu systems, chances are you already have Avahi already installed both the server avahi-daemon and the client avahi-discover

Basically you would set it up as follows:

  • If you want a fancy name for your server (instead of its hostname, which is the default), you just need to have its name configured properly in the Avahi daemon. This configuration can be done through the desktop or by modifying the /etc/avahi/avahi-daemon.conf configuration file and ensuring it has the following defined:

    [server]
    host-name=database
    domain-name=local
    


  • The client would just need to resolve the IP address of the name database.local to obtain the IP address. For example running ping database.local or using the Avahi tools: avahi-resolve -4 -n database.local

This works because the local DNS domain is defined as a multicast domain. The client will send a multicast query to the LAN, which will reach all the systems connected. The Avahi daemon in the server will answer to that query providing its IP address.

You will be able to find out more information on how to setup ZeroConf here.

If you would like to tinker with mDNS, you can also install both mzclient, avahi-utils and mdns-scan. The first one can be used to advertise a service and the others to find that service in the network. For example:

To run in the server a service to register a new name associated with the MySQL database:

    $ mzclient -p "_sql._tcp 3306 database"
    *** Registering name = 'database', type = '_sql._tcp', domain = 'local.'
    *** Registered name = 'database'
    (...)

To try to find the service using Avahi in a single shot:

$ avahi-browse -t _sql._tcp 
+   eth0 IPv4 database    _sql._tcp            local

Or by continuously scanning the network trying to find available mDNs services:

    $ mdns-scan 
    + server [xx:xx:xx:xx:xx:xx]._workstation._tcp.local
    + database._sql._tcp.local
    Browsing ... \           
[ interrupt with Ctrl+Z]


Notice that in this configuration you are not using a central DNS server, it is not required. All the queries are done in the local LAN using multicast traffic.

  • I like this and I am digging into it. If I understand the mzclient is the server end. Is it actually broadcasting a sql server available on the network? Could I actually set my client softwares mysql host to database._sql._tcp.local and have it find the server? – JpaytonWPD Feb 18 '15 at 18:32
  • Yes, the mzclient is the server end. It does not broadcast information, it answers to broadcast mDNS queries such as those sent by mdns-scan which is, again, a debugging tool. You can read the manpages for both at manpages.ubuntu.com Those are testing tools and they do not rely on having a local mDNS reponder daemon. If you want a final setup I suggest you configure avahi directly in your clients and your servers. – Julian Garla Feb 24 '15 at 8:58
1

I guess server's MAC is not going to chage, at least not frequently, so I would use that to identify the server's IP. I would use something like arpwatch to monitor the network until the servers IP/MAC pair is identified thus having the server IP.

  • Thats a good idea but I think some more background might be necessary. There are multiple LANs with a single server on each. Clients maybe be connecting to any of these networks and new ones may be added at any time so keeping a list of MAC's is not ideal. (some are private). Otherwise it is a great idea. – JpaytonWPD Feb 17 '15 at 16:03
  • @JpaytonWPD please add the background to your question. It is easy to miss and hard to read in the comments. – terdon Feb 17 '15 at 16:07
1

A network scan with nmap should work. A far easier first step is to run the command arp -a which could give you all of the mac and IP on your broadcast network (if ICMP requests are not blocked).

Next, try ping of the broadcast address you are in (requires ICMP requests not blocked). For instance, if your server is 192.168.1.10 and the netmask is 255.255.255.0, then ping -b 192.168.1.255 (on Windows, it would be ping -a 192.168.1.255 ) should invoke responses from all of the other devices (servers, routers, thin clients, etc) on your network.

Of course, this only gives you devices within your subnet. If your 'network' has more subnets, you can run ping to the broadcast address of those other networks as well, and yield a similar list of devices from each.

  • It seems nmap can perform these steps all together in one command. This does work though. Thanks – JpaytonWPD Feb 18 '15 at 0:40
1

Edit 2 (per our conversation):

See if this works better for you (with more information):

  nmap -p 22 --open -sV 192.168.1.0/24

Like before, add the awk if you just want the IP's:

  nmap -p 22 --open -sV 192.168.1.0/24 | 
        awk '/is up/ {print up}; {gsub (/\(|\)/,""); up = $NF}'

where:

nmap : the executable name
-p 22 : specifies the port to test
--open : suppress output for clients that are not listening
-sV : display the version string reported by the scanned server

Edit:

If you are trying to get all the ipaddress on a network that the local machine can potentially talk to, try nmap:

nmap -sP -PA21,22,25,3389 192.168.1.1-254 | 
    awk '/is up/ {print up}; {gsub (/\(|\)/,""); up = $NF}'

I try hitting a custom range of ports to test if servers are up -PA21,22,25,3389 (on the broadcast network 192.168.1.1-254) you can change this if you have a specific port you might know you are trying to hit. You can remove the awk if you want more than just the ipaddresses, it would also print out the hostname and such.


If you just want the IP addresses of a server from ifconfig, you can just run:

ifconfig | awk '/inet addr/{print substr($2,6)}'
[OR]
/sbin/ifconfig | awk '/inet addr/{print substr($2,6)}'

This will print results like:

10.0.0.XX1
10.0.0.XX2
10.0.0.XX3
127.0.0.1

To remove localhost - 127.0.0.1 from the results use:

ifconfig | awk '/inet addr/{print substr($2,6)}' | awk '!/127.0.0.1/'

Result:
192.168.1.XXX

You could put that line in a script as is and run it on local machines to get the ip addresses, or you can also put in in a shell script to get remote addresses via ssh like so:

#!/bin/sh
#getremoteips.sh
#chmod 700 getremoteips.sh ##Root should only be running this

ssh $1 "/sbin/ifconfig |
awk '/inet addr/{print substr(\$2,6)}' |
awk '!/127.0.0.1/'"

And to run the script: ./getremoteips.sh <enter hostname or ip>

  • This wont work, assume the client has no access or knowledge of the server. This will be a background process with no user interaction on the client to find and connect to the server. – JpaytonWPD Feb 17 '15 at 16:34
  • @JpaytonWPD I updated my answer. It seems you want to have your local machine scan the broadcast network for available servers? – devnull Feb 17 '15 at 16:51
  • That could very well work. I can run a small webserver on a unusual port and have the clients check each device with that port open for a configuration file. – JpaytonWPD Feb 17 '15 at 23:00
  • I tested a few times and I got too many results. I tried a port that I know is not open on anything and I still got all the IP's on my network. – JpaytonWPD Feb 17 '15 at 23:01
  • If I use -PN it lists every ip in the range. If I remove it I still get every active client even if the port is not open. I suppose I can check every IP if the port is open after but I think nmap should be able to do this. – JpaytonWPD Feb 18 '15 at 0:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.