Router – How to get internal hosts to use a VPN connection set up on a FreeBSD router

freebsdpptprouterroutingvpn

Question in short: How do I get traffic from a host on an internal network, using NAT behind a router, to use a VPN connection set up on the router?

I have a FreeBSD 9 router with 4 network interfaces. One external connected to my ISP and the others connected to internal subnets. The internal interfaces use NAT (by pf) to connect to the external world.

Now, I would like to have all traffic from a host on one of the subnets use a PPTP VPN connection set up on the FreeBSD machine. The end result would be that a host on the internal network uses a VPN without having to use a VPN client on the host itself.

I've managed to set up the VPN client with mpd5. Connecting from the router to the VPN server with mpd5, I get a new network interface — ng0 — with an ip address.

My problem is that I don't know where to go from here. There's just an interface (ng0) with an IP address. How do I make traffic from the internal, NATed, network use the VPN connection?

If you're trying to answer or point me in the right direction, you can start with the assumption I don't know or understand anything about VPNs, routing, NAT or pf — which I clearly almost don't. (Adding a route from where to where? Adding pf rules doing what to incoming and outgoing packets? etc.)

Configuration

This is right after connecting to the VPN server from the router.

My network

My /etc/pf.conf:

ext_if = "em0"
local_if = "em1"
wifi_if = "em2"
misc_if = "em3"
localnet = "{" $local_if:network $wifi_if:network $misc_if:network "}"
nat on $ext_if from $localnet to any -> ($ext_if)
pass in all
pass out all keep state

Routing table:

Destination        Gateway            Flags    Refs      Use  Netif Expire
default            188.60.52.1        UGS         0   998893    em0
10.0.1.0/24        link#10            U           0   159240    em1
10.0.1.1           link#10            UHS         0      358    lo0
10.0.2.0/24        link#11            U           0   503719    em2
10.0.2.1           link#11            UHS         0        0    lo0
10.0.3.0/24        link#12            U           0  3773731    em3
10.0.3.1           link#12            UHS         0        0    lo0
98.158.118.1       link#15            UH          0        0    ng0
98.158.118.63      link#15            UHS         0        0    lo0
127.0.0.1          link#13            UH          0        0    lo0
188.60.52.0/22     link#9             U           0        0    em0
188.60.55.17       link#9             UHS         0        0    lo0

To connect to the VPN server I have this in /usr/local/etc/mpd/mpd.conf:

strongvpn:
    create bundle static B1
    set bundle yes compression
    set ipcp ranges 0.0.0.0/0 0.0.0.0/0
    set ccp yes mppc
    set mppc yes e128
    set mppc yes stateless

    # Not using these yet, as I don't know what to put in them ...
    #set iface up-script /usr/local/etc/mpd5/ip-up.sh
    #set iface down-script /usr/local/etc/mpd5/ip-down.sh

    create link static L1 pptp
    set link action bundle B1
    set auth authname XXXXXXXXX
    set auth password XXXXXXXXX
    set link max-redial 0
    set link mtu 1460
    set link keep-alive 20 75
    set pptp peer 98.158.112.17
    set pptp disable windowing
    open

Best Answer

The key question here is, "Did you try the VPN yet?" Everything seems fine. If your FreeBSD box can already route to the remote side of the VPN, your job is almost done. That means that the connection is valid and it is aware of the route to the remote network.

The host behind the router shouldn't require any changes at all to communicate "through the VPN." If it has the router set as its default gateway, then all traffic to remote networks (including the other side of the VPN) should go through the router, which as we stated, is already aware of the appropriate route. If you want to be very explicit, add a static route to the routing table of the host in question to ensure that it is aware of the correct route to the remote side of the VPN.