Andrey's Blog

Linux: Network and Its Configuration

Table of Contents

  1. Networks, Packets and Layers
  2. IPv4 Addresses and Subnets
  3. Subnet Math (CIDR)
  4. Routing
  5. IPv6
  6. Basic ICMP and DNS Tools
  7. Name Resolution
  8. Transport Layer: TCP, UDP and Ports
  9. DHCP
  10. NetworkManager
  11. NAT
  12. Firewalls
  13. Cheat Sheet

1. Networks, Packets and Layers

A typical LAN

A local area network (LAN) connects hosts to each other. A router connects the LAN to other networks, such as the internet, through its uplink.

                                                 .───────────.
                                                (  Internet   )
                                                 '─────┬─────'
                       LAN                             │ Uplink
                        │                              │
                        ▼                              │
     ┌──────────────┬──────────────┬─────────────┐     │
     │              │              │             │     │
┌────┴────┐    ┌────┴────┐    ┌────┴────┐    ┌───┴─────┴──┐
│ Host A  │    │ Host B  │    │ Host C  │    │   Router   │
└─────────┘    └─────────┘    └─────────┘    └────────────┘

Packets

Data travels in small chunks called packets. Each packet has:

Splitting data into packets lets many hosts share the same network and lets lost pieces be re-sent individually.

Network layers

Networking is split into layers. Each layer only talks to the layer directly above and below it.

Layer (book / TCP/IP model)OSIWhat it doesExamples
ApplicationL7The “language” applications speakHTTP, SSH, DNS, TLS
TransportL4Data delivery between applications on two hosts (ports)TCP, UDP
Network / InternetL3Moving packets between hosts, across networksIP, ICMP
Physical (+ link)L1–L2Sending bits over a medium and frames on the local linkEthernet, Wi-Fi, MAC addresses, ARP

When data is sent, each layer wraps the data from the layer above with its own header (encapsulation). The receiver unwraps the headers in reverse order.

Application:                               ┌──────────────────┐
                                           │ HTTP request     │
                                           └──────────────────┘
Transport:                    ┌────────────┬──────────────────┐
                              │ TCP header │      data        │   segment
                              │ (ports)    │                  │
                              └────────────┴──────────────────┘
Network:          ┌───────────┬────────────┬──────────────────┐
                  │ IP header │ TCP header │      data        │   packet
                  │ (IP addrs)│            │                  │
                  └───────────┴────────────┴──────────────────┘
Link:  ┌──────────┬───────────┬────────────┬──────────────────┬─────┐
       │ Ethernet │ IP header │ TCP header │      data        │ FCS │   frame
       │ (MACs)   │           │            │                  │     │
       └──────────┴───────────┴────────────┴──────────────────┴─────┘

2. IPv4 Addresses and Subnets

Subnets

The internet’s topology is decentralized. It’s made up of smaller networks called subnets, all interconnected in some way. A LAN is normally a single subnet.

                                                     .───────────.
                       Subnet 10.23.2.0/24 (LAN)    (  Internet   )
                                  │                  '─────┬─────'
                                  ▼                        │
     ┌───────────────┬────────────────┬─────────────┐      │
     │               │                │             │      │
┌────┴──────┐   ┌────┴──────┐   ┌─────┴──────┐   ┌──┴──────┬┴───────┐
│ 10.23.2.4 │   │10.23.2.37 │   │10.23.2.132 │   │10.23.2.1│ Uplink │
├───────────┤   ├───────────┤   ├────────────┤   │         │ Address│
│  Host A   │   │  Host B   │   │   Host C   │   ├─────────┴────────┤
└───────────┘   └───────────┘   └────────────┘   │      Router      │
                                                 └──────────────────┘

The router has two addresses: one inside the LAN (10.23.2.1) and one on its uplink.

Viewing addresses

ip address show        # short: ip a
ip -br address         # brief, one line per interface
2: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP ...
   │          └─────────────┬─────────────────┘ └──┬───┘                 └┬─┘
   │                 interface flags (UP = on)   max packet size    link is up
   └─ interface name
    link/ether 3c:58:c2:aa:bb:cc brd ff:ff:ff:ff:ff:ff
               └──────┬────────┘
               MAC address (layer 2)
    inet 192.168.1.10/24 brd 192.168.1.255 scope global dynamic wlp0s20f3
         └──────┬──────┘     └─────┬─────┘                └──┬──┘
         IPv4 address/prefix   broadcast             assigned by DHCP
    inet6 fe80::1a2b:3c4d:5e6f:7a8b/64 scope link
          └────────────┬─────────────┘    └─┬──┘
           IPv6 address                link-local only

Special and private address ranges

RangePurpose
10.0.0.0/8Private (RFC 1918)
172.16.0.0/12Private (RFC 1918)
192.168.0.0/16Private (RFC 1918), typical for home networks
127.0.0.0/8Loopback (127.0.0.1 = this machine)
169.254.0.0/16Link-local: self-assigned when DHCP fails
100.64.0.0/10Carrier-grade NAT (also used by Tailscale)

Private addresses are not routed on the internet. To get out, they need NAT (see section 11).

What the subnet mask is for

The subnet mask lets every device answer one question before it sends a packet: is the destination on my local network, or somewhere else?

An IPv4 address is 32 bits. The mask says how many of those bits identify the network and how many identify the host within it.

192.168.1.10/24   (mask 255.255.255.0)

  11000000.10101000.00000001 . 00001010
  └────────── 24 bits ─────┘   └─8 bits┘
         network: 192.168.1     host: .10

How a host uses it

To reach another IP, the host ANDs both addresses with its mask and compares the results:

Me:      192.168.1.10  AND 255.255.255.0 = 192.168.1.0
Target:  192.168.1.50  AND 255.255.255.0 = 192.168.1.0   → same network
Target:  8.8.8.8       AND 255.255.255.0 = 8.8.8.0       → different network
                 Packet to send to IP X
                           │
                           ▼
          ┌────────────────────────────────────┐
          │  (my IP AND mask) == (X AND mask) ?│
          └────────┬──────────────────┬────────┘
               yes │                  │ no
                   ▼                  ▼
     ┌─────────────────────────┐ ┌──────────────────────────┐
     │ Same network            │ │ Different network        │
     │ ARP: "who has X?"       │ │ Send to default gateway  │
     │ → get X's MAC address   │ │ (ARP for the router's    │
     │ → send frame directly   │ │  MAC, not X's)           │
     │   via the switch        │ │ → router forwards it     │
     └─────────────────────────┘ └──────────────────────────┘

Without a mask, a host couldn’t decide whether to ARP for the target directly or hand the packet to the router.

What else depends on the mask

What goes wrong if masks are mismatched

If one host has /24 and another on the same wire has /16, they can disagree about who is local. One side ARPs directly while the other sends via the gateway, which causes one-way or flaky connectivity. This is a classic source of confusing LAN bugs.

Kubernetes connection

k3s uses a pod CIDR (10.42.0.0/16) and a service CIDR (10.43.0.0/16) by default. These must not overlap with your LAN subnet. Otherwise the host can’t tell whether 10.x traffic should go to a pod or out to the network.


3. Subnet Math (CIDR)

Long form vs CIDR form

Long form (mask)CIDR
255.0.0.0/8
255.240.0.0/12
255.255.0.0/16
255.255.255.0/24
255.255.255.192/26

The number after the slash is how many bits of the mask are 1s, counted from the left. An IPv4 mask is 32 bits, so the prefix ranges from /0 to /32.

From mask to prefix

Write each octet in binary and count the 1s:

255.255.255.0
11111111.11111111.11111111.00000000
    8   +    8   +    8   +    0    = 24  → /24

255.255.0.0
11111111.11111111.00000000.00000000
    8   +    8   +    0   +    0    = 16  → /16

A valid mask is always a solid block of 1s followed by a solid block of 0s. You never get 11110111.

Octet values to memorize

Only 9 values are possible for a single mask octet:

BinaryDecimal1-bits
0000000000
100000001281
110000001922
111000002243
111100002404
111110002485
111111002526
111111102547
111111112558

So 255.255.255.192 is 8 + 8 + 8 + 2 = /26.

From prefix to mask

Take /20. That’s 20 ones: 8 + 8 + 4, then 0.

11111111 . 11111111 . 11110000 . 00000000
   255   .    255   .    240   .     0      → 255.255.240.0

How many hosts fit

The leftover bits are host bits: 32 − prefix.

addresses    = 2^(32 − prefix)
usable hosts = 2^(32 − prefix) − 2     (minus network and broadcast address)
PrefixHost bitsAddressesUsable hosts
/161665,53665,534
/248256254
/2666462
/30242
/31122 (point-to-point links, no broadcast)
/3201a single host

Worked example: 192.168.1.77/26

 .0              .64             .128            .192            .255
 ├───────────────┼───────────────┼───────────────┼───────────────┤
 │   block 1     │   block 2     │   block 3     │   block 4     │
                 ▲       ▲      ▲
                 │       │      └── .127  broadcast
                 │       └───────── .77   our host
                 └───────────────── .64   network address

Network:    192.168.1.64
Hosts:      192.168.1.65 – 192.168.1.126
Broadcast:  192.168.1.127

“256 minus the mask octet = block size” is the fastest way to do this in your head. Check your work with:

ipcalc 192.168.1.77/26

4. Routing

The routing table

ip route show          # short: ip r
default via 192.168.1.1 dev wlp0s20f3 proto dhcp src 192.168.1.10 metric 600
└──┬──┘     └────┬────┘     └───┬───┘                               └───┬───┘
   │        gateway (router)  interface                    lower = preferred
   └─ matches everything not matched by a more specific route (0.0.0.0/0)

192.168.1.0/24 dev wlp0s20f3 proto kernel scope link src 192.168.1.10
└─────┬──────┘                              └───┬────┘
  local subnet                  directly reachable, no gateway needed

Each route says: “to reach destinations in this prefix, send packets out this interface, optionally via this gateway.”

Longest-prefix match

When several routes match, the most specific (longest prefix) wins:

Routes:                                  Destination 10.42.0.15 matches:
  default          via 192.168.1.1         default       (/0)
  10.0.0.0/8       via 192.168.1.254       10.0.0.0/8    (/8)
  10.42.0.0/24     dev cni0                10.42.0.0/24  (/24)  ◄── wins
ip route get 8.8.8.8      # which route would be used for this destination?

Changing addresses and routes (temporary)

sudo ip address add 192.168.1.50/24 dev eth0     # add an address
sudo ip address del 192.168.1.50/24 dev eth0     # remove it
sudo ip link set eth0 up                          # bring interface up (down to disable)
sudo ip route add default via 192.168.1.1 dev eth0
sudo ip route del default
sudo ip route add 10.10.0.0/16 via 192.168.1.254  # static route to another subnet

ARP / neighbor table

ARP maps IP addresses to MAC addresses on the local network.

ip neigh show
# 192.168.1.1 dev wlp0s20f3 lladdr 9c:53:22:11:22:33 REACHABLE

Following the path

tracepath example.com      # no root needed
traceroute example.com     # classic tool
mtr example.com            # continuous traceroute + ping

5. IPv6

IPv4IPv6
Size32 bits128 bits
Notation192.168.1.102001:db8:0:1::10 (hex, :: = run of zeros)
Loopback127.0.0.1::1
Typical subnet/24/64
Local-onlyprivate ranges + NATlink-local fe80::/10 (every interface has one)
Address configDHCPSLAAC (auto from router advertisements) or DHCPv6
ARPARPNeighbor Discovery (NDP, via ICMPv6)
ip -6 address show
ip -6 route show

Hosts often have several IPv6 addresses at once: link-local, global, and temporary “privacy” addresses.


6. Basic ICMP and DNS Tools

ping

ping sends ICMP echo requests and measures round-trip time and packet loss.

ping example.com
ping -c 4 example.com      # stop after 4 packets
ping -4 example.com        # force IPv4
ping -6 example.com        # force IPv6
64 bytes from 93.184.215.14: icmp_seq=1 ttl=56 time=12.4 ms
                                     │      │       └─ round-trip time
                                     │      └─ hops left (TTL)
                                     └─ gaps in sequence numbers = lost packets

No reply doesn’t always mean the host is down. Many firewalls block ICMP.

DNS lookups

host www.example.com          # simple lookup
dig www.example.com           # detailed DNS query
dig +short www.example.com    # just the answer
dig @1.1.1.1 example.com      # ask a specific DNS server
dig example.com MX            # mail server records
dig -x 8.8.8.8                # reverse lookup (IP → name)
getent hosts example.com      # resolve the way applications do (uses nsswitch)

dig and host query DNS directly. getent hosts follows the system resolution order, including /etc/hosts.


7. Name Resolution

How a hostname becomes an IP

  Application calls getaddrinfo("example.com")
                     │
                     ▼
       ┌──────────────────────────┐
       │   /etc/nsswitch.conf     │   hosts: files myhostname resolve [!UNAVAIL=return] dns
       │   decides the ORDER      │
       └─────┬──────────────┬─────┘
       1st   │              │  then
             ▼              ▼
  ┌──────────────────┐  ┌──────────────────────────────┐
  │  /etc/hosts      │  │ DNS resolver                 │
  │  static entries  │  │ /etc/resolv.conf             │
  └──────────────────┘  │  → often 127.0.0.53          │
                        │   (systemd-resolved stub)    │
                        └──────────────┬───────────────┘
                                       ▼
                        ┌──────────────────────────────┐
                        │ DNS server (router, ISP,     │
                        │ 1.1.1.1, …) from DHCP or     │
                        │ manual config                │
                        └──────────────────────────────┘

/etc/hosts

Static name-to-address mappings, checked before DNS (with the usual nsswitch order).

# Loopback entries; do not change.
# For historical reasons, localhost precedes localhost.localdomain:
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# See hosts(5) for proper format and other examples:
# 192.168.1.10 foo.example.org foo
# 192.168.1.13 bar.example.org bar

Format: IP canonical-name [aliases…]. Useful for local dev domains or homelab hosts without a DNS server.

/etc/resolv.conf

Tells the resolver which DNS servers to use:

nameserver 127.0.0.53
options edns0 trust-ad
search lan

On systems with systemd-resolved (Fedora, Ubuntu), this file is usually a symlink pointing to the local stub 127.0.0.53. The real upstream servers are shown by:

resolvectl status            # DNS servers per interface
resolvectl query example.com # resolve via systemd-resolved
resolvectl flush-caches      # clear the DNS cache

/etc/nsswitch.conf

Controls the order of sources for name lookups: hosts, but also users (passwd), groups, etc.

hosts: files myhostname resolve [!UNAVAIL=return] dns
       │     │          │                          └─ classic DNS via resolv.conf
       │     │          └─ systemd-resolved
       │     └─ the machine's own hostname always resolves
       └─ /etc/hosts first

8. Transport Layer: TCP, UDP and Ports

Ports

IP gets a packet to the right host. A port (0–65535) gets it to the right application on that host. A connection is identified by:

(protocol, source IP, source port, destination IP, destination port)
  TCP,     192.168.1.10, 53122,     93.184.215.14,  443
RangeNameNotes
0–1023Well-knownNeed root to listen (22 SSH, 53 DNS, 80 HTTP, 443 HTTPS)
1024–49151Registerede.g. 5432 PostgreSQL, 6443 Kubernetes API
49152–65535EphemeralRandom source ports for outgoing connections (Linux uses 32768–60999)

/etc/services maps port numbers to service names. That’s why tools can show ssh instead of 22.

grep -w 443 /etc/services

TCP vs UDP

TCPUDP
ConnectionYes (handshake)No
ReliabilityRetransmits lost data, in orderFire and forget
OverheadHigherLower
Used byHTTP, SSH, databasesDNS, DHCP, video/voice, QUIC (HTTP/3), WireGuard

TCP three-way handshake:

   Client                              Server (listening)
     │ ──────── SYN ─────────────────►  │
     │ ◄─────── SYN-ACK ──────────────  │
     │ ──────── ACK ─────────────────►  │
     │       connection ESTABLISHED     │

Inspecting connections: ss (and netstat)

netstat is deprecated on modern distros. ss replaces it with the same flags:

ss -nt            # established TCP connections, numeric (same as netstat -nt)
ss -tlnp          # listening TCP sockets + owning process (-p needs sudo for others)
ss -ulnp          # listening UDP sockets
ss -tanp state established '( dport = :443 )'   # filter
FlagMeaning
-t / -uTCP / UDP
-lListening sockets only
-aAll (listening + connected)
-nNumeric: don’t resolve names or port names
-pShow process

A server bound to 127.0.0.1:8080 is only reachable locally. Bound to 0.0.0.0:8080 (or *:8080), it is reachable on all interfaces.


9. DHCP

DHCP (Dynamic Host Configuration Protocol) gives a host its IP address, subnet mask, default gateway and DNS servers automatically. The exchange is called DORA:

  Client (no IP yet)                       DHCP server (usually the router)
     │ ─── DISCOVER (broadcast) ──────────►  │   "Is there a DHCP server?"
     │ ◄── OFFER ──────────────────────────  │   "You can have 192.168.1.10"
     │ ─── REQUEST (broadcast) ───────────►  │   "I'll take 192.168.1.10"
     │ ◄── ACK ────────────────────────────  │   "Confirmed, lease: 24h,
     │                                       │    gateway .1, DNS .1"

10. NetworkManager

NetworkManager is a daemon started at boot. Like most daemons, it doesn’t depend on a desktop. It listens to events from the system and users (cable plugged in, Wi-Fi available, VPN started) and changes the network configuration based on its rules. It stores configuration persistently, unlike ip.

Key terms:

nmcli                                   # overview of all devices
nmcli device status                     # devices and their state
nmcli connection show                   # saved connection profiles
nmcli connection show --active
nmcli device wifi list                  # nearby Wi-Fi networks
nmcli device wifi connect "SSID" --ask  # connect, prompt for password
nmcli connection up "Home"
nmcli connection down "Home"
nmcli general hostname                  # show hostname

Set a static IP (persistent):

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 "1.1.1.1 9.9.9.9"
sudo nmcli connection up "Wired connection 1"

Switch back to DHCP: ipv4.method auto.

On Fedora, profiles are stored as keyfiles in /etc/NetworkManager/system-connections/. nmtui offers a simple text-menu interface.


11. NAT

NAT (Network Address Translation) lets many hosts with private addresses share one public address. The router rewrites the source address and port of outgoing packets and remembers the mapping so replies can be sent back.

 LAN (private)                     Router (NAT)                    Internet
                              ┌────────────────────┐
 192.168.1.10:53122 ────────► │ 192.168.1.1        │
   → 93.184.215.14:443        │                    │  src rewritten to
                              │ NAT table:         │  203.0.113.7:40001
 192.168.1.11:53122 ────────► │ .10:53122 ↔ :40001 │ ──────────────────►  93.184.215.14:443
   → 93.184.215.14:443        │ .11:53122 ↔ :40002 │  203.0.113.7:40002
                              │      203.0.113.7   │ ◄──────────────────  replies to :40001
                              └────────────────────┘  → back to .10:53122

12. Firewalls

The Linux kernel filters packets with netfilter. Its modern rule interface is nftables, which replaces iptables. The tools below are front-ends that write those rules for you.

 ┌──────────────┐   ┌────────────────┐
 │ ufw          │   │ firewalld      │      friendly front-ends
 │ (Ubuntu)     │   │ (Fedora, RHEL) │
 └──────┬───────┘   └───────┬────────┘
        └─────────┬─────────┘
                  ▼
        ┌───────────────────┐
        │ nftables /iptables│                rule sets
        └─────────┬─────────┘
                  ▼
        ┌───────────────────┐
        │ netfilter (kernel)│                filters every packet
        └───────────────────┘

Use one front-end per machine. Mixing them leads to conflicting rules.

firewalld (Fedora / RHEL)

firewalld uses zones (e.g. public, home, trusted), each with its own rules. Interfaces and source networks are assigned to zones.

sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all                          # rules in the default zone
sudo firewall-cmd --add-service=http --permanent      # allow a known service
sudo firewall-cmd --add-port=8080/tcp --permanent     # allow a port
sudo firewall-cmd --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload                            # apply --permanent changes

Without --permanent, a change is active immediately but lost at reload/reboot. With --permanent, it’s saved but only applied after --reload.

k3s note: the k3s docs recommend either disabling firewalld or trusting the pod and service networks, e.g. firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16 and the same for 10.43.0.0/16, plus opening 6443/tcp for the API server.

ufw (Ubuntu / Debian)

sudo ufw status verbose
sudo ufw allow 22/tcp             # allow SSH before enabling!
sudo ufw allow from 192.168.1.0/24 to any port 5432
sudo ufw deny 23
sudo ufw enable
sudo ufw delete allow 22/tcp

⚠️ On a remote machine, always allow SSH before enabling a firewall, or you’ll lock yourself out.


13. Cheat Sheet

TaskCommand
Show addressesip a, ip -br a
Show IPv6 addressesip -6 address show
Show routesip r, ip -6 route show
Which route for a destinationip route get 8.8.8.8
Add address (temporary)sudo ip address add 192.168.1.50/24 dev eth0
Set default route (temporary)sudo ip route add default via 192.168.1.1 dev eth0
Remove default routesudo ip route del default
ARP / neighbor tableip neigh
Subnet calculatoripcalc 192.168.1.77/26
Test reachabilityping -c 4 host, ping -4 / ping -6
Trace the pathtracepath host, mtr host
DNS lookuphost name, dig +short name
Resolve like applications dogetent hosts name
DNS servers in useresolvectl status
Listening portssudo ss -tlnp
Active TCP connectionsss -nt (old: netstat -nt)
Port ↔ service name/etc/services
NetworkManager overviewnmcli, nmcli device status
Connect to Wi-Finmcli device wifi connect "SSID" --ask
Static IP (persistent)nmcli connection modify … ipv4.method manual …
Firewall (Fedora)sudo firewall-cmd --list-all
Firewall (Ubuntu)sudo ufw status verbose

Key files:

FilePurpose
/etc/hostsStatic hostname → IP mappings
/etc/resolv.confDNS servers and search domains
/etc/nsswitch.confOrder of name lookup sources
/etc/servicesPort numbers ↔ service names
/etc/NetworkManager/system-connections/Saved NetworkManager profiles