Guides

Check your IP address on Linux: ip addr, hostname -I and your public IP

ip -brief addr show lists every interface's address; hostname -I prints just the addresses. Neither shows your public IP behind NAT — curl ifconfig.me does.

Published ~6 min read

Short answer: ip -brief addr show lists every interface and its address in one short line each; hostname -I prints just the addresses, nothing else; and neither one tells you your public IP if the server sits behind NAT or a cloud provider’s private network — for that, ask an outside server with curl ifconfig.me.

TaskCommand
Every interface, short formip -brief addr show
Every interface, full detailip addr show
One interface onlyip addr show eth0
Addresses only, no interface nameshostname -I
Default route (which interface faces the internet)ip route get 1.1.1.1
Public IP, as seen from outsidecurl ifconfig.me
Public IP, JSON with more detailcurl ipinfo.io
Who owns a given public IPwhois 203.0.113.10
Legacy tool (often not installed)ifconfig

ip addr: the current tool

short form
ip -brief addr show
Example output
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             203.0.113.10/24 2001:db8::a1b2/64 fe80::be24:11ff:fe02:713b/64
full detail
ip addr show
Example output (one interface, shortened)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether be:24:11:02:71:3b brd ff:ff:ff:ff:ff:ff
    inet 203.0.113.10/24 metric 100 brd 203.0.113.255 scope global dynamic eth0
       valid_lft 3542sec preferred_lft 3542sec
    inet6 2001:db8::a1b2/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 86389sec preferred_lft 14389sec
    inet6 fe80::be24:11ff:fe02:713b/64 scope link
       valid_lft forever preferred_lft forever
  • lo is always the loopback interface, 127.0.0.1 — never your real address, even on the shortest list.
  • The /24 after an address is the subnet mask in CIDR notation, not part of the IP itself.
  • fe80::… is a link-local IPv6 address, generated automatically on every interface and only reachable from the same local network — never the address to give out for anything.
  • dynamic next to an address means DHCP (or, for IPv6, SLAAC) assigned it and it can change; static means it was set by hand in the interface’s own configuration and stays fixed.

One interface by name

Linux
ip addr show eth0
ip -4 addr show eth0    # IPv4 only
ip -6 addr show eth0    # IPv6 only

Interface names vary by provider and image: eth0 is common on KVM virtual machines, Ubuntu’s predictable naming scheme produces names like enp1s0 instead. ip -brief link show lists every interface name that exists on the box before you pick one.

hostname -I: just the addresses

Linux
hostname -I
Example output
203.0.113.10 2001:db8::a1b2 fe80::be24:11ff:fe02:713b%eth0

Capital -I (not the lowercase -i, which does something else entirely and is deprecated) prints every address of every interface as a plain space-separated list — the form to reach for inside a script, since there is nothing to parse out of it:

grab just the first (usually main) IPv4 address
hostname -I | awk '{print $1}'

Your public IP: ask outside the server

ip addr and hostname -I only ever show you the address this machine has, which on a VPS behind a cloud NAT, a home router, or a Docker container is a private address — not what the rest of the internet sees you as. To get that, ask a server outside your own network:

Linux · macOS
curl ifconfig.me
curl -4 ifconfig.me    # force IPv4
curl -6 ifconfig.me    # force IPv6
curl ipinfo.io         # adds city, ASN and organisation as JSON

On a typical KVM VPS, where the public IP is configured directly on the network interface rather than behind NAT, ip addr already shows the same address curl ifconfig.me would report — the two only diverge behind NAT or a cloud load balancer. The my IP tool runs the same outside check from a browser, with no terminal needed, and shows IPv4 and IPv6 side by side.

Which interface actually talks to the internet?

Linux
ip route get 1.1.1.1
Example output
1.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.10 uid 0
    cache

On a server with one network card this is obvious, but on anything with several (a VPN interface, a Docker bridge, a second NIC on an internal VLAN) this is the reliable way to find the one your traffic actually leaves through, and the src field is the address it leaves with — which is the address a remote server sees, regardless of what any other interface shows.

ifconfig still works, where it is installed

if net-tools is installed
ifconfig

ifconfig is the older BSD-style tool and is not installed by default on current Debian, Ubuntu, Rocky or AlmaLinux minimal images — it ships in the net-tools package, which the ip command (from iproute2) replaced over a decade ago in every Linux distribution’s own documentation. If a script or an old habit still needs it, ifconfig: command not found has the install line for each distribution; for anything new, write ip commands instead.

Checking that a domain actually points at this IP

Knowing the server’s own IP is usually step one of pointing a domain at it or checking that DNS has caught up:

Linux · macOS · Windows
dig +short example.com
nslookup example.com

Pointing a domain at a VPS covers the DNS side end to end, from the A record to waiting out the TTL.

Using the address in a script

common patterns
PUBLIC_IP=$(curl -s ifconfig.me)
LOCAL_IP=$(hostname -I | awk '{print $1}')
MAIN_IP=$(ip -4 -j addr show eth0 | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['addr_info'][0]['local'])")

-j on any ip subcommand prints JSON instead of the usual text, which is worth reaching for the moment a script needs to pick one specific field reliably rather than parsing columns that can shift between distributions.

Frequently asked

What is the quickest command to see my IP address on Linux?

ip -brief addr show lists every interface with its address on one short line each. hostname -I is shorter still when you only need the addresses themselves, with no interface names, which also makes it the easier one to use inside a script.

Why does ip addr show a different IP than curl ifconfig.me?

ip addr only ever shows the address assigned to this machine's own network interface, which behind NAT — a home router, a cloud load balancer, a Docker container — is a private address, not what the rest of the internet sees. curl ifconfig.me asks a server outside your network and reports the address it saw you connect from, which is the real public IP in that case.

Why is ifconfig not found on my server?

ifconfig ships in the net-tools package, which current Debian, Ubuntu, Rocky and AlmaLinux minimal images do not install by default — it was replaced by the ip command (from iproute2) in every current distribution's own documentation over a decade ago. Install net-tools if a script still needs it specifically, or rewrite the script around ip.

How do I find which network interface actually reaches the internet?

ip route get 1.1.1.1 shows the interface and source address your traffic really leaves through, which matters once a server has more than one network interface — a VPN, a Docker bridge, a second NIC — and the obvious-looking first interface in the list is not necessarily the one in use.

Related articles

All guides