The network and DNS the fleet expects¶
The fleet builds its own VMs, and it builds none of the network under them. This page describes that network: the VLANs the fleet touches, what your router has to let pass between them, and how a fleet hostname comes to resolve.
At the end of it you know what to set up on your router, your switch, and your DNS server before the build starts, and which name each page needs pointing at which address. The page has no steps of the fleet's own. The steps on a router depend on your equipment, so the page says what the fleet needs and leaves the clicks to the router's documentation.
Status: written, not yet run. See Not yet confirmed.
The two networks¶
The fleet's VMs sit on two networks, and each is a VLAN of its own. A VLAN, a virtual LAN, is a separate network that shares switches and cables with others, kept apart by a number tagged on each frame.
| Network | VLAN | Subnet and gateway in these pages | Holds |
|---|---|---|---|
| Servers | 7 |
172.16.7.0/24, gateway 172.16.7.1 |
Everything that never faces the internet |
| DMZ | 8 |
172.16.8.0/24, gateway 172.16.8.1 |
The hosts that take traffic from the internet |
These pages call the Servers VLAN the internal network. Wherever a page says internal network, internal subnet, or internal host, it means VLAN 7.
Two more VLANs take part in the build and hold no VM. The Proxmox host's management address is on MGMT, VLAN 1, and is 172.16.1.11 in these pages, in 172.16.1.0/24. The machine you work from, with the control shell and your browser, is on Users, VLAN 4.
The network these pages were written for has eleven VLANs. The fleet touches four of them, and the rest play no part in the build.
| VLAN | Name | Part in the build |
|---|---|---|
1 |
MGMT | Proxmox management and the network switches. The Proxmox host's own address is here |
2 |
AV | None |
3 |
Security | None |
4 |
Users | End users, and the machine you work from |
5 |
VoIP | None |
7 |
Servers | The internal network, with six of the eight VMs |
8 |
DMZ | bh01 and mx01 |
9 |
Guest | None |
10 |
WAN1 | None |
11 |
WAN2 | None |
14 |
IOT | None |
Each VM has one static address. You write it in the inventory and in opentofu/prod.tfvars, and the build sets it.
| Host | Network | Address |
|---|---|---|
| km01 | Internal | 172.16.7.101 |
| tf01 | Internal | 172.16.7.111 |
| ci01 | Internal | 172.16.7.121 |
| id01 | Internal | 172.16.7.131 |
| pk01 | Internal | 172.16.7.141 |
| ap01 | Internal | 172.16.7.151 |
| bh01 | DMZ | 172.16.8.111 |
| mx01 | DMZ | 172.16.8.121 |
Your own numbers differ. See The values in these pages for what to replace.
Each VM uses its network's gateway as its DNS server too, unless the inventory names another with network_dns. In these pages that is the router, at 172.16.7.1 for the internal network and 172.16.8.1 for the DMZ.
Background: why the DMZ is a network of its own
bh01 and mx01 handle traffic that starts on the internet. If one of them is taken over, the attacker holds a machine inside your network.
On a separate VLAN, every connection from that machine to the internal hosts passes through the router, and the router's firewall refuses all but the few listed on this page. On the same network as the other hosts, nothing would stand between them.
What to set up before the build¶
The fleet configures nothing on the router or the switch. These have to exist before Proxmox and the installer ISO:
| On | The fleet needs |
|---|---|
| The router | The Servers and DMZ VLANs, each with a subnet and a gateway address on the router |
| The router's firewall | The flows in What has to cross, and nothing else from the DMZ inward |
| The switch | Servers and DMZ carried as tagged VLANs on the port the Proxmox host is plugged in to, beside MGMT for the host's own address |
| The Proxmox host | The bridge vmbr0 set as VLAN aware |
| The DNS server the VMs use | A way for you to add records. See Names |
OpenTofu attaches each VM to the bridge and gives its network device the VLAN tag from the VM's vlan_id in opentofu/prod.tfvars. The bridge is vmbr0 unless the VM's entry sets bridge. A VM with vlan_id = 7 is on the internal network, and one with vlan_id = 8 is on the DMZ.
The DMZ is first used by bh01, so its firewall rules can wait until bh01's page. The VLAN itself is simplest to create now, with the internal one.
What has to cross¶
Hosts on the same VLAN reach each other without the router. A connection that leaves a VLAN goes through the router, and the router's firewall has to allow it.
The fleet needs the flows below, and every one of them crosses the router. Your machine is on Users and the Proxmox host is on MGMT, so neither shares a VLAN with any VM. The other rows run between Servers and the DMZ, or start on the internet. How you write each rule depends on your router.
| From | To | Port | Why |
|---|---|---|---|
| The control shell, on Users | The Proxmox host, on MGMT | 8006/tcp, 22/tcp |
OpenTofu creates VMs through the API. The install logs in over SSH to read a new VM's host key |
| The control shell, on Users | Every VM, on Servers and the DMZ | 22/tcp |
The run installs and deploys over SSH |
| The control shell and your browser, on Users | km01 | 9120/tcp |
The run's last stage calls Komodo's API, and you open Komodo at its direct address |
| Your browser, on Users | Every VM | 443/tcp, 8443/tcp |
The web interfaces, and each host's Traefik dashboard |
| ci01, where Semaphore runs | The Proxmox host, on MGMT | 8006/tcp, 22/tcp |
The same two as the shell, after the handover |
| The Proxmox host, on MGMT | ci01 | 8025/tcp |
Proxmox's notifications, sent as mail to mailrise |
| ci01 | bh01 and mx01 | 22/tcp |
The run, from Semaphore |
| bh01 and mx01 | km01 | 9120/tcp |
Periphery dials Komodo Core |
| bh01 and mx01 | tf01 | 6379/tcp |
The Redis copy on bh01, and each host's route publisher |
| bh01 | Every internal host that serves a web interface | 443/tcp |
Published routes, the sign-in on id01, and telemetry to ci01 |
| mx01 | ci01 and id01 | 443/tcp |
Telemetry, and the sign-in |
| ci01 | mx01 | 587/tcp |
Service mail, which Postfix relays through Stalwart once mx01 is live |
| mx01 | The UniFi console | The port in DOCKNS_UNIFI_HOST |
dockns, after bootstrap mode |
| The internet | mx01, by a port forward | 25/tcp, 465/tcp, 587/tcp, 993/tcp |
Mail arriving, and mail clients |
Outbound, every VM needs the internet on ports 80 and 443, for NixOS packages, container images, the fleet-stacks repo, Let's Encrypt, and Cloudflare's API. bh01 also needs port 7844 outbound, over TCP and UDP, for its tunnel. mx01 also needs port 25 outbound, to deliver mail.
Allow nothing else from the DMZ inward, and forward no port to bh01. The web reaches bh01 through the tunnel it opens outward.
The diagram shows the four VLANs, the router that joins them, and the flows that cross it. Every arrow between two boxes passes through the router's firewall.
flowchart LR
internet[The internet]
router[Router and its firewall]
subgraph users[Users, VLAN 4]
shell[Control shell and your browser]
end
subgraph mgmt[MGMT, VLAN 1]
proxmox[Proxmox host, 172.16.1.11]
end
subgraph internal[Servers, VLAN 7, the internal network]
km01[km01, Komodo]
ci01[ci01, Semaphore]
tf01[tf01, Redis]
web[Every host's Traefik]
end
subgraph dmz[DMZ, VLAN 8]
bh01[bh01]
mx01[mx01]
end
router ---|gateway 172.16.7.1| internal
router ---|gateway 172.16.8.1| dmz
shell -->|8006 and 22| proxmox
shell -->|22, 443, 8443, and 9120 on km01| internal
shell -->|22, 443, and 8443| dmz
ci01 -->|8006 and 22| proxmox
proxmox -->|8025| ci01
ci01 -->|22| dmz
bh01 -->|9120| km01
bh01 -->|6379| tf01
bh01 -->|443| web
mx01 -->|9120, 6379, 443| internal
bh01 -->|tunnel, outbound 7844| internet
internet -->|mail ports, forwarded| mx01
The diagram draws mx01's three flows as one arrow. They go to km01, tf01, and to ci01 and id01, as the table says. It leaves out the router's lines to Users and MGMT, whose gateway addresses these pages do not give, and ci01's mail to mx01 on port 587.
The hosts' own firewalls¶
The router is one of two firewalls on each path. Every VM has a firewall of its own, written by the build, so no rule on a VM is yours to add by hand.
| A VM opens | To |
|---|---|
| SSH, port 22 | Any address, with a rate limit |
| Traefik's ports 80, 443, and 8443 | Any address |
| Komodo Core, port 9120 on km01 | Any address |
| The mail ports on mx01 | Any address |
| Redis on tf01, port 6379 | The internal subnet |
| Syslog, the Dozzle agent, and ci01's two SMTP ports | The internal subnet |
The internal subnet is the value of docker_stacks_internal_subnet in the inventory. A port opened to it is closed to every other VLAN, which is why bh01 and mx01 are each added to tf01's docker_stacks_port_sources by address. The Proxmox host needs the same on ci01 for port 8025. See Send Proxmox's notifications to mailrise. See Admit the DMZ on tf01 and The firewall.
Names¶
Every web interface in the fleet is reached by name. Traefik on each host picks the container from the name in the request, so an address alone gets no answer from it.
How a name is formed¶
The names are built from the domain, the site's subdomain, the host, and the service. In these pages the domain is myah-mitchell.com and the subdomain is home..
| Form | Example | Names |
|---|---|---|
<service>.<host>.home.myah-mitchell.com |
semaphore.ci01.home.myah-mitchell.com |
One service, by the host it runs on |
<host>.home.myah-mitchell.com |
tf01.home.myah-mitchell.com |
The host itself |
<service>.home.myah-mitchell.com |
ntfy.home.myah-mitchell.com |
A service by its short name, inside the site |
<service>.myah-mitchell.com |
auth.myah-mitchell.com |
A public name, reached through bh01's tunnel |
<service> is the service's name, such as komodo or traefik, and <host> is the VM's, such as km01. The first form is the one the build pages send you to. See Conventions in the fleet-stacks repo for the variables behind the forms.
Three ways a name resolves¶
No host in this guide runs a DNS server. A name resolves because you, or later dockns, put it somewhere a resolver looks.
| Way | Works for | Used when |
|---|---|---|
| A line in your own machine's hosts file | Your browser and your shell, on that machine alone | Opening a web interface, at any stage |
| A record on your own DNS server | Every machine that uses the server, the VMs and their containers included | A container has to look the name up |
| A record written by dockns | The same as the row above | Not yet, for internal names. See dockns |
The hosts file¶
A hosts file is a list of names and addresses that a machine consults before it asks DNS. Each line is an address, a space, and one or more names:
| System | File |
|---|---|
| Linux | /etc/hosts |
| macOS | /etc/hosts |
| Windows | C:\Windows\System32\drivers\etc\hosts |
Editing it needs root on Linux and macOS, and an editor run as administrator on Windows. The file has no wildcards, so each name needs to be written out.
A record on your DNS server¶
A hosts file on your machine does nothing for a container on a VM. Some containers look a fleet name up themselves, and they ask the VM's DNS server, which is the network's gateway in these pages.
Those names need an A record on that server, pointing at the host's address. The DMZ's DNS server has to resolve the same internal names, because bh01 looks up tf01. How a record is added depends on what serves your DNS.
dockns¶
dockns is a container in the system-agent stack. It writes a DNS record for each container on its host that carries dockns labels, on a UniFi console for internal names and at Cloudflare for public ones. It first runs when a host leaves bootstrap mode.
As the fleet-stacks repo stands, dockns writes no internal record. Only ntfy, Stalwart, and Bulwark carry its labels, and those labels name a server called technitium, while system-agent sets dockns up with unifi and cloudflare. Keep every hosts file line and every record made by hand after the fleet leaves bootstrap mode. See Leaving bootstrap mode.
Which name each page needs¶
Each row is the first page that needs the name. A name marked DNS server has to be a record, because a container looks it up. For the others, a hosts file line on your own machine is enough.
| Page | Name | Points at | Where |
|---|---|---|---|
| The first run | komodo.km01.home.myah-mitchell.com |
172.16.7.101 |
Hosts file. Optional, since http://172.16.7.101:9120 works without a name |
| Semaphore (ci01) | semaphore.ci01.home.myah-mitchell.com |
172.16.7.121 |
Hosts file |
| VictoriaMetrics (ci01) | grafana.ci01.home.myah-mitchell.com |
172.16.7.121 |
Hosts file |
| Core infrastructure (ci01) | uptime-kuma.ci01.home.myah-mitchell.com |
172.16.7.121 |
Hosts file |
| Identity (id01) | authentik.id01.home.myah-mitchell.com |
172.16.7.131 |
Hosts file |
| Certificates (pk01) | step-ca.pk01.home.myah-mitchell.com |
172.16.7.141 |
Hosts file |
| Traefik hub (tf01) | tf01.home.myah-mitchell.com |
172.16.7.111 |
DNS server |
| Traefik hub (tf01) | traefik.tf01.home.myah-mitchell.com |
172.16.7.111 |
Hosts file |
| DMZ edge (bh01) | tf01.home.myah-mitchell.com, from the DMZ |
172.16.7.111 |
DNS server |
| DMZ edge (bh01) | traefik.bh01.home.myah-mitchell.com |
172.16.8.111 |
Hosts file |
| Leaving bootstrap mode | authentik.id01.home.myah-mitchell.com |
172.16.7.131 |
DNS server |
| Leaving bootstrap mode | vmauth.ci01.home.myah-mitchell.com |
172.16.7.121 |
DNS server |
| Mail (mx01) | mail.mx01.home.myah-mitchell.com |
172.16.8.121 |
Hosts file |
| Applications (ap01) | dozzle.ap01.home.myah-mitchell.com |
172.16.7.151 |
Hosts file |
Public names, such as auth.myah-mitchell.com, are records at Cloudflare that a command on bh01's page creates. See Publishing a hostname.
Not yet confirmed¶
Nothing on this page has been tried against a router or a running fleet. It is derived from the build pages and the fleet's repos.
- The list of flows. It is collected from the host pages, the stacks' firewall rules, and the connections the run makes. No fleet has been built behind a firewall that allows only these.
- How MGMT reaches the Proxmox host. The pages give the host's address and say the bridge is VLAN aware. Whether MGMT arrives untagged on the Proxmox host's port is not stated anywhere.
- The subnets and gateways of Users and MGMT, which these pages do not give. Write the rules from Users with your own.
- The Proxmox host to ci01 on port 8025. It follows from the Proxmox host being on MGMT while ci01 opens that port to the internal subnet alone. No page listed it before, and Proxmox Backup Server needs the same from wherever it runs.
- ci01 to the Proxmox host on port 22. It follows from Semaphore running the same install as the shell, which logs in to the Proxmox host. No page lists it as a rule.
- dockns on bh01. mx01's page says dockns needs to reach the UniFi console, and bh01 runs the same system-agent after bootstrap mode. bh01's page lists no such rule.
- The browser's ports. 443, 8443, and 9120 on km01 come from the addresses the pages open. A page may open another port directly.
- Outbound internet for the internal hosts. The pages list the ports for bh01 and mx01, and say of km01 only that it can reach the internet.
- The names table. It lists the first name each page opens. A page may open further names on the same host, each of which needs a line of its own.
- The hosts file paths and the form of a line. They are each system's standard ones and were not checked on a machine for this build.