# Warden pf Rules

Use this file when you need the minimal firewall shape for Warden jail egress.

## Minimal NAT model

```pf
ext_if = "vtnet0"
warden_net = "192.168.100.0/24"

nat on $ext_if from $warden_net to any -> ($ext_if)
pass quick on warden0 inet from $warden_net to any keep state
```

That is the baseline rule set. Do not add broad filtering complexity until
basic egress works.

## Recommended structure

Keep Warden rules in a dedicated include file or dedicated section. Avoid
mixing Warden NAT with unrelated firewall logic.

Example concept:

```pf
ext_if = "vtnet0"
table <clawdie_jails> persist { 192.168.100.0/24 }

nat on $ext_if from <clawdie_jails> to any -> ($ext_if)
pass quick on warden0 inet from <clawdie_jails> to any keep state
```

## Validation

Before loading rules:

```sh
pfctl -nf /etc/pf.conf
```

After loading rules:

```sh
pfctl -sn
pfctl -sr
```

Expected:

- `pfctl -sn` shows a NAT rule for `192.168.100.0/24`
- `pfctl -sr` shows a `pass quick on warden0 ... keep state` rule

## DNS note for Bastille jails

Do not blindly reuse the host resolver file when the host is using Tailscale
MagicDNS.

If a jail receives:

```conf
nameserver 100.100.100.100
```

that can be wrong for the Warden VNET jail model.

Preferred Bastille resolver file:

```conf
nameserver 1.1.1.1
nameserver 9.9.9.9
```

and set in `bastille.conf` as:

```sh
bastille_resolv_conf="/usr/local/etc/bastille/resolv.conf"
```

## What not to add first

- per-jail Tailscale rules
- complex pass/block logic
- multi-subnet abstractions
- browser VM rules

Those belong later.
