Use this file to discover all available pages before exploring further.
The metal Salt state configures the two bare-metal hypervisor hosts (metal-us-east-01 and metal-us-east-02) that run all WikiOasis virtual machines via KVM/libvirt under Proxmox. The top-level state is a simple include list that composes six sub-states, each responsible for a distinct infrastructure concern. Metal hosts have a public IP, an internal private bridge for VM traffic, and a vRack interface for inter-host connectivity.
Enables net.ipv4.ip_forward via sysctl and manages iptables DNAT/MASQUERADE rules for port-forwarding traffic to VMs.
ssh
Deploys a hardened sshd_config from a Jinja template and reloads sshd on changes.
dns_dhcp
Registers VM hostname/MAC/IP records via the assign-host script, which drives the internal DNS and DHCP server.
ipv6_routing
Configures sysctl parameters for IPv6 forwarding and proxy NDP, and installs an if-up.d script to set up per-VM IPv6 routes on interface bring-up.
apt_proxy
Runs a Squid HTTP proxy on port 3129 that caches APT package downloads for all VMs on the internal network.
vm_ipv6
Assigns a /128 IPv6 address and default route to a specific VM based on its Proxmox VM ID and the host’s IPv6 prefix — applied on VM minions, not the metal host itself.
Installs the squid package, deploys the config file, and ensures the service is running and restarted on config changes. The proxy is used by VMs during the initial provisioning phase before Salt takes over; once Salt manages a host it enforces that /etc/apt/apt.conf.d/99proxy is absent so the proxy is no longer in the APT path.
# salt/metal/apt_proxy/init.slssquid: pkg.installed: [] service.running: - enable: True - watch: - file: /etc/squid/squid.conf - require: - pkg: squid/etc/squid/squid.conf: file.managed: - source: salt://metal/apt_proxy/files/squid.conf - user: root - group: root - mode: '0644' - require: - pkg: squid# The apt proxy config is only needed before Salt manages a host.# Enforce it is absent once Salt takes over./etc/apt/apt.conf.d/99proxy: file.absent
The Squid configuration is intentionally minimal — it listens on 0.0.0.0:3129 and allows access only from localhost and RFC 1918 10.0.0.0/8 addresses:
Deploys the /usr/local/sbin/assign-host management script and idempotently registers every hostname defined in the dns_hosts pillar key. The unless guard checks the existing host table before running, making repeated applies safe.
Enables IPv4 forwarding via sysctl and installs a templated script that applies iptables DNAT and MASQUERADE rules for each forwarding rule defined in the pillar. The script is re-run only when it changes (onchanges), keeping state application fast on subsequent runs.
metal.ipv6_routing — IPv6 Forwarding and Proxy NDP
Writes /etc/sysctl.d/99-vrack.conf to enable IPv4/IPv6 forwarding and proxy NDP, applies the settings immediately, and installs an if-up.d hook that re-applies VM IPv6 routes whenever a network interface comes up.
Deploys a Jinja-templated sshd_config to the metal host and reloads sshd on changes. The template is rendered with pillar data, allowing per-host SSH policy (e.g. allowed users, port, key types) without separate state files.
This sub-state runs on VM minions (not on the metal hosts). It derives the VM’s Proxmox ID and the metal host’s IPv6 prefix from the proxmox pillar, then assigns a /128 address <prefix>::<vmid> on the VM’s primary interface and sets the default route via the metal host’s link-local gateway.
# salt/metal/vm_ipv6/init.sls (condensed){%- set vm = salt['pillar.get']('proxmox:vms:' ~ grains['id'], {}) %}{%- set vmid = vm.get('vmid') %}{%- set host_cfg = salt['pillar.get']('proxmox:hosts:' ~ vm.get('metal_host', ''), {}) %}{%- set prefix = host_cfg.get('ipv6_prefix', '') %}{%- set gw_ll = host_cfg.get('vm_gateway_ll', '') %}{%- set iface = vm.get('interface', 'ens18') %}{%- if vmid is not none %}/etc/network/interfaces.d/ipv6.conf: file.managed: - source: salt://metal/vm_ipv6/files/interfaces.jinja - template: jinja - user: root - group: root - mode: '0644'ipv6_addr_{{ vmid }}: cmd.run: - name: ip -6 addr add {{ prefix }}::{{ vmid }}/128 dev {{ iface }} - unless: ip -6 addr show dev {{ iface }} | grep -q '{{ prefix }}::{{ vmid }}/128'ipv6_default_route_{{ vmid }}: cmd.run: - name: ip -6 route add default via {{ gw_ll }} dev {{ iface }} - unless: ip -6 route show | grep -q 'default via {{ gw_ll }}' - require: - cmd: ipv6_addr_{{ vmid }}{%- endif %}
For example, VM mw-us-east-011 with vmid: 160 on metal-us-east-01 (prefix 2604:2dc0:100:295c) receives address 2604:2dc0:100:295c::160/128.
# Apply all metal sub-states to both metal hostssalt 'metal*' state.apply metal# Apply a single sub-statesalt 'metal*' state.apply metal.apt_proxysalt 'metal*' state.apply metal.ip_forwardingsalt 'metal*' state.apply metal.ipv6_routing# Apply vm_ipv6 to VM minions (not metal hosts)salt 'mw*' state.apply metal.vm_ipv6# Dry-run firstsalt 'metal*' state.apply metal test=True
The metal.ip_forwarding sub-state modifies live iptables rules. Always run with test=True on metal hosts before applying changes to ip_forwarding pillar entries, since an incorrect DNAT rule can redirect live traffic to the wrong VM.