On Sat, Dec 14, 2024 at 02:07:13PM +1000, David Gwynne wrote:
> On Thu, Dec 12, 2024 at 06:01:37PM -0400, Christopher Sean Hilton wrote:
> > Hi,
> >
> > I'm trying to setup a pair of OpenBSD machines to handle their respective
> > home networks and
> > create a IKEv2 VPN tunnel between them. If I call one side _home_ and one
> > side _remote_ I
> > think that defines things. The main function of the tunnel is to allow
> > stuff on the _remote_
> > network to access services in the _home_ network. As a second function, I
> > want a handful of
> > hosts in the _remote_ network to consume the internet via the _home_
> > network's ISP. My
> > `iked.conf` files look like this:
> >
> > [...snip...]
>
> the thing i think you're missing is that enc0 is not a real interface.
> it largely exists so you can see what the ipsec stack is doing with
> things like tcpdump via bpf. however, assigning an IP to it and
> expecting to be able to route over it is not supported, even if some of
> that appears to work.
>
> > [...snip...]
>
> ok. ive written this up before, so i'll paste it and tweak it here:
>
> For a packet going through an OpenBSD router, these are the main
> steps:
>
> 1. Packet is received by the incoming network interface
> 2. Packet is shown to BPF
> 3. PF processing for incoming packets
> 4. IP routing/stack processing
> 5. PF processing for outgoing packets
> 6. Packet is shown to BPF on outgoing interface
> 7. Transmission on the outgoing interface
>
> There are a couple of interesting things to note here.
>
> PF is run twice for packets going through a router/firewall. Once when
> the packet is received by a network interface and before the IP stack,
> and again when the packet leaves the IP stack and goes out to a network
> interface.
>
Thanks for this! It will help me to debug and fix the problem. If I have to,
I'm assuming
that I can something like this
```
## Remote iked.conf
...
from $full-vpn-subnet to any \
...
```
And this?
```
## Home side pf.conf
...
match in on enc0 from <full-vpn-subnet> to !<local-networks> nat to
($ext_if)
...
```
If that doesn't work, I've read the man page for the sec interface and that may
help me out
with the problem that I have. Before I set this up I had figured out how to do a
split-tunnel VPN between OpenBSD and a MacOS client. I experimented and figured
out how to
change that into a full-tunnel VPN. That solves my problem in a different way
but this is
still interesting to me. I'd love to have a VPN setup remotely and to determine
where
packets "leave my infrastructure" based on the address they get from the DHCP
server.
> [...snip...]
>
> Just to be clear, the source IP or the network interface a packet was
> received on does not affect the route lookup performed by the IP stack,
> it is only the destination IP address that is used. Also, packets in
> each direction of a connection are routed independently, meaning replies
> need to be routed correctly too.
>
> Generally, by the time pf gets to see a packet going out an interface,
> it is too late to affect where it's going because that decision has
> already been made by the route lookup in the IP stack.
>
> [...snip...]>
>
> these steps ignore ipsec processing though. the ipsec policy database
> (SPD) is consulted between steps 4 and 5 above. if a packet matches the
> SPD, it's taken away from the stack processing, encrypted (and shown to
> bpf on enc0) and then injected back into the stack at step 4 so it can
> figure out where the encrypted packet is supposed to be routed to.
>
> the stuff above also ignores what pf can do to a packet. if pf rewrites
> or reroutes a packet in step 5, the packet is basically taken back
> to step 4 for a new route lookup, and then skips step 5 again.
>
> so what does this mean for what you're trying to achieve?
>
> firstly, if you want to send packets from hosts in the <full-vpn> table
> over the vpn, you need to do more than just change the source ip. as
> described above, the routing table sends packets somewhere based
> entirely on the destination address, which nat-to doesn't affect at all.
>
> it is possible that you could write ipsec config that will generate SPD
> entries that will take these packets and move them over the ipsec link.
> that config might look like this:
>
> home_network="192.168.1.0/24"
> remote_network="192.168.2.0/24"
>
> ikev2 passive esp \
> from any to dynamic \
> from $home_network to $remote_network \
> from any to $full_vpn_1 \
> from any to $full_vpn_2 \
> from any to $full_vpn_n \
> ...
>
> and on the remote side:
>
> ikev2 active esp \
> from dynamic to any \
> from $remote_network to $home_network \
> from $full_vpn_1 to any \
> from $full_vpn_2 to any \
> from $full_vpn_n to any \
> ...
>
> alternatively, you could use sec(4) (or wg(4) or openvpn or something),
> which would let you use routes and pf to control which packets get sent
> where. if you went that way you would need to use a separate routing
> table/domain for the <full-vpn> hosts, or route-to in pf to control
> where those packets go.
>
> tl;dr: either use ipsec policy to control where packets go with vanilla
> ipsec peers, or use routes/pf to control where packets go over a tunnel
> like sec(4). don't use routes/pf to try and control ipsec policy.
>
Thanks again. Right now I'm not in a place where I feel I can safely experiment
with this if
it means playing the firewall on the home box. I will be in a couple of days
and I will
setup a test rig to figure things out.
Thanks
--
Chris
__o "All I was trying to do was get home from work."
_`\<,_ -Rosa Parks
___(*)/_(*)____.___o____..___..o...________ooO..._____________________
Christopher Sean Hilton [chris/at/vindaloo/dot/com]