Linux Networking Basics: ip, nmcli, ss, DNS and Firewalls

Short answer

Four commands answer most "is my network working?" questions: your address, your route to the internet, whether DNS works, and what is listening.

ip -br addr
ip route
resolvectl query example.com
sudo ss -tulpn

Who manages your network?

Before changing anything, find out which tool owns the configuration, because changes made with the wrong tool get overwritten.

SystemUsual network managerDNS resolver
Ubuntu Desktop, MintNetworkManagersystemd-resolved
Ubuntu Servernetplan → systemd-networkdsystemd-resolved
Fedora (all editions)NetworkManagersystemd-resolved
Debian desktopNetworkManagerNetworkManager writes /etc/resolv.conf
Debian minimal/serverifupdown (/etc/network/interfaces)plain /etc/resolv.conf
ArchWhatever you installed (NetworkManager, systemd-networkd or iwd)Your choice
openSUSENetworkManager on desktops; wicked on some server installsnetconfig / NetworkManager
systemctl is-active NetworkManager systemd-networkd
ls -l /etc/resolv.conf
ls /etc/netplan/ 2>/dev/null

If /etc/resolv.conf is a symlink into /run/systemd/resolve/, systemd-resolved is in charge of DNS.

Interfaces, addresses and routes with ip

ip from iproute2 replaces ifconfig, route and arp. Every subcommand can be abbreviated (ip a, ip r) and -br gives a compact view.

ip -br link          # interfaces and up/down state
ip -br addr          # addresses per interface
ip route             # routing table
ip route get 1.1.1.1 # which interface and gateway a packet would use
ip neigh             # ARP/neighbour table

Example output:

lo               UNKNOWN        127.0.0.1/8 ::1/128
enp3s0           UP             192.168.1.42/24 fe80::1c2:3aff:fe4b:9d10/64
wlp2s0           DOWN

How to read it:

  • Interface names are predictable names: en… is Ethernet, wl… is Wi-Fi, lo is loopback. Docker and VPNs add docker0, wg0, tun0 and so on.
  • A 169.254.x.x address means DHCP failed; the interface gave itself a link-local address.
  • No line starting default via in ip route means there's no gateway, so nothing outside your LAN is reachable.

IPv6

Most networks now hand out IPv6 addresses alongside IPv4. Use ip -6 addr and ip -6 route to see them, and ping -6 or curl -6 to test. If some sites load slowly or time out while others work, a broken IPv6 path is a common cause: compare curl -4 -I https://example.com with curl -6 -I https://example.com. Fix the router or disable IPv6 for that one connection with nmcli connection modify <name> ipv6.method disabled rather than system-wide.

Temporary changes, useful for testing, are lost on reboot:

sudo ip link set enp3s0 up
sudo ip addr add 192.168.1.50/24 dev enp3s0
sudo ip route add default via 192.168.1.1

NetworkManager with nmcli

On desktops, Fedora and most laptops, make permanent changes with nmcli (or nmtui for a text menu). Settings are stored as connection profiles.

nmcli general status
nmcli device status
nmcli connection show
nmcli device wifi list
nmcli device wifi connect "MyNetwork" --ask
nmcli connection down "MyNetwork"
nmcli connection up "MyNetwork"

Set a static IP address

nmcli connection show            # find the profile name, e.g. "Wired connection 1"
sudo nmcli connection modify "Wired connection 1" \
  ipv4.method manual \
  ipv4.addresses 192.168.1.50/24 \
  ipv4.gateway 192.168.1.1 \
  ipv4.dns "192.168.1.1 9.9.9.9"
sudo nmcli connection up "Wired connection 1"
# back to DHCP
sudo nmcli connection modify "Wired connection 1" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""

Doing this over SSH will drop your session if the new address is wrong; do it from the console or have a way back in. Wi-Fi problems such as missing adapters or firmware are covered in fixing Wi-Fi on Linux and, for Ubuntu specifically, Ubuntu Wi-Fi fixes.

Ubuntu Server: netplan

Ubuntu Server describes the network in YAML under /etc/netplan/:

network:
  version: 2
  ethernets:
    enp3s0:
      addresses: [192.168.1.50/24]
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses: [192.168.1.1, 9.9.9.9]
sudo chmod 600 /etc/netplan/*.yaml
sudo netplan try      # applies, then rolls back after 120 s unless you confirm
sudo netplan apply

netplan try is the safe option over SSH. On Ubuntu Desktop, netplan hands everything to NetworkManager, so use nmcli there.

Open ports and connections with ss

ss replaces netstat. The flag set worth memorising is -tulpn: TCP, UDP, listening, process, numeric.

sudo ss -tulpn                  # what's listening and which program owns it
ss -tn state established        # active TCP connections
sudo ss -tlpn 'sport = :80'     # who is on port 80?
sudo lsof -i :8080              # alternative, if lsof is installed

Example output:

Netid State  Local Address:Port  Peer Address:Port Process
tcp   LISTEN 0.0.0.0:22          0.0.0.0:*         users:(("sshd",pid=812,fd=3))
tcp   LISTEN 127.0.0.1:5432      0.0.0.0:*         users:(("postgres",pid=990,fd=6))

Test a port from another machine

ss only shows that something is listening. To check whether the port is actually reachable through firewalls and routers, test from a second machine:

nc -zv 192.168.1.42 22            # TCP connect test (package netcat-openbsd / nmap-ncat / openbsd-netcat)
curl -I http://192.168.1.42:8080  # for HTTP services
nmap -p 22,80,443 192.168.1.42    # several ports at once

"Connection refused" means the packet arrived but nothing is listening on that address; a timeout usually means a firewall dropped it.

The local address tells you who can reach the service: 0.0.0.0 or [::] means all interfaces, 127.0.0.1 means only this machine. A service bound to localhost can't be reached from the network no matter what the firewall says. If a program fails to start because the port is taken, see bind: Address already in use; if SSH is refused, see ssh: Connection refused.

DNS: resolvectl, dig and /etc/hosts

resolvectl status               # per-interface DNS servers (systemd-resolved)
resolvectl query archlinux.org  # resolve through the system resolver
dig archlinux.org +short        # query directly (package dnsutils / bind-utils / bind)
dig @9.9.9.9 archlinux.org      # bypass your configured server
getent hosts archlinux.org      # resolve exactly as applications do, including /etc/hosts
sudo resolvectl flush-caches

If dig @9.9.9.9 works but normal lookups don't, the problem is your configured DNS server, not your connection. Change it per connection with nmcli connection modify <name> ipv4.dns "9.9.9.9" ipv4.ignore-auto-dns yes, or in netplan. Don't hand-edit /etc/resolv.conf when it's managed; your edit will be overwritten. The full fix list for lookups failing is in Temporary failure in name resolution.

Hostname

hostnamectl                       # current hostname, OS and kernel
sudo hostnamectl set-hostname nas # change it permanently

Update the matching line in /etc/hosts (on Debian and Ubuntu, 127.0.1.1 oldname) after renaming, or sudo may pause while it tries to resolve the old name.

/etc/hosts overrides DNS for specific names on this machine, for example 192.168.1.10 nas.home.

Firewalls: ufw, firewalld and nftables

All current distributions use the kernel's nftables framework underneath; the friendly front end differs.

TaskUbuntu / Mint (ufw)Fedora / openSUSE (firewalld)
Statussudo ufw status verbosesudo firewall-cmd --list-all
Enablesudo ufw enablesudo systemctl enable --now firewalld
Allow SSHsudo ufw allow OpenSSHsudo firewall-cmd --permanent --add-service=ssh
Allow a portsudo ufw allow 8080/tcpsudo firewall-cmd --permanent --add-port=8080/tcp
Remove a rulesudo ufw delete allow 8080/tcpsudo firewall-cmd --permanent --remove-port=8080/tcp
Apply permanent rulesimmediatesudo firewall-cmd --reload
  • Ubuntu ships ufw but leaves it disabled. Allow SSH before ufw enable on a remote machine.
  • Fedora Workstation uses the FedoraWorkstation zone, which already allows high ports (1025–65535) for local development; Fedora Server is stricter.
  • Debian and Arch install no firewall by default. Install ufw or firewalld, or write /etc/nftables.conf and enable nftables.service.
  • Docker inserts its own rules for published ports, which ufw doesn't see; see the Docker page.

To see the real ruleset regardless of front end: sudo nft list ruleset.

Diagnosing "no internet" step by step

Work outward from your machine; the first step that fails is where the problem is.

  1. Link: ip -br link. Interface DOWN or missing points to cable, Wi-Fi or driver.
  2. Address: ip -br addr. No address or 169.254.x.x means DHCP failed: nmcli connection up <name> and check the router.
  3. Gateway: ip route, then ping -c3 <gateway>.
  4. Internet by IP: ping -c3 1.1.1.1. Fails while the gateway works: router, ISP, VPN or firewall.
  5. DNS: resolvectl query example.com or getent hosts example.com. IP works but names don't: DNS.
  6. Path: tracepath example.com or mtr example.com shows where packets stop.
  7. The service itself: curl -v https://example.com shows TLS, proxy and HTTP errors.

Logs for the network stack:

journalctl -b -u NetworkManager
journalctl -b -u systemd-resolved
journalctl -b -u systemd-networkd

Use the journalctl cheat sheet to filter these, and the ssh cheat sheet once the network is up and you want to reach other machines.

Installing the tools

ip and ss are always present. The rest may need installing:

# Ubuntu, Debian, Mint
sudo apt install dnsutils traceroute mtr-tiny nmap
# Fedora
sudo dnf install bind-utils traceroute mtr nmap
# Arch
sudo pacman -S bind traceroute mtr nmap
# openSUSE
sudo zypper install bind-utils traceroute mtr nmap

Only scan networks you own or are allowed to test with nmap.

Frequently asked questions

What replaced ifconfig on Linux?

The ip command from iproute2. ip addr shows addresses, ip link shows interfaces and ip route shows routes. ifconfig is in the optional net-tools package and no longer installed by default.

How do I see which ports are open on Linux?

Run sudo ss -tulpn. It lists listening TCP and UDP sockets with the program that owns each one. Whether those ports are reachable from outside also depends on the firewall.

Why does /etc/resolv.conf point to 127.0.0.53?

On systems using systemd-resolved (Ubuntu, and Fedora by default), applications ask a local stub resolver at 127.0.0.53, which forwards to the real DNS servers. Run resolvectl status to see those upstream servers.

Are ip command changes permanent?

No. Addresses and routes added with ip are lost at reboot or when NetworkManager reconfigures the interface. Make permanent changes with nmcli, netplan, or your distribution's network configuration.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.