Alright, let’s talk about ip addr. This is your new best friend, your go-to tool for figuring out why your brilliant server can’t seem to talk to anyone else. It replaces the old ifconfig command, which, while nostalgic, is about as useful as a dial-up modem for managing modern networks. The iproute2 suite of tools (which includes our star, ip) is just better. It’s more powerful, consistent, and actually maintained. So let’s get comfortable with it.

First things first, you need to see what you’re working with. You can’t fix a network interface if you don’t know its name, and the kernel, in its infinite wisdom, gives them truly inspired names like eth0 or, on more modern systems, absolute mouthfuls like enp0s31f6.

Checking Your Current Configuration

Just run ip addr by itself. Go on, do it. I’ll wait.

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether aa:bb:cc:00:11:22 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.42/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 86384sec preferred_lft 86384sec
    inet6 fe80::a8bb:ccff:fe00:1122/64 scope link
       valid_lft forever preferred_lft forever

Let’s break down this word salad. For each interface (like lo and eth0), you get a treasure trove of info:

  • state UP: This is crucial. It means the interface is enabled. If it says state DOWN, the kernel-level switch is flipped off.
  • link/ether aa:bb:cc:00:11:22: That’s your MAC address, the hardware serial number for your network card.
  • inet 192.168.1.42/24: Your IPv4 address and its subnet mask (in CIDR notation, /24 meaning 255.255.255.0). The brd is the broadcast address for that subnet.
  • scope global: This address is valid for communication outside the immediate network. Contrast this with scope host on the loopback, which is only for the machine itself.
  • dynamic: This address was probably handed out by a DHCP server. If you set it manually, it would say static.

Assigning a Static IP Address

DHCP is great until it isn’t. For a server, you usually want a predictable, static address. Here’s how you give eth0 a new identity. The basic syntax is ip addr add <IP/CIDR> dev <device_name>.

# Let's assign the address 192.168.1.100 with a 24-bit subnet mask
$ sudo ip addr add 192.168.1.100/24 dev eth0

Now run ip addr show dev eth0 again. You’ll see your new address listed right alongside the old one.

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether aa:bb:cc:00:11:22 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.42/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 86384sec preferred_lft 86384sec
    inet 192.168.1.100/24 scope global secondary eth0
       valid_lft forever preferred_lft forever

Wait, secondary? Yep. The kernel is perfectly happy to let an interface have multiple IP addresses. This is a feature, not a bug. It’s incredibly useful for things like hosting multiple SSL sites on a single box. To replace the old address, you have to manually remove it first.

Removing an IP Address

Removing an address is just as straightforward. You need to tell it exactly which address to remove from which device.

# First, remove the old dynamic address
$ sudo ip addr del 192.168.1.42/24 dev eth0

# Now, let's say you typo'd the new one or need to change it. Remove that too.
$ sudo ip addr del 192.168.1.100/24 dev eth0

# Now add the correct one, cleanly.
$ sudo ip addr add 192.168.1.101/24 dev eth0

Crucial Pitfall Alert: The ip addr command changes the configuration immediately, but it is not persistent. The moment you reboot, all your carefully crafted changes will vanish, and the system will revert to whatever its default configuration is (e.g., DHCP). This is great for testing and debugging, but for a permanent fix, you must edit the network configuration files for your distribution (/etc/network/interfaces on Debian/Ubuntu, nmcli or systemd-networkd files on others). Consider ip addr your live, in-memory scratchpad.

A Note on the ‘dev’ and ‘scope’ Keywords

You might wonder why the command needs dev eth0. It’s because the IP address doesn’t exist in a vacuum; it must be attached to a specific device (network interface). The scope is also important. For most LAN addresses, you’ll use scope global. The scope link is reserved for link-local addresses (like the IPv6 ones starting with fe80::) which are only valid on the specific physical network segment and aren’t routable. You almost never need to set scope manually, but it’s good to know what it means when you see it.