Wheelhouse docs

Every installer question#

Arrow keys move, space toggles a checkbox, Enter accepts. The installer asks for a disk, a host name, a time zone, two interfaces and what to do with them, and two passwords; three of the screens only appear for particular answers. It builds a file of set commands from what you said and shows you that file before it does anything. This page walks the screens in the order they appear and says what each answer writes. Nothing on this page has touched the disk: the summary screen at the end is the point of no return.

Disk#

Every block device lsblk reports as a disk, except the one you booted from, with its size and model. Loop, zram, optical, ramdisk and floppy devices are filtered out.

Everything on the disk you pick is erased. If the list is empty, the machine has no disk other than the install medium and the installer says so and sends you back.

Host name#

Letters, digits and hyphens, one to 63 characters, not starting or ending with a hyphen — the installer enforces exactly that pattern and refuses a name the router would not accept rather than silently rewriting it. The default is wheelhouse.

It becomes the router's host name and the common name on the self-signed certificate the agent generates.

set system host-name wheelhouse

Time zone#

A region first, then a zone inside it. The regions come from the machine's own timedatectl list-timezones output, filtered to the ones containing a / so that legacy names like EST5EDT are not offered, with UTC added as a region on its own. The default is whatever the live system currently thinks it is.

Logs, the audit trail and certificate validity all read from this.

set system time-zone Europe/Berlin

WAN — the internet side#

Every Ethernet interface with its link state and current address, plus Set the WAN up later. Pick the one facing your modem or upstream.

  • DHCP — the usual case. The provider hands out the address.
  • Static — the installer then asks for the address with its prefix length, the provider's gateway, and resolvers as a comma-separated list. The prefilled examples are documentation-range addresses; replace them.
delete interfaces ethernet eth0 address
set interfaces ethernet eth0 description WAN
set interfaces ethernet eth0 address dhcp

Static instead produces the address, a default route and one set system name-server line per resolver you named:

delete interfaces ethernet eth0 address
set interfaces ethernet eth0 description WAN
set interfaces ethernet eth0 address 203.0.113.2/24
set protocols static route 0.0.0.0/0 next-hop 203.0.113.1
set system name-server 9.9.9.9
set system name-server 1.1.1.1

LAN — your network#

The same interface menu, minus whatever you chose as WAN, plus Set the LAN up later. Then the router's own address on that network with its prefix length. The default is 192.168.1.1/24. This is the address you will browse to.

delete interfaces ethernet eth1 address
set interfaces ethernet eth1 address 192.168.1.1/24
set interfaces ethernet eth1 description LAN

On a single-NIC machine this menu contains only skip, and the installer takes a different path from here — Boxes with one port.

LAN services#

Three checkboxes, all on by default. This screen only appears if you chose a LAN.

Hand out addresses (DHCP server) and answer DNS#

One checkbox for both, because they are configured together. It writes a DHCP pool covering the upper part of the LAN subnet and a DNS forwarder on the router's LAN address.

The pool starts at the hundredth usable address or the midpoint of the subnet, whichever comes first, and stops at the second-to-last usable address — so the low addresses stay free for things you number by hand. On the default 192.168.1.1/24 that is 192.168.1.100 to 192.168.1.253.

set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 subnet-id 1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option default-router 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option name-server 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 start 192.168.1.100
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 stop 192.168.1.253
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 lease 86400
set service dns forwarding listen-address 192.168.1.1
set service dns forwarding allow-from 192.168.1.0/24
set service dns forwarding cache-size 10000
set service dns forwarding dhcp eth0

The lease is one day. The forwarder listens on the router's LAN address only and answers only that subnet, so it is not an open resolver.

That last line is conditional. When the WAN is on DHCP, the forwarder takes its upstream resolvers from the WAN lease (set service dns forwarding dhcp <WAN>). Otherwise it uses the system's own resolvers (set service dns forwarding system), and if you did not name any on the static-WAN screen the installer adds 9.9.9.9 and 1.1.1.1 as system name-servers so that the forwarder has somewhere to ask.

A subnet too small for a pool skips the DHCP server rather than failing the install. The installer needs at least eight usable addresses; below that it writes the log line and carries on without a DHCP server.

Firewall#

Default-deny inbound on both address families. It is written whenever this box is left checked and there is a WAN — it does not need a LAN. The exact ruleset is below.

NAT#

One masquerade rule sharing the WAN address with the LAN. It needs both a WAN and a LAN; with either missing, nothing is written.

set nat source rule 100 description "LAN to WAN"
set nat source rule 100 outbound-interface name eth0
set nat source rule 100 source address 192.168.1.0/24
set nat source rule 100 translation address masquerade

Management access#

Only appears if you chose a WAN and skipped the LAN. The installer first states plainly what that combination means: the firewall blocks everything arriving from the WAN, so after the install the web UI is reachable only from the console until you add an interface or a rule. It then offers one way back in — an address or prefix allowed through the input filter to reach the router itself.

Leave it empty to allow nothing. Give it a prefix and you get one extra accept rule, in the family the address belongs to:

set firewall ipv4 input filter rule 50 action accept
set firewall ipv4 input filter rule 50 description "management source"
set firewall ipv4 input filter rule 50 source address 203.0.113.0/24

An address with a colon in it is treated as IPv6 and the rule goes into the v6 ruleset instead. One family, not both.

No firewall#

Only appears if you unchecked the firewall and chose a WAN. It is a confirmation that spells out the consequence — the router will accept anything arriving from the internet, including the web UI on 8443, with the first-boot admin password printed on the console banner — and its default answer is Turn it on.

Passwords#

Two of them, each typed twice.

  • The Wheelhouse admin password — the admin account in the web UI.
  • The console password — the vyos account you use at the console and, if you enable SSH later, over SSH.

Any non-empty password is accepted. There is no length rule and no character rule, on purpose: how long your password is, is your business. Under eight characters the installer says how many characters it is and offers Use it or Change it — a hint, not a refusal. An empty entry, or two entries that differ, is refused and asked again.

Both passwords are verified before the disk is touched. The console one is checked against the router's own /etc/shadow entry; the admin one by signing in to the agent with it. An install that finishes is an install you can log in to.

set system login user vyos authentication plaintext-password "$WH_VYOS_PASSWORD"

The console password is the one thing that stays a shell variable in the generated command file rather than being written into it. The file is expanded by the router's own shell from the environment, so the password never lands on disk in that file.

Summary#

  Disk:            /dev/sda  (erased)
  Host name:       wheelhouse
  Time zone:       Europe/Berlin
  WAN:             eth0 - DHCP
  LAN:             eth1 - 192.168.1.1/24, DHCP+DNS, NAT
  Firewall:        default deny in, IPv4 and IPv6, eth1 out
  Web UI account:  admin
  Console account: vyos

Three buttons:

ButtonWhat it does
InstallThe point of no return. What the installer does starts here.
BackCloses the summary and returns to the welcome menu. Choosing install again starts at the disk question with your previous answers as the defaults.
CommandsShows the exact list of set commands this install will run.

Commands is the screen worth reading. It is not a rendering of your answers; it is the file the installer then executes, so what you read and what runs cannot drift apart. It includes exactly which of the conditional firewall rules you are getting. The same file is copied onto the installed system afterwards as /config/wheelhouse/install.commands, mode 600, so months later you can see how the box was built.

You can produce the same file without booting anything — see below.

What the firewall checkbox writes#

Written whenever the box is left checked and there is a WAN. Conditional lines are marked.

set firewall global-options state-policy established action accept
set firewall global-options state-policy related     action accept
set firewall global-options state-policy invalid     action drop

set firewall ipv4 input   filter default-action drop
set firewall ipv4 input   filter rule 10   accept   inbound-interface <LAN>      (if there is a LAN)
set firewall ipv4 input   filter rule 20   accept   inbound-interface lo
set firewall ipv4 input   filter rule 30   accept   protocol icmp
set firewall ipv4 input   filter rule 40   accept   udp/68 on <WAN>              (if the WAN is DHCP)
set firewall ipv4 input   filter rule 50   accept   source <management source>   (if you gave one)
set firewall ipv4 forward filter default-action drop
set firewall ipv4 forward filter rule 10   accept   inbound-interface <LAN>      (if there is a LAN)

set firewall ipv6 input   filter default-action drop
set firewall ipv6 input   filter rule 10   accept   inbound-interface <LAN>      (if there is a LAN)
set firewall ipv6 input   filter rule 20   accept   inbound-interface lo
set firewall ipv6 input   filter rule 30   accept   protocol icmpv6
set firewall ipv6 input   filter rule 40   accept   udp/546 on <WAN>
set firewall ipv6 input   filter rule 50   accept   source <management source>   (if you gave one)
set firewall ipv6 forward filter default-action drop
set firewall ipv6 forward filter rule 10   accept   inbound-interface <LAN>      (if there is a LAN)
set firewall ipv6 forward filter rule 20   accept   protocol icmpv6

Four things worth understanding before the box faces the internet.

  1. Both families are filtered. A box filtered on one family and open on the other is not filtered, and a provider can bring IPv6 up without being asked. If the image turns out to have no firewall ipv6 configuration node, the installer leaves a marker, says so on a screen at the end, and writes the IPv4 ruleset — rather than committing a v4-only ruleset silently.
  2. ICMP is accepted from anywhere, WAN included, on both families. For IPv4 that is a choice: a router that does not answer ping is hard to diagnose, and you can narrow rule 30 later. For IPv6 it is not optional — neighbour discovery and path-MTU discovery are ICMPv6, and a router that drops them loses its own default route. The generated line for rule 30 falls back from protocol icmpv6 to protocol ipv6-icmp for older trees.
  3. The DHCP client is admitted explicitly — udp/68 on the WAN for v4, udp/546 for v6 — rather than left to depend on connection tracking, so a lease renewal or a delegated prefix cannot be dropped by the default-deny rule.
  4. Nothing here opens 8443 from the WAN. With a LAN, the web UI is reachable from the LAN. Without one, it is reachable from the console and from the management prefix you named, and nowhere else.

Seeing what an install would do, without doing it#

The installer can print the set commands a set of answers produces and stop. Printing changes nothing, so --commands is the one mode that does not re-run itself under sudo and does not refuse to run on an installed system. It is how you review a firewall before committing to it, and how you check a seed before handing it a fleet:

bash
wheelhouse-install --answers /tmp/answers --commands

The answers file is KEY=VALUE lines. The keys the installer reads are, in the script's own order: DISK, OVERWRITE, HOSTNAME, TIMEZONE, WAN_IFACE, WAN_ADDRESSING, WAN_ADDRESS, WAN_GATEWAY, WAN_DNS, LAN_IFACE, LAN_ADDRESS, LAN_DHCP, FIREWALL, NAT, MGMT_SOURCE, ADMIN_PASSWORD, VYOS_PASSWORD, REBOOT, POWEROFF, KEEP_PREVIOUS, CONFIG_COMMANDS, CONFIG, SSH_KEYS, ON_ERROR. Anything else in the file is ignored. Leave WAN_IFACE or LAN_IFACE empty to skip that half.

It is the same file the Commands button shows, and the same one the install then runs.

See also#


Checked against packaging/wheelhouse-install, packaging/dialogrc, packaging/seed-to-answers.py, docs/install.md, docs/security.md, tools/tests/test_install_commands.py.

Updated 2026-09-02 install installer firewall dhcp