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]

Reply via email to