Friday, 16 October 2026

Network Ips, docker range

 /24 what does it mean?

first 24 bits of the IP address belong to the network portion, leaving the remaining 8 bits for individual devices (hosts).

so there will be total of 256 ips for 8 bits 
because 8 bits equals 256 because each bit has 2 possible states
2^8 = 256
1. The Total Count (256 Possibilities)
An 8-bit system has 8 binary slots, and each slot can be either a 0 or a 1. To find the total number of unique combinations, you calculate 2⁸, which equals 256. This means an 8-bit number can represent 256 distinct values.
2. The Maximum Value (255)
Because computers are digital systems, they start counting from 0 rather than 1.
  • The lowest possible value is all zeros: 00000000 (which equals 0).
  • The highest possible value is all ones: 11111111 (which equals 255).
If you count all the numbers from 0 to 255, you get exactly 256 total numbers.
  • The lowest possible 8-bit number is 00000000 (which is 0).
  • The highest possible 8-bit number is 11111111 (which is \(128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255)

 addresses in a network  =  2^(32 − N)

   /24  →  2^(32−24)  =  2^8  =  256      ✓ matches your count
   /28  →  2^(32−28)  =  2^4  =   16

Why it splits into 16

Carving a /24 into /28s means taking 4 more bits away from the host part:

   169.254.6.0/24    11111111.11111111.11111111 . 00000000
                                               └── 8 host bits ──┘
                                                    2^8 = 256 addresses

   169.254.6.0/28    11111111.11111111.11111111 . 1111 . 0000
                                               └─4─┘   └─4──┘
                                          new subnet    host bits
                                          bits: 2^4     = 2^4 = 16
                                              = 16        addresses
                                              subnets     each

asdad
"bip": "169.254.4.1/28",
"default-address-pools": [ { "base": "169.254.6.0/24", "size": 28 } ]

Two separate knobs, and they're easy to conflate:

KeyMeaning
basethe total space Docker may carve up
sizethe prefix length of each network it creates — not the number of networks

So size: 28 means every auto-created network is a /28. The base then divides evenly:

169.254.6.0/24  ── 256 addresses, sliced into /28 ──
├── 169.254.6.0/28      ← network 1
├── 169.254.6.16/28     ← network 2
├── 169.254.6.32/28     ← network 3
│   ⋯
└── 169.254.6.240/28    ← network 16


asdsad
sa

16 is the block size. Not all 16 are assignable:

   169.254.9.0/28
   ├── .0    network address    ← not assignable
   ├── .1    gateway            ← Docker takes it
   ├── .2 … .14   13 container slots
   └── .15   broadcast          ← not assignable

   block = 16  ·  usable hosts = 14  ·  after the gateway = 13


asdsadasd Docker colloision

ip route get 172.17.0.5

   BEFORE                                AFTER  (a stack comes up on 172.17.0.0/16)
   ─────────────────────────────         ────────────────────────────────────────
   default         via 172.19.11.1       172.17.0.0/16   dev docker0   ← NEW, /16 > /0
   169.254.0.0/16  enp0s31f6             172.19.11.0/24  enp0s31f6
   172.19.11.0/24  enp0s31f6             169.254.0.0/16  enp0s31f6
                                          default         via 172.19.11.1

   packet ─→ gateway ─→ LAN ─→ 172.17.0.5        packet ─→ docker0 ─→ ARP ─→ nobody
              ✓ SYN arrives                                  ✗ dies. 172.17.0.5
                                                               never saw a packet.


asdadad cooliosn B 


 Docker created a network on 172.19.11.0/28   ← contains 172.19.11.1

   main table                            local table = "addresses I answer for"
   ───────────────────────────           ──────────────────────────────────────
   172.19.11.0/28  br-18191aa6  ← NEW    local 172.19.11.161  dev enp0s31f6
   172.19.11.0/24  enp0s31f6             local 172.19.11.1    dev lo       ← NEW
   default         via 172.19.11.1
                                         the host now thinks the GATEWAY is itself

   packet for 8.8.8.8 ─→ default via 172.19.11.1 ─→ look up .1 ─→ "that's me"
                                                       └─→ delivered to lo ─→ ✗

why colliosnn 

 ── inside the host (nothing on the wire yet) ──      ── on the wire ──
   ───────────────────────────────────────────────      ─────────────────

   1.  app: send() to 8.8.8.8
   2.  routing table: which interface?
         8.8.8.8 is not in 172.19.11.0/24
         → default route → next hop 172.19.11.1, dev enp0s31f6
   3.  routing table AGAIN: how do I reach 172.19.11.1?
         it IS in my /24 → on-link → ARP for it
   4.  ARP: who has 172.19.11.1?  →  00:09:0f:09:6f:1a
   5.  build the ethernet frame:
         dst MAC = 00:09:0f:09:6f:1a   ← the gateway
         dst IP  = 8.8.8.8             ← unchanged
                                                     ────→ gateway ──→ … ──→ 8.8.8.8

asdadadsadasdsad ssh colliosn 

 you: 172.19.11.160                    host: 172.19.11.161  (sshd :22)
   ──────────────────                    ──────────────────────────────

   1.  SYN ───────────────────────────→  arrives on enp0s31f6
                                          ← no routing decision needed.
                                            A packet that arrives, arrives.
   2.                                       kernel accepts. sshd replies.
   3.                                       route lookup for 172.19.11.160
                                            ← ★ THIS is where it dies
   4.  SYN-ACK ←─────────────────────────   (or doesn't)

three way ssh colliosn 
   ── A ── your address falls inside a range Docker claimed
   ─────────────────────────────────────────────────────────
   reply to 172.19.11.160  →  matches 172.19.11.0/24 → enp0s31f6   ✓
   reply to 172.19.11.5    →  matches 172.19.11.0/28 → br-xxxx     ✗
                              (Docker took .0/28; .5 is inside it)

   ── B ── you're off-subnet, and the gateway got shadowed
   ─────────────────────────────────────────────────────────
   reply to 10.20.30.40    →  off-link → default via 172.19.11.1
                              → lookup .1 → "local, dev lo" → loopback   ✗

   ── C ── rp_filter = 1 (strict)
   ─────────────────────────────────────────────────────────
   SYN arrives on enp0s31f6. Kernel checks: would I send *back* to
   this source via enp0s31f6?  A Docker route now says "no, via docker0"
   → packet dropped BEFORE sshd ever sees it.      ✗
   (this host is at rp_filter=2, so it's spared)


asdadasdasdsad host vs brdige(host dangerous)

docker0 — yes, with one trap that catches everyone

The trap is a naming collision: bridge is both a driver and the name of one specific network.

   driver "bridge"        ← the technology. docker0 AND every br-xxxx use it.
   network named "bridge" ← docker0 specifically. The default one.
   network_mode: bridge   ← attach to docker0.

So this lands you on docker0:

services:
  app:
    network_mode: bridge      # explicit

And this does not — it silently creates a user-defined bridge called <project>_default:

services:
  app:
    networks: [default]       # ← its own br-xxxx, NOT docker0

Compose's auto-created default network is a user-defined bridge. Every compose stack on this host proves it:

   docker network ls
   bridge                              ← docker0. linkdown. empty.
   umami_default                       ← user-defined, br-ba9f53a61dc4

That's why docker0 is linkdown here — nothing has ever asked for it.

you writeyou getgateway
network_mode: bridgedocker0bip
nothing / networks: [default]<project>_default (own br-xxxx)subnet + 1
an explicit networks: blockone br-xxxx per networksubnet + 1
network_mode: hostnonenone

User-defined is strictly better, which is why docker0 is effectively legacy:

  • DNS by name — on a user-defined network, db resolves to the container. On docker0 you need --link (deprecated) or hardcoded IPs. That's why umami-umami-1 can just say db in its connection string.
  • Isolation between networks — Docker inserts DOCKER-ISOLATION rules so certgen-net can't reach umami_default. The default bridge is more permissive.
  • Hot attach/detach without restarting containers.

2. network_mode: host — yes, genuinely dangerous

It removes the boundary entirely. The container doesn't get its own network namespace; it shares the host's.

   ── bridged ──                          ── host mode ──
   ┌─ container netns ─┐                  ┌────────────────────────┐
   │ eth0 169.254.9.3  │                  │  container process     │
   └────────┬──────────┘                  │  lives in the HOST's   │
            │ veth                        │  network namespace     │
   ┌────────▼──────────┐                  │                        │
   │ br-ba9f53a61dc4   │ ← boundary       │  binds :443, :22, :80  │
   └────────┬──────────┘                  │  reaches 127.0.0.1     │
            │ iptables NAT + isolation    │  sees the whole LAN    │
   ┌────────▼──────────┐                  └───────────┬────────────┘
   │ host 172.19.11.161│                              │
   └───────────────────┘                  no boundary. it IS the host.

sadsadad

mode        allocates an IP?          from where              can it take .161?
   ─────────   ───────────────────────   ─────────────────────   ─────────────────
   host        no                        —                       only if the host
                                                                 already has it
   bridge      yes                       169.254.x.0/28 (Docker)  no
   macvlan     yes                       your LAN subnet          yes — and that's
                                                                 a duplicate-IP bug


asdsad using host mode no longer uses bips, container just seperate themself by taking over real host ports

   HOST MODE × 3
   ─────────────

   ┌──────────────────────────────────────────────────────┐
   │  the host's single network namespace                 │
   │                                                      │
   │   enp0s31f6   172.19.11.160/24                       │
   │                                                      │
   │   :80    ← container A                               │
   │   :8080  ← container B                               │
   │   :9000  ← container C                               │
   │                                                      │
   │   no eth0 for any of them. no address. no veth.      │
   │   A, B and C reach each other on 127.0.0.1           │
   └──────────────────────────────────────────────────────┘

   from the LAN, all three answer to the SAME address:

     172.19.11.160:80     172.19.11.160:8080     172.19.11.160:9000
     └──────────────── one IP, three ports ────────────────┘

The port becomes the only thing that tells them apart

   BRIDGED × 3                          HOST MODE × 3
   ───────────                          ─────────────
   ┌─A─┐ ┌─B─┐ ┌─C─┐                    ┌──────────────────────┐
   │.2 │ │.3 │ │.4 │  ← own addresses   │  :80  :8080  :9000   │
   └─┬─┘ └─┬─┘ └─┬─┘                    │  ← only ports differ │
     └─────┼─────┘                      └──────────────────────┘
       br-xxxx (169.254.9.1)
           │
     host 172.19.11.161

asdasda

and no host to docker port mappings

No comments:

Post a Comment