Linux Networking Cheat Sheet

Linux networking commands by symptom: ip and ss, DNS with dig and resolvectl, persistent configuration with nmcli, netplan or networkd, firewalld and ufw, and tcpdump.

Start by symptom

No address
ip -br a
No route out
ip r
Name does not resolve
dig host +short
Port refuses the connection
ss -tulpn
Packets disappear
tcpdump -i any -nn host X
Works locally, blocked from outside
firewalld or ufw
ifconfig, netstat and route are gone. They belong to the unmaintained net-tools package and are not installed by default on RHEL 8 and later, on recent Ubuntu, or on most appliances. The replacements are ip and ss, and they report more.

Addresses, links and routes

TaskCommand
Everything, one line per interfaceip -br a
Full detailip a
One interfaceip a show eth0
Link state, speed and MACip -br link
Interface counters, errors and dropsip -s link show eth0
Routing tableip r
Which route will be used for a targetip route get 8.8.8.8
Neighbours, the ARP cacheip neigh
Clear one neighbour entryip neigh del 10.0.0.1 dev eth0
Bring an interface up or downip link set eth0 up
Add an address, until rebootip addr add 10.0.0.5/24 dev eth0
Add a route, until rebootip route add 10.20.0.0/16 via 10.0.0.1
Negotiated speed and duplexethtool eth0
Driver level error countersethtool -S eth0
ip changes are not persistent. Anything set with ip addr or ip route is gone at the next reboot or the next time the network service restarts. Use it to test, then write the change into the distribution’s own configuration, which is the next section.

Sockets and ports

TaskCommand
What is listening, with the processss -tulpn
Established connectionsss -tnp state established
One portss -tulpn sport = :443
Connections to one hostss -tn dst 10.0.0.50
Summary counts by statess -s
Is the port reachable from heretimeout 3 bash -c "</dev/tcp/10.0.0.50/443" && echo open
Same, if netcat is installednc -zv 10.0.0.50 443
Which process holds a file or socketlsof -i :443
The ss flags read as words. -t TCP, -u UDP, -l listening, -p process, -n numeric. -tulpn is simply all of them, and it is the one form worth memorising.

DNS

TaskCommand
Just the answerdig example.com +short
One record typedig MX example.com
Ask a specific serverdig @10.0.0.10 host.corp.local
Reverse lookupdig -x 10.0.0.25 +short
Follow the delegation from the rootdig +trace example.com
Quick answer without dighost example.com
What the resolver is configured withcat /etc/resolv.conf
With systemd-resolved, the real pictureresolvectl status
Resolve through systemd-resolvedresolvectl query host.corp.local
Flush the resolver cacheresolvectl flush-caches
Order of hosts file versus DNS/etc/nsswitch.conf
/etc/resolv.conf is often a lie. On Ubuntu and anything with systemd-resolved it is a symlink to a stub listing 127.0.0.53, and the real upstream servers only show in resolvectl status. Editing the file by hand is overwritten on the next network change. dig is installed by the bind-utils package on the RHEL family and dnsutils on Debian and Ubuntu.

Making it persistent, by distribution

DistributionWhat manages the network
RHEL, Rocky, AlmaLinux, FedoraNetworkManager, driven by nmcli
Ubuntu Server 18.04 and laternetplan, YAML in /etc/netplan/
Ubuntu Desktopnetplan on top of NetworkManager, so nmcli works too
Debian/etc/network/interfaces, or netplan on newer images
SLES and openSUSEwicked, or YaST
Photon OS, including the vCenter appliancesystemd-networkd, files in /etc/systemd/network/
NetworkManager task, RHEL familyCommand
Devices and their statenmcli device status
Connection profilesnmcli connection show
Details of one profilenmcli connection show "ens192"
Set a static addressnmcli con mod "ens192" ipv4.method manual ipv4.addresses 10.0.0.5/24 ipv4.gateway 10.0.0.1 ipv4.dns "10.0.0.10"
Back to DHCPnmcli con mod "ens192" ipv4.method auto
Apply the changenmcli con down "ens192" then nmcli con up "ens192"
Add a static routenmcli con mod "ens192" +ipv4.routes "10.20.0.0/16 10.0.0.1"
Set the hostnamehostnamectl set-hostname srv01.corp.local

Ubuntu Server, /etc/netplan/01-netcfg.yaml. Indentation is two spaces and it matters.

network:
  version: 2
  ethernets:
    ens192:
      addresses: [10.0.0.5/24]
      routes:
        - to: default
          via: 10.0.0.1
      nameservers:
        addresses: [10.0.0.10, 10.0.0.11]
        search: [corp.local]
netplan taskCommand
Apply with an automatic rollback if you lose the sessionnetplan try
Apply for realnetplan apply
Show the merged configurationnetplan get
Use netplan try over a remote session. It reverts after 120 seconds unless you confirm, which is the difference between a typo you undo and a trip to the console. The gateway4 key you may see in older guides is deprecated: use the routes form above.

Firewall, by distribution

Taskfirewalld, RHEL familyufw, Ubuntu
Is it runningfirewall-cmd --stateufw status
Full current rulesfirewall-cmd --list-allufw status verbose
Open a portfirewall-cmd --add-port=8443/tcp --permanentufw allow 8443/tcp
Open a named servicefirewall-cmd --add-service=https --permanentufw allow https
Limit to a source networkfirewall-cmd --zone=internal --add-source=10.0.0.0/24 --permanent then --zone=internal --add-port=22/tcp --permanentufw allow from 10.0.0.0/24 to any port 22
Applyfirewall-cmd --reloadimmediate
Remove a rulefirewall-cmd --remove-port=8443/tcp --permanentufw delete allow 8443/tcp
Which zone is this interface infirewall-cmd --get-active-zonesno zones, ufw is flat
Underneath bothCommand
The actual ruleset on modern systemsnft list ruleset
Legacy view, where iptables still existsiptables -L -n -v
Is anything dropping, with countersnft list ruleset | grep -i drop
Without –permanent the rule dies at reload. firewalld keeps a runtime set and a permanent set. Add a rule permanently and reload, or add it at runtime to test and then promote it with firewall-cmd --runtime-to-permanent.

Path and capture

TaskCommand
Trace the pathtraceroute -n 8.8.8.8
Same, without extra packagestracepath 8.8.8.8
Continuous path and lossmtr -n 8.8.8.8
Watch traffic on a porttcpdump -i any -nn port 443
Watch one host, stop after 100 packetstcpdump -i any -nn host 10.0.0.50 -c 100
Write a capture for Wiresharktcpdump -i any -nn -w /tmp/cap.pcap host 10.0.0.50
Read it backtcpdump -nn -r /tmp/cap.pcap
See the payload as texttcpdump -i any -nnA port 80
Test an HTTP endpointcurl -I https://example.com
Test TLS and see the certificateopenssl s_client -connect host:443 -servername host
-nn twice is deliberate. One n stops host name lookups, the second stops port name lookups. On a box with broken DNS, a plain tcpdump appears to hang while it tries to resolve every address it sees.

Symptom to command

SymptomRun this, in order
No address at allip -br link for carrier, then journalctl -u NetworkManager or -u systemd-networkd
Address but nothing routesip r for a default route, then ip route get for the target
Ping by IP works, names faildig @server name, resolvectl status, /etc/nsswitch.conf
Connection refusedss -tulpn on the server: nothing is listening, or it listens on 127.0.0.1 only
Connection times outFirewall. firewall-cmd --list-all or ufw status, then nft list ruleset
Works locally, not from another subnetRouting or the service bound to the wrong address. Check both ends with tcpdump.
Slow or lossyip -s link for drops, ethtool eth0 for a duplex mismatch, then mtr
Config survives a test but not a rebootYou used ip addr add. Write it into nmcli, netplan or networkd.
Two interfaces, traffic leaves the wrong oneip route get target, then compare route metrics

FAQ

The service is listening but nobody can connect.
Read the local address in ss -tulpn. If it says 127.0.0.1:8080 the service is bound to loopback only and no firewall change will help; the fix is in the application configuration. 0.0.0.0:8080 or *:8080 means it listens everywhere, and then it is the firewall or routing.
Which file do I edit to change the IP?
It depends on the distribution, which is the whole problem. RHEL family: nmcli. Ubuntu Server: the YAML in /etc/netplan/. Debian: /etc/network/interfaces. Photon OS and the vCenter appliance: /etc/systemd/network/. Editing the wrong one changes nothing and looks like the system ignoring you.
I changed resolv.conf and it reverted.
Something owns that file: systemd-resolved, NetworkManager or the DHCP client. Set DNS where the network is configured instead, with nmcli con mod ... ipv4.dns or the nameservers block in netplan.
Is there an equivalent of Test-NetConnection?
Not as one command. nc -zv host port comes closest when netcat is installed, and bash can do it with no packages at all: timeout 3 bash -c "</dev/tcp/host/port" returns success if the port accepts. For the full picture combine ip route get, dig and ss.
Can I capture traffic on a VM without installing anything?
tcpdump is present on most server images and is the right tool inside the guest. If the traffic never reaches the guest, capture on the ESXi host instead with pktcap-uw, because the problem is then the portgroup, the vSwitch or the physical uplink.