RDP Monster

How to Check IP Address in Linux: ip addr, hostname -I, curl

How to Check IP Address in Linux: ip addr, hostname -I, curl

Check your IP address in Linux with ip addr

The command that answers "what is my IP address" on any current Linux distribution is ip, from the iproute2 package. It ships by default on every major distribution, works without root, and is what the other commands in this guide wrap or have been replaced by. The basic form lists every interface with all of its addresses:

ip addr show
ip a            # same thing, shorter

On a server with a single network card the output looks like this (the valid_lft lifetime lines are trimmed):

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 203.0.113.25/24 brd 203.0.113.255 scope global eth0
    inet6 2001:db8:1::25/64 scope global
    inet6 fe80::5054:ff:fe12:3456/64 scope link

How to read it:

  • Interface name. lo is the loopback, always 127.0.0.1, reachable only from the machine itself. The real card is eth0 here; with predictable interface names it appears as ens3, enp0s3 or eno1, and wireless cards start with wl.
  • inet is the IPv4 address, inet6 the IPv6. The /24 suffix is the prefix length in CIDR notation, the modern spelling of the netmask 255.255.255.0.
  • scope global means routable beyond this host; scope link (the fe80:: line) is valid only on the attached network segment; scope host is loopback.
  • state UP with LOWER_UP means the interface is enabled and has a link. state DOWN or NO-CARRIER is the usual reason an interface has no address at all.

Useful variants:

ip -4 addr                  # IPv4 only
ip -6 addr                  # IPv6 only
ip -br -4 addr              # one line per interface
ip -4 addr show dev eth0    # a single interface

The brief form (-br) is the fastest way to check an IP address in Linux when several interfaces exist, the normal situation on a VPS running Docker:

$ ip -br -4 addr
lo               UNKNOWN        127.0.0.1/8
eth0             UP             203.0.113.25/24
docker0          DOWN           172.17.0.1/16

hostname -I: just the addresses

When you only need the addresses, hostname -I (capital I) prints every configured address on one line, space-separated, loopback and IPv6 link-local excluded:

$ hostname -I
203.0.113.25 2001:db8:1::25

Two caveats. The lowercase hostname -i is a different command: it resolves the machine's hostname through /etc/hosts and DNS, which on Debian and Ubuntu usually yields 127.0.1.1. And hostname -I prints addresses in no guaranteed order, virtual bridges such as docker0 included, so hostname -I | awk '{print $1}' is a shortcut for humans, not a reliable "primary IP" for scripts. The option is not POSIX: Debian, Ubuntu, Fedora and RHEL have it, minimal BusyBox-based images such as Alpine may not.

ifconfig, nmcli and networkctl

ifconfig (deprecated, net-tools)

ifconfig is what older tutorials show. It belongs to net-tools, deprecated in favour of iproute2 for years and no longer in the default install of current Ubuntu, Debian and Fedora/RHEL releases. If it returns command not found, switch to ip or install the package:

sudo apt install net-tools     # Debian / Ubuntu
sudo dnf install net-tools     # Fedora / RHEL / Rocky / Alma
$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 203.0.113.25  netmask 255.255.255.0  broadcast 203.0.113.255
        inet6 fe80::5054:ff:fe12:3456  prefixlen 64  scopeid 0x20<link>

Readable, but with a real limitation: ifconfig shows only one IPv4 address per interface. Secondary addresses added with ip addr add, common on a VPS with several public IPs, are invisible to it.

nmcli and networkctl

Desktops and Fedora/RHEL-family servers manage their network with NetworkManager; Ubuntu Server uses netplan on top of systemd-networkd, and many VPS images follow the same model. Each has a status tool that shows address, gateway and DNS in one block:

nmcli device show eth0
nmcli -g IP4.ADDRESS device show eth0     # NetworkManager: just the address field
networkctl status eth0                    # systemd-networkd

The -g (--get-values) flag prints the bare value of one field, prefix length included, which is handy for scripts. If you are not sure which stack your machine runs, or even which distribution and release it is, identify the OS version from the command line first; the answer decides which tool is present.

Find your public IP address with curl

Everything above reports the address configured on the interface. On most VPS the public IPv4 is assigned directly to the interface, so that is also what the internet sees. At home, in an office or on some clouds, the interface carries a private address from the RFC 1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and a router or a 1:1 NAT translates it on the way out. The only reliable way to see the public side is to ask an external service:

curl -4 icanhazip.com
curl -4 ifconfig.me/ip
curl -4 https://api.ipify.org
curl -6 icanhazip.com          # public IPv6, if the host has one

The -4 and -6 flags force the address family, which matters on dual-stack hosts: without them curl may prefer IPv6 and return an address you did not expect. icanhazip.com has been operated by Cloudflare since 2021 and returns plain text. Read the answer as "the address my traffic leaves from": behind a VPN or a proxy it is the exit node's address, not your ISP's.

IPv6: global versus link-local

Almost every Linux interface shows at least one inet6 line, and it is often mistaken for a public IPv6 address. The line beginning with fe80:: and marked scope link is link-local: every interface generates one automatically, it is valid only on the attached network, and it is never reachable from the internet. A public IPv6 address is marked scope global and starts with a 2 or a 3, since global unicast space is 2000::/3.

ip -6 addr show scope global
ip -6 route show default

If the first command prints nothing, the machine has no routable IPv6 and curl -6 will fail. Extra global addresses flagged temporary on a desktop come from privacy extensions; servers keep those off so the address stays stable for DNS and firewall rules.

Default gateway, route and DNS

An address on its own does not tell you whether the machine can reach anything. The routing table does, and ip route (short form ip r) prints it:

$ ip route
default via 203.0.113.1 dev eth0 proto static
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.25

The default via line is the default gateway, the router every packet uses when no more specific route matches. The second line was added by the kernel when the address was configured; its src field is the address the host prefers as a source on that network. The most useful trick here builds on that: ask the kernel which address it would use for a given destination.

$ ip route get 1.1.1.1
1.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.25 uid 1000
    cache

That src value is, by definition, the machine's outbound address toward the internet, whatever interfaces, bridges or tunnels exist. For DNS, /etc/resolv.conf is still the place to look, but on systems running systemd-resolved (Ubuntu since 18.04, recent Fedora) it only contains the local stub 127.0.0.53; the real upstream resolvers are shown by resolvectl status, or by the IP4.DNS fields of nmcli device show on NetworkManager hosts.

Scripting: put the IP address in a variable

Interactive output is designed for humans; a script needs one address with nothing around it. These patterns hold up, from the simplest to the most robust:

# One interface, IPv4, prefix length stripped
IP=$(ip -4 -o addr show dev eth0 | awk '{print $4}' | cut -d/ -f1)

# Robust: the source address used to reach the internet
IP=$(ip route get 1.1.1.1 | awk '{for (i=1; i<=NF; i++) if ($i == "src") {print $(i+1); exit}}')

# Same thing with JSON output and jq
IP=$(ip -j route get 1.1.1.1 | jq -r '.[0].prefsrc')

# Public IP, with a timeout so the script never hangs offline
PUBLIC_IP=$(curl -4 -s --max-time 5 https://icanhazip.com)

The -o flag makes ip print one address per line, which keeps the awk field positions safe; add head -n 1 if the interface carries several IPv4 addresses. The -j flag switches ip to JSON output, and jq then picks fields by name. Prefer that form in anything that runs on more than one machine: interface names differ from host to host, field names do not.

CommandWhat it showsBest for
ip addr / ip -br -4 addrEvery interface, all addresses, stateDaily use, the full picture
hostname -IAll addresses on one lineA quick glance
ip route get 1.1.1.1Source address used toward the internetScripts, multi-interface hosts
ifconfigOne IPv4 per interface (deprecated)Legacy systems, old tutorials
curl -4 icanhazip.comPublic IPv4 as the internet sees itNAT, VPN, confirming a VPS address

What changes on a VPS

On a VPS with a dedicated IPv4, ip -4 addr, hostname -I and curl -4 icanhazip.com should all return the same address, because the public IP is configured straight on the interface with no NAT in between. When they disagree, something is in the path: a provider-side NAT, a forgotten VPN client, or a Docker bridge that took the first slot in hostname -I.

Once the address is confirmed, check two things. First, whether it is actually reachable and on which ports, which is a different question from whether it is configured: check the open ports on your Linux server from the inside with ss -tulpn and from the outside with nmap. Second, reverse DNS. Look up the PTR record for your address:

dig -x 203.0.113.25 +short

A fresh VPS usually answers with a generic provider name, or with nothing at all. If the server sends mail or exposes any public service, set the hostname and the reverse DNS so they match; outbound mail in particular is routinely rejected when the PTR record and the HELO name disagree.

These commands become reflexes fastest on a server whose address is yours alone and does not move. A Linux VPS from rdp.monster comes with a dedicated IPv4, full root access, dedicated CPU and RAM, unlimited (fair-use) bandwidth and no KYC, with crypto accepted, from $8.99/month. The server is online about 10 seconds after payment confirms, so the first ip -br -4 addr you run on it is only a moment away.

Frequently Asked Questions

Why does hostname -I show more than one IP address?

It lists every configured address on every interface, virtual bridges included.
hostname -I prints all addresses on all interfaces except loopback and IPv6 link-local ones, so a machine with Docker, libvirt, a VPN client or a second network card shows several. docker0 contributes 172.17.0.1, virbr0 typically 192.168.122.1, and a dual-stack host adds its global IPv6 address. The order is not guaranteed. When you need the address your traffic really leaves from, run ip route get 1.1.1.1 and read its src field instead.

Why does ifconfig say command not found on Ubuntu?

ifconfig belongs to net-tools, which current distributions no longer install by default.
The ifconfig command is part of the net-tools package, deprecated in favour of iproute2 and absent from the default install of current Ubuntu, Debian and Fedora/RHEL releases. The replacement is ip addr, which is available everywhere. If a script or an old habit really requires it, install the package with sudo apt install net-tools or sudo dnf install net-tools, keeping in mind that ifconfig shows only one IPv4 per interface and hides secondary addresses added with ip addr add.

Why does hostname -i return 127.0.1.1?

Lowercase -i resolves the hostname through /etc/hosts, where Debian-based systems map it to 127.0.1.1.
hostname -i does not inspect the network at all: it resolves the system's hostname the way any application would, through /etc/hosts and then DNS. The Debian and Ubuntu installers add a line mapping the hostname to 127.0.1.1 so the machine can resolve its own name without a network, and that line is what comes back. Use the capital-I form, hostname -I, which reads the real interface addresses, or ip -4 addr for the full detail.

How do I find the IP addresses of other devices on my network?

Read the neighbour table with ip neigh, or sweep the subnet with nmap -sn.
Devices your machine has recently exchanged packets with are in the ARP/neighbour cache, shown by ip neigh show (or arp -a if net-tools is installed). For a complete picture, ping-sweep the subnet: nmap -sn 192.168.1.0/24 lists every host that answers, with names when reverse DNS provides them. Substitute your own network, which you can read from the scope link route in ip route. On a VPS this is rarely useful, and scanning neighbouring addresses may breach your provider's terms.

Adrien Roche, Infrastructure & Hosting Editor

Systems engineer with 10+ years operating Windows Server and Linux fleets. Adrien runs the rdp.monster infrastructure documentation and writes our guides on RDP, VPS hosting, server administration, networking and privacy tooling.

Register to our reseller program

Your information

If you have any question, contact us by clicking here !
Name(Required)
Enter your email address, you must have an account on dashboard.rdp.monster !

Your company

Enter your website address if you have one
Quickly explain how you're going to sell services to your customers. For example, talk to people on forums.

Even monsters love cookies!

We use cookies to enhance your browsing experience, serve personalized ads or content, and analyze our traffic. By clicking "Accept", you consent to our use of cookies.