mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
Apply a consistent naming convention to the Make target inventory so
every target is grouped by its domain:
- compose-* (compose-up/down/restart/stop/exec/inner-run)
- network-* (network-dns-setup/remove, network-ipv6-disable/restore,
network-refresh, network-trust-ca)
- security-* (security-apparmor-restore/teardown)
- diagnose-* (diagnose-network, diagnose-disk-usage)
- fix-* (fix-chmod, fix-dockerignore)
- clean-* (clean-cache, clean-pycache-dirs)
- install-* (install-agent)
- meta-* (meta-list, meta-tree, meta-mig)
Drop the stale debug-network target and reintroduce its functionality
as diagnose-network. Cascade renames through:
- Makefile (.PHONY entries, prereqs, recursive $(MAKE) calls)
- contributor docs, agent-iteration docs, role-level docs
- bundle README, environment scripts, install/lint/test wrappers
- AGENTS.md, CLAUDE.md, compose/cache.override.yml, .github/workflows
Historical entries under docs/requirements/ and changelog/ stay
untouched as audit logs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
107 lines
5.2 KiB
Markdown
107 lines
5.2 KiB
Markdown
# Network 🌐
|
||
|
||
When compose pulls hang, image builds fail to resolve registry manifests, `make install-lint` times out on a TLS handshake, or DNS lookups return surprising addresses, the cause is almost always one of three things: MTU mismatch, IPv6 misrouting, or DNS / proxy interference.
|
||
|
||
## Diagnose tool 🕵️
|
||
|
||
```bash
|
||
make diagnose-network
|
||
```
|
||
|
||
Runs [__main__.py](../../../../cli/contributing/network/diagnose/__main__.py) inside the running `infinito` container and produces a structured DNS / TCP / TLS / PMTU report against the standard infrastructure hosts (`github.com`, `ghcr.io`, `registry-1.docker.io`, `auth.docker.io`, `pypi.org`, `files.pythonhosted.org`, `registry.npmjs.org`, `objects.githubusercontent.com`, `raw.githubusercontent.com`), separately for IPv4 and IPv6 when available. Extra hosts can be appended via `INFINITO_NET_DEBUG_HOSTS="example.com api.example.org" make diagnose-network`.
|
||
|
||
On first run it self-installs `iputils-ping` + `iproute2` via the container's package manager (Debian / Ubuntu apt, Arch pacman, Fedora / CentOS / RHEL dnf). The installer waits up to two minutes for an apt-lock if a parallel deploy is running. IPv6 probes are auto-skipped when the bridge has no usable IPv6 default route.
|
||
|
||
For each host the script reports four signals:
|
||
|
||
| Signal | Means | Fails when |
|
||
|---|---|---|
|
||
| `DNS` | `socket.getaddrinfo` resolution time + returned addresses | resolver unreachable, no records, AAAA/A missing |
|
||
| `TCP` | `socket.connect` time to the resolved address on `:443` | routing missing, firewall drops, upstream not listening |
|
||
| `TLS` | `ssl.wrap_socket` handshake time, negotiated protocol, certificate CN | __MTU drops mid-handshake__, MITM cert mismatch, CA bundle missing, server-side issue |
|
||
| `PMTU` | largest ICMP-DF payload that survives (= path MTU − 28 bytes IP+ICMP header) | container lacks `ping` after auto-install (auto-skipped), or path drops every probe size |
|
||
|
||
The classic failure shape (`DNS [OK]`, `TCP [OK]`, `TLS [FAIL] TimeoutError after 8s`) is an __MTU mismatch__, not a TLS-layer bug. Small packets (TCP-SYN, DNS replies) survive; the larger TLS-ServerHello with the certificate chain is dropped silently because the path MTU is below the bridge MTU and ICMP-needs-frag is filtered upstream. When `auth.docker.io` is OK but `ghcr.io` / `registry-1.docker.io` time out, the chain-length difference between hosts (Cloudflare-fronted ≈ small chain, GitHub/AWS ≈ large chain) confirms MTU as the cause rather than a blanket TLS block.
|
||
|
||
DNS resolutions to `172.30.0.4` for hosts like `pypi.org` are intentional: the package-cache frontend overrides those names in `/etc/hosts`, so traffic terminates at the local registry mirror with `0.00s` DNS/TCP/TLS times instead of hitting the public registry.
|
||
|
||
## MTU 📦
|
||
|
||
Docker defaults to MTU 1500. If the host outbound interface uses a smaller MTU (e.g. due to VPN, tunnels, or jumbo-frame negotiation failure), packets MAY be dropped or fragmented and TLS handshakes time out mid-flight (see the diagnose tool's classic-failure shape above).
|
||
|
||
The local development compose stack SHOULD inherit the host Docker MTU automatically from `/etc/docker/daemon.json`. If auto-detection is unavailable or wrong, override it explicitly with `INFINITO_OUTER_NETWORK_MTU`.
|
||
|
||
Inspect the host MTUs:
|
||
|
||
```bash
|
||
ip link show docker0
|
||
ip link show eth0
|
||
```
|
||
|
||
Fix via `/etc/docker/daemon.json`:
|
||
|
||
```json
|
||
{"mtu": 1450}
|
||
```
|
||
|
||
Then restart Docker:
|
||
|
||
```bash
|
||
sudo systemctl restart docker
|
||
```
|
||
|
||
For a one-off local override of the compose bridge, regenerate `.env` with the desired value and recreate the stack cleanly:
|
||
|
||
```bash
|
||
INFINITO_OUTER_NETWORK_MTU=1400 make dotenv
|
||
make compose-down && make compose-up
|
||
```
|
||
|
||
A clean `down && up` is required after the change: `make compose-up` alone recreates the bridge but compose then re-attaches existing containers with dynamic IPs instead of the static `default.env` ones, which breaks CoreDNS.
|
||
|
||
## IPv6 🔢
|
||
|
||
If IPv6 is active but misconfigured, Docker MAY attempt to pull over IPv6 and fail.
|
||
|
||
```bash
|
||
ip -6 addr show
|
||
curl -6 https://registry-1.docker.io/v2/
|
||
```
|
||
|
||
The recommended way to disable IPv6 for local development is via Make:
|
||
|
||
```bash
|
||
make network-ipv6-disable
|
||
```
|
||
|
||
This also restarts `docker.service` and then calls `make network-refresh`, so the running Infinito development stack is recreated when one is active and the new setting reaches fresh container network namespaces.
|
||
|
||
To restore the original IPv6 settings afterwards:
|
||
|
||
```bash
|
||
make network-ipv6-restore
|
||
```
|
||
|
||
This restore path also restarts `docker.service` and then calls `make network-refresh`, so the running Infinito development stack is recreated when one is active and the restored setting reaches fresh container network namespaces.
|
||
|
||
You can also refresh the running local stack directly after host-level changes:
|
||
|
||
```bash
|
||
make network-refresh
|
||
```
|
||
|
||
Alternatively, disable IPv6 only in Docker via `/etc/docker/daemon.json`:
|
||
|
||
```json
|
||
{"ipv6": false}
|
||
```
|
||
|
||
## General Connectivity 🔌
|
||
|
||
```bash
|
||
ping -c 3 registry-1.docker.io
|
||
curl -v https://registry-1.docker.io/v2/
|
||
```
|
||
|
||
Check firewall rules, proxy settings, and DNS configuration. The `proxy env vars` and `CA bundle summary` sections of `make diagnose-network` surface the same information from inside the container.
|