Software and Versions Used
This explanation applies to:
- TCP/IP stack: IPv4 and IPv6 (RFC 791, RFC 8200)
- Docker: Version 24.0+ (for container examples)
- Linux kernel: 5.15+ (Netfilter subsystem)
- Context: Distribution-independent networking fundamentals
IP Addresses Are Unique Identifiers Within the Network Namespace
Every IP address identifies a specific network endpoint. IPv4 uses 32-bit addresses (4,294,967,296 possible addresses), while IPv6 expands this to 128 bits (340 sextillion addresses). These numbers are not theoretical constructs—they define practical limits. A /24 subnet (255.255.255.0 netmask) provides 254 usable host addresses, while a /16 subnet provides 65,534 addresses.
Container networks use the private address ranges defined by RFC 1918: 192.168.0.0/16, 172.16.0.0/12, and 10.0.0.0/8. By default, Docker creates a 172.17.0.0/16 network—a subnet within the RFC 1918 range 172.16.0.0/12. Docker networks remain isolated from other private networks. Each container receives a sequential address: 172.17.0.2, 172.17.0.3, and so on.
The subnet notation /24, /16, and /12 describes how many bits are reserved for the network. A /24 means 24 network bits and 8 host bits, resulting in 2^8 = 256 addresses minus the network and broadcast addresses = 254 usable IP addresses. A /16 reserves 16 network bits and 16 host bits, resulting in 2^16 = 65,536 addresses minus 2 = 65,534 usable IP addresses.
Ports Define Service Endpoints on IP Addresses
A port is a 16-bit number (0–65535) that identifies specific services on an IP address. Port 80 is universally associated with HTTP, port 443 with HTTPS, and port 22 with SSH. These assignments are conventions established by the Internet Assigned Numbers Authority (IANA)—not technical requirements. A web server can listen on port 8080, and SSH can listen on port 2222.
Ports 0–1023 are “Well-Known Ports” and are traditionally reserved for system services. Ports 1024–49151 are “Registered Ports” for specific applications. Ports 49152–65535 are “Dynamic/Private Ports” for temporary connections. A client uses a random port from the dynamic range for outbound connections, and the server replies to that temporary port number.
Docker port mapping connects host ports to container ports: -p 8080:80 forwards host port 8080 to container port 80. Netfilter automatically creates DNAT (Destination Network Address Translation) rules in the PREROUTING chain. This iptables manipulation explains conflicts with UFW—both tools modify the same Netfilter tables without coordination.
The TCP/IP Stack Architecture Determines Data Flow
Network communication operates in layers. The lowest layer (Layers 1–2) transports Ethernet frames between physically connected devices. Layer 3 (IP) routes packets between different networks. Routers serve as forwarding points for this traffic. Layer 4 (TCP/UDP) establishes communication between applications. Each layer adds its own headers and removes them again at the receiving end.
An HTTP request passes through these layers: HTTP request → TCP segment (with port information) → IP packet (with source and destination IP addresses) → Ethernet frame (with MAC addresses). At the destination, the process is reversed: Ethernet frame → IP packet → TCP segment → HTTP request. Each layer processes only its own headers before passing the payload to the next layer.
TCP (Transmission Control Protocol) guarantees reliable data transfer through sequence numbers, acknowledgments, and retransmission of lost packets. UDP (User Datagram Protocol) omits these guarantees in favor of lower latency. DNS uses UDP for fast queries, while HTTP uses TCP for reliable delivery of larger amounts of data.
Subnetting Enables Hierarchical Network Organization
Subnetting divides large networks into smaller, manageable units. A /16 network (192.168.0.0/16) can be divided into 256 /24 subnets: 192.168.0.0/24, 192.168.1.0/24, …, 192.168.255.0/24. Each subnet functions as its own broadcast domain with its own gateway IP address.
The subnet mask determines which part of the IP address identifies the network. A /24 mask (255.255.255.0) means that the first three octets (192.168.1) identify the network, while the last octet (0–255) identifies the hosts. Two IP addresses within the same subnet communicate directly over Layer 2. Different subnets require a router.
Variable Length Subnet Masking (VLSM) optimizes IP address utilization. A point-to-point link between two routers requires only a /30 subnet (4 IP addresses: network, router A, router B, broadcast). A server network with 50 hosts uses a /26 subnet (64 IP addresses). This flexibility significantly reduces address waste.
Routing Tables Determine Packet Paths
Every network interface has a routing table that determines where packets are sent. The default route (0.0.0.0/0) forwards all unknown destinations to the default gateway. More specific routes take precedence: a route to 192.168.1.0/24 overrides the default route for that subnet.
Container networks create separate routing tables inside isolated network namespaces. A container sees only its own routing table, with the Docker bridge acting as the default gateway. The host maintains a master routing table that connects physical interfaces with virtual container bridges.
Multiple default gateways require policy-based routing or metric weighting. A system with both Ethernet and Wi-Fi typically prefers Ethernet (lower metric). If Ethernet fails, Wi-Fi automatically takes over. These failover mechanisms operate transparently for applications.
Docker Network Isolation and Port Mapping
Docker creates an isolated network namespace for every container, complete with its own loopback interface, routing table, and firewall rules. This isolation explains why localhost inside a container can reach only services running within that same container.
The default Docker bridge network connects containers through a virtual bridge interface (docker0). This bridge functions like a switch: containers can communicate with one another using their bridge IP addresses. Port mapping with -p creates NAT rules that forward host ports to container ports.
User-defined networks provide additional features: automatic DNS resolution between containers, improved isolation from other containers, and IPv6 support. A docker network create command creates a separate bridge network with its own IP address range, independent of the default docker0 bridge.
IPv6 Fundamentals for Modern Networks
IPv6 uses 128-bit addresses written in hexadecimal notation: 2001:db8:85a3::8a2e:370:7334. The colon notation allows abbreviations: leading zeros may be omitted, and consecutive blocks of zeros can be compressed into ::. This address is globally unique without requiring NAT.
IPv6 addresses have a hierarchical structure. The first 64 bits identify the network prefix, while the last 64 bits identify the host. Automatic configuration using SLAAC (Stateless Address Autoconfiguration) generates host IDs from MAC addresses or random values. Privacy Extensions periodically change the host ID to improve anonymity.
Link-local addresses (fe80::/10) work without router configuration for local communication. Unique Local Addresses (fc00::/7) correspond to IPv4 private addresses for internal networks. Global Unicast Addresses (2000::/3) provide globally unique addresses without the complexity of NAT.
Practical NAT Implementations
Network Address Translation (NAT) translates private IP addresses into public addresses for Internet access. A router with the public IP address 203.0.113.1 translates outgoing packets from 192.168.1.100:3456 to 203.0.113.1:3456. Incoming reply packets are translated back. This state table allows multiple private devices to access the Internet through a single public IP address.
Port Address Translation (PAT) extends NAT by translating ports when port conflicts occur. Two internal hosts using identical source ports receive different external ports: 192.168.1.100:80 → 203.0.113.1:1024, 192.168.1.101:80 → 203.0.113.1:1025. The router maintains a mapping table to perform the correct reverse translation.
Docker uses masquerading to provide Internet access for containers. Container packets use the host IP address as their source address. Iptables rules in the POSTROUTING chain automatically translate container IP addresses to the host IP address. This NAT implementation works transparently as long as outbound connections are initiated.
Debugging Techniques for Network Problems
ss -tulnp displays all listening ports together with their associated processes. The output includes the protocol (TCP/UDP), local address, port, and process ID. A service listening on 0.0.0.0:80 accepts connections on every interface, while 127.0.0.1:8080 listens only on localhost. This information quickly identifies service binding problems.
ip route show displays the current routing table, including the default gateway and interface-specific routes. ip addr show lists all IP addresses assigned to each interface. These tools replace the older ifconfig and route commands with more modern and precise output.
Packet tracing with tcpdump or Wireshark shows the packets that are actually transmitted. A tcpdump -i any port 80 command displays all HTTP packets on every interface. The output includes source and destination IP addresses, ports, TCP flags, and packet sizes. This low-level analysis helps diagnose complex connectivity problems.
Firewall Integration and Port Security
Modern Linux systems use Netfilter for packet filtering. Every packet passes through defined hooks: PREROUTING (before the routing decision), INPUT (to local processes), FORWARD (packets forwarded through the system), OUTPUT (from local processes), and POSTROUTING (after the routing decision).
Stateful packet filtering (connection tracking) keeps track of established connections. A rule such as --state ESTABLISHED,RELATED allows reply packets for outbound connections without opening inbound ports. This mechanism enables secure default configurations with outbound connections allowed and inbound ports blocked.
Docker automatically modifies iptables rules to provide container connectivity. The DOCKER chain in the FORWARD table allows inter-container communication. Port mapping creates DNAT rules in the PREROUTING chain. These automatic changes can override or bypass manually configured firewall rules.
Performance Optimization and Monitoring
TCP window scaling improves throughput on high-bandwidth connections. The original 16-bit TCP window is limited to 64 KB. The window scaling option multiplies this size for modern Gigabit connections. A 1 Gbit/s connection with a 50 ms RTT requires a 6 MB window size for optimal throughput.
Receive Side Scaling (RSS) distributes network interrupts across multiple CPU cores. Multi-queue network adapters create separate queues for each core. This parallelization prevents a single CPU core from becoming the bottleneck for network performance.
iftop displays bandwidth usage per connection in real time. nethogs groups network traffic by process. nload visualizes interface utilization graphically. These tools quickly identify bandwidth problems and unexpected network activity.
Next Steps:
-
Container Networks: Docker Bridge, Overlay Networks, Service Discovery (planned)