How to get the correct IP on a Linux server?

Hi

I need to get IP address from linux server.
There are many script to do this, but no one is perfect.
They just grab eth0 or eth1 from ifconfig, and this may, may not be correct.

You may have several IF configured, but only one is default GW

Here is how I would like the process to be.

  1. What is the default gateway?
    This can be found using route -n and look at flags UG

  2. Look at ifconfig and select the IP that correspond to default gateway within subnetmask.

This would give correct IP and ifname if you need it.

But there is but.
One one virtual server it may looks like this

route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 venet0
ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:12840125 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12840125 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:4483434938 (1.4 GB)  TX bytes:4483434938 (1.4 GB)

venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:127.0.0.2  P-t-P:127.0.0.2  Bcast:0.0.0.0  Mask:255.255.255.255
          inet6 addr: 2b00:daa0:da:99:225:71:fd32:d097/128 Scope:Global
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:41235259 errors:0 dropped:0 overruns:0 frame:0
          TX packets:39244451 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2827188617 (1.8 GB)  TX bytes:3421181418 (1.4 GB)

venet0:0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:182.23.5.11  P-t-P:37.247.52.130  Bcast:0.0.0.0  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

No default gateway, and SM 255.255.255.255
This is typical on VPN tunnels etc.

So how do I find DG, IP and correct ifname??

ip route
default via 10.1.1.254 dev eth0  proto static 
10.1.1.0/24 dev eth0  proto kernel  scope link  src 10.1.1.1  metric 1 

?

ip route
default dev venet0  scope link

Does help, but I still have two if name with venet0 , venet0 and venet0:0

EDIT: This shows only one if and can be used with ip route

ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/void
    inet 127.0.0.2/32 scope host venet0
    inet 182.23.5.11/32 scope global venet0:0
    inet6 2b00:daa0:da:99:225:71:fd32:d097/128 scope global
       valid_lft forever preferred_lft forever

Looking at your post#1, venet0 is the host itself. The :0 I know as alias interfaces, see man ifconfig. That setup is a bit strange to me.

Its because its a VPS and I have no control of it.
But I seems that global only exist with line having active IP.

This seems to work on both physical and VPS server.

ip addr show | awk -F"[ /]+" '/inet / && /global/ {print $3}'

Can other test this and see if it give only one correct IP for the active IF

try:

$ ip add sh | grep -w inet

This will grep all ip on all interfaces

And that is what i do not need.
If you read post above, I need only the IP that is used for traffic.
In same range as Default Gateway.

I am no longer competent on Linux (it's been more than 5 years since I used it regularly), but perhaps this will provide more specific information than the simpler ip route ?

ip route get <addr>

Where <addr> is any destination address to which you do not have a direct host-host or host-subnet route. Perhaps you could use 8.8.8.8 (one of Google's public dns ip addresses).

ip route get doesn't actually send a packet, it only uses the kernel's routing information to determine how such a packet would be sent.

Regards,
Alister

2 Likes

Perfect
Thank you :slight_smile:

This gives exactly what i want:

ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $NF}'