CentOS server: how to detect network status changes - linux

I have setup a CentOS 6.4 server (minimal install) which is connected to network through an ethernet cable. The problem is that when the network link goes down, the status changes are not automatically detected but if i type "ifconfig" the interface still keeps its IP address (which is assigned by a DHCP server). After some time that the link is down the interface loses the address but when the link comes up again the network connection is not automatically restored like it would happen in a desktop computer. Even the command "dhclient eth0" does not always work to restore things, and I have to restart the whole network service with "/ect/init.d/network restart".
Is there any way to automatically detect network status changes like it happens in desktop installations? I'm thinking about a cron script that every 5 minutes pings a server outside my network and if it doesn't get any response it restarts network service, but this does not sound very efficient... is there another way?
EDIT: I realized I have not explained the situation correctly. My network topology is: server --> switch --> router --> external network (the router is another centos server with DHCPD).
For some reasons (that i'm not getting), when it happens that the router goes down and reboots, the other server becomes unreachable, and I have to manually restart network service on it. So the link does not effectively go down (the switch keeps it up), but the status change is at IP level.

You can check if you have NetworkManager enabled, I usually don't use it in the servers but it can help you in this case because it will monitor automatically the connections (it is quite common in desktop installations).
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-NetworkManager.html
To look for messages indicating an issue with the NIC just check the kernel ring buffer using the dmesg command.
For example when the cable is disconnected from a given interface this is what I get:
igb: eth1 NIC Link is Down
The first word will depend on the name of your network driver.
You could also configure the system to log these messages also to /var/log/messages (by default I am not sure if they appear there). Then it would be just a matter of monitoring the log, look for similar messages and restart the network service.
In any case the NetworkManager, if it is not already enabled, it should be an easier solution.

There is a module called miimon for monitoring the network interface's status. ethtool will give you the link status.
$ethtool eth0
...
Link detected: yes

Related

Routing HTTP through specific network interface

I'm very unfamiliar with Linux so forgive me if this has been answered before, I've read quite a few answers but I'm never sure if they actually relate to my question.
I have a headless raspberry pi that connects to my phone's bluetooth automatically, my phone shares its internet access by tethering. I use this initial and reliable connection to SSH to my raspberry pi, and use the desktop with VNC viewer.
I would like to connect to a WiFi network that uses a captive portal, but the browser always uses the bluetooth connection so it never redirects me to the portal page. The bluetooth connection is just to be able to use the desktop so I can get through the portal, then I would like to either disconnect bluetooth or just not use it, mainly because of the low bandwidth it provides.
I've added wlan0 as a priority interface with ifmetric, but that hasn't worked.
I was thinking that forcing all HTTP connections through the wlan0 interface could solve the problem, but there may be a simpler way, feel free to tell me.
Can you explain in "simple" terms the best way to achieve this ?
Of course, there are multiple solutions. The simplest is making sure that there is only one correct default route.
There are 3 situations:
You are only connected via bluetooth via ssh
You are connected via bluetooth and via wifi, but not yet through the splash
You are through the splash
Each will require a different network configuration.
In 1, your network config will probably be:
some IP address (let's call it IP-bt) and network mask
Default gateway is your phone
With route -n you can verify this.
In 2, the network config will depend a bit on the wifi network, but in general, your network config will be:
you'll still have IP-bt
you will have a new address on the wifi adapter (which we call IP-wifi)
the default gateway should be the gateway on the wifi network.
When you verify this with route -n, you might still see a route with destination 0.0.0.0 towards your phone. You can delete this route. Your phone should be on a directly connected network and your ssh session should therefore not break.
If the default gw is not on the wifi network, you can still remove the route that sets your phone as default gw.
Under 3, the default gw must be on the wifi network, and not on the phone. You will still be able to use your phone, because it is directly connected.
Something to watch out for in this scenario is that your phone will act as a DHCP server. That means once in a while your DHCP lease will refresh, and the bluetooth default route may re-appear. Disconnecting bluetooth will prevent this.
The second solution is to use ifmetric. Instead of making wlan0 a lower metric, make your bluetooth a higher metric. Again verify with route -n that the metrics are as you want them to be. Verify with a traceroute how the packets are moving.
A third, and most complex option would be to install Quagga and configure correct routing.

I programmatically need to notice when connman has processed its config file (and has set an IP or not)

How can I wait in my user space program until connman has finished the network configuration on Linux booting? (Unfortunately, this is not Wants=connman.service.)
After systemd service connman is up, my user space program starts via systemd service (Wants=network.target connman.service), and it wants to read the network configuration via C function getifaddrs() (e.g. ifa->ifa_addr and ifa->ifa_addr->sa_family). Now two things can happen, either connman reads an explicitely unconfigured network (IPv4=0.0.0.0/0.0.0.0/0.0.0.0) or a certain network configuration (e.g. IPv4=192.168.0.50/255.255.255.0/0.0.0.0) from its config file. For some reasons my program has to wait on a certain code line until connman has finished its setup with one of both cases. How do I do that?
All I found in the systemd synchronisation possibilities were points of times when the connman service is up (Wants=connman.service) which does not mean it has processed its config file, it's before that!!!), and secondly, network-online.target for when an IP address is configured (which does not include the case of 0.0.0.0/0.0.0.0/0.0.0.0 in the connman config file).
addon: I noticed an IP address is set during Linux booting as soon as "Link is up - 100Mbps/Full - flow control off" is printed on console. How do I detect that in my user program?
Uhm, all I found is this workaround. The start script of my service looks into connman's .config file and searches for the line with "IPv4=", and in case it's all 0.0.0.0 there I can immediately start my application or otherwise I have to loop in that script until ifconfig reports it has set an IP address for that certain network adapter interface.

Connecting to remote service to test RPC program

I am working in a Linux Debian 7 distribution.
I programmed a very simple procedure to test onc-rpc.
The 'remote' call works fine when I call it this way:
test_client localhost
However, when I invoke it by calling a remote server IP:
test_client 202.170.91.155
I get an error message:
202.170.91.155: RPC: Port mapper failure - RPC: Unable to receive
I am just learning and I know almost nothing about portmapping in Linux.
The IP I was trying to call for the service is the IP address of the same machine. I speculate the rpcbind daemon does the necessary mapping for the server when you register a new service, but I really have no clue.
Which steps should I take in order to fix this error?
In the end, the issue has nothing to do with programming.
This kind of error may appear when the rpcbind daemon (In charge on giving information about the port where the requested service is listening) does not give a response to the calling machine.
This can happen due to errors in NAT or firewalling.
So, a first attempt to diagnose the problema, as with anything regarding networking, could involve verifying the connection is fine by making ping to every interface involved, from closest to furthest, making sure each jump works fine.
For instance, in the issue decribed above: Pinging the supposed internal server ip address (it failed) helped to discover that the machine was using an IP other than the intended (the one mapped to receive request to port 111).
Stopping and restarting eth0 configuration with ifdown/ifup correctly updated ipv4 info, effectively making reachable the rpc service.

Find network interface that is communicating with gateway without using PING/ ICMP or UDP

I have a RHEL client machine which has to get data from the RHEL server machine at the time of booting up.
The IP address of the server is known.
The gateway which has to be used by the client machine is known.
The client machine has multiple network interfaces. All may not be up at the same time or all may be connected to different networks.
I need to determine which network interface has to be used.
I know that this can be easily done using the "ping" or "traceroute".
The issue is ICMP protocol is disabled both at the client end as well as the server end.
ICMP has been disabled due to security concerns.
ICMP may be disabled at machine level or it may be disabled for the whole network.
In otherword, I need to find a way that can give me if two ip's are communicating if ICMP is disabled.
Also, I have to use this result in my script, which I am writing in bash, to set the network of the client machine.
What is the best possible way to achieve this?
You can ping the ip with ARP try using arping command

DHCP and IP address acquired event

I am using Linux and I need some indication that an IP address has been acquired by the n/w interface over DHCP. Is there any event that I can wait for... Ideally I would like to have something like this: An event or a call back so that whenever the interface acquires an IP address I can get to know immediately. Is there any such event or call back or any provision?
Thanks!
If you're on a desktop distro running NetworkManager, it will run scripts in /etc/NetworkManager/dispatcher.d when the network interface changes state, passing information via the command line and environment variables. I forget the details, but you can check the documentation and existing examples.
NetworkManager also has a dbus interface, which you can listen to for the same information. Running (as root) dbus-monitor --system while you bounce your interface will show you the relevant signal.

Resources