Network basics from the terminal: ip, ss, nmcli, resolvectl
Find your address and interface, see which ports are open, set a static IP, and check DNS.
Part 11 of 12 in Linux basics for self-hosters. Last updated
In short: ip -br a lists every interface with its addresses, ip r shows the default gateway, and sudo ss -tlnp shows which programs listen on which TCP ports. Changes made with ip addr are lost at reboot; make a static address permanent with nmcli con mod on NetworkManager systems. For DNS, cat /etc/resolv.conf only tells the truth when it does not say 127.0.0.53; if it does, systemd-resolved is in charge and resolvectl status shows the real servers.
ip: interfaces, addresses and routes
ip -br a # brief: one line per interface
ip -br link # interfaces with MAC address and state
ip -4 a show scope global # only real IPv4 addresses
ip r # routes; the "default via" line is your gateway
ip neigh # other machines this one talked to recently (ARP) lo UNKNOWN 127.0.0.1/8 ::1/128
enp3s0 UP 192.168.1.50/24 fe80::5054:ff:fe12:3456/64
wlp2s0 DOWN
default via 192.168.1.1 dev enp3s0 proto dhcp metric 100
192.168.1.0/24 dev enp3s0 proto kernel scope link src 192.168.1.50 metric 100
Interfaces have predictable names such as enp3s0 (wired, PCI bus 3, slot 0) or
wlp2s0 (wireless). The old eth0 and wlan0 only show up in
virtual machines and old guides. The /24 after the address is the netmask:
the first 24 bits are the network, so every 192.168.1.x is local. Reference:
ip(8).
The same two commands on a laptop on Wi-Fi, with the wired port unplugged:
$ ip -4 -br addr
lo UNKNOWN 127.0.0.1/8
wlp0s20f3 UP 10.0.0.99/24
$ ip route
default via 10.0.0.254 dev wlp0s20f3 proto static metric 600
10.0.0.0/24 dev wlp0s20f3 proto kernel scope link src 10.0.0.99 metric 600 Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
ss: which ports are open?
sudo ss -tlnp # TCP ports in LISTEN, with the program
sudo ss -ulnp # the same for UDP
ss -tn state established # open connections right now
sudo ss -tlnp 'sport = :443' # who listens on port 443? State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("rootlessport",pid=2311,fd=10)) -t TCP, -u UDP, -l listening, -n numbers
instead of names, -p the process (needs sudo for other users' programs). The
local address is the important column: 0.0.0.0 or [::] accepts
connections from the network, 127.0.0.1 only from this machine. Rootless podman
containers show up as rootlessport or pasta. Reference:
ss(8).
Try it with a throwaway web server bound to localhost: ss shows who listens, curl proves it answers, and a port nobody listens on is refused at once:
$ python3 -m http.server 8765 --bind 127.0.0.1 >/dev/null 2>&1 &
$ ss -tlnp 'sport = :8765'
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 5 127.0.0.1:8765 0.0.0.0:* users:(("python3",pid=3111442,fd=3))
$ curl -sI http://127.0.0.1:8765/ | head -3
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.13.14
Date: Mon, 28 Sep 2026 04:36:01 GMT
$ timeout 3 bash -c '</dev/tcp/127.0.0.1/9'; echo "exit=$?"
bash: connect: Connection refused
bash: line 1: /dev/tcp/127.0.0.1/9: Connection refused
exit=1 Real output on openSUSE Tumbleweed, Python 3.13, 2026-09-28; user and host names and addresses redacted.
A static IP that survives a reboot
sudo ip addr add 192.168.1.50/24 dev enp3s0 works instantly and is gone at the next
reboot, or even sooner when NetworkManager renews the connection. For a permanent address, tell
the program that manages the network. On openSUSE Tumbleweed, Leap 16, Fedora and desktop
Ubuntu that is NetworkManager:
nmcli con show # connection names, e.g. "Wired connection 1"
sudo nmcli con mod "Wired connection 1" \
ipv4.method manual \
ipv4.addresses 192.168.1.50/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "192.168.1.2 9.9.9.9"
sudo nmcli con up "Wired connection 1" # apply it
Doing this over SSH? The connection drops when the address changes, so connect to the new
address afterwards, and try it first on a machine you can reach with a keyboard. Other
network managers: older Leap 15 servers often use wicked, Ubuntu Server uses netplan and
Debian servers often use /etc/network/interfaces. systemctl is-active
NetworkManager tells you whether nmcli applies. Often simpler still: reserve the address
for the machine's MAC address in your router's DHCP settings and leave the server on DHCP. See
nmcli(1).
DNS: which server am I using?
cat /etc/resolv.conf # nameserver lines, unless it says 127.0.0.53
resolvectl status # with systemd-resolved: real servers per interface
nmcli -g IP4.DNS dev show enp3s0 # what NetworkManager handed out
getent hosts example.com # resolve a name the way programs do
dig example.com # detailed answer (package bind-utils or dnsutils)
dig @9.9.9.9 example.com # ask one specific server
Fedora and Ubuntu run systemd-resolved
by default, so /etc/resolv.conf points at the local stub 127.0.0.53
and resolvectl shows the real servers. openSUSE and Debian usually do not, and
there the file itself lists the servers (on openSUSE it is written by netconfig, so do not
edit it by hand). If a self-hosted DNS filter answers for getent but not for
dig @its-address, look at its firewall and listening address first.
On openSUSE without systemd-resolved, the file names the LAN's DNS server directly:
$ grep '^nameserver' /etc/resolv.conf; getent ahostsv4 opensuse.org | head -1
nameserver 10.0.0.10
195.135.223.50 STREAM opensuse.org
$ curl -sS -o /dev/null -w 'HTTP %{http_code} in %{time_total}s\n' https://www.opensuse.org/
HTTP 200 in 0.302128s Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
Testing a connection
ping -c 4 192.168.1.1 # is the gateway reachable?
ping -c 4 example.com # DNS and internet in one go
ping -c 1 -M do -s 1472 example.com # does a full 1500-byte packet pass unfragmented?
tracepath -n example.com # the route, and where the path MTU shrinks
curl -I https://example.com # does the web server answer? headers only
nc -zv 192.168.1.50 22 # is TCP port 22 reachable from here?
Work from the inside out: your own interface, the gateway, an IP on the internet, then a name.
The step that fails tells you whether it is cabling, routing or DNS. The 1472 in the MTU test
is 1500 minus 28 bytes of IP and ICMP headers; -s 1500 would always fail on a normal
link. mtr combines ping and tracepath in one live view if it is installed.
The firewall
A service listening on 0.0.0.0 can still be unreachable because the firewall drops
the traffic. openSUSE and Fedora use firewalld (sudo firewall-cmd --list-all shows
what is open); Ubuntu ships ufw (sudo ufw status), which is off until you turn it on.
The firewalld port helper gives you the commands to
open a port for the LAN only, check it and undo it. For reaching the server from outside your
home, a VPN beats opening ports: the
WireGuard config generator writes both ends,
and the SSH key and config helper sets up key
login once you are in.
Common mistakes
A static address with /32
/32 is a network of exactly one address, so the machine knows no neighbours and
no route to the gateway. A home LAN is almost always /24
(netmask 255.255.255.0).
A service that only listens on 127.0.0.1
If ss -tlnp shows 127.0.0.1:8080, nothing outside the machine can
connect, whatever the firewall says. Change the service's listen address, or for a container
the PublishPort= line (PublishPort=8080:80 publishes on all
addresses, PublishPort=127.0.0.1:8080:80 only locally).
Editing /etc/resolv.conf by hand
NetworkManager, netconfig or systemd-resolved rewrites it at the next change. Set DNS servers
on the connection (ipv4.dns in nmcli) or in the router's DHCP settings instead.
To copy files between machines once the network works, continue with
rsync and tar.
Frequently asked questions
How do I find my IP address in the Linux terminal?
ip -br a prints one line per interface with its state and addresses, for example enp3s0 UP 192.168.1.50/24. ip -4 a show scope global limits it to real IPv4 addresses. Your public internet address is a different thing; your router knows it.
How do I check which ports are open on Linux?
sudo ss -tlnp lists TCP ports in the LISTEN state with the program behind each one; use -ulnp for UDP. An address of 0.0.0.0 or [::] means reachable from the network, 127.0.0.1 means only from the machine itself. A firewall can still block a listening port.
Why does /etc/resolv.conf show 127.0.0.53?
That is the local stub of systemd-resolved, the default on Fedora and Ubuntu. Programs ask it and it forwards to the real DNS servers. Run resolvectl status to see which servers each interface uses.
What replaced ifconfig and netstat?
ip replaces ifconfig and route (ip a, ip r), and ss replaces netstat (ss -tlnp). The old net-tools package is not installed by default on most current distributions.