Jail as a gateway for external devices

Hi Guys,

I am configuring OpenVPN in a FreeBSD Jail. The VPN itself is configured and works well, no problems here: when I am inside the Jail I can see that all traffic goes through VPN.

21:00:57.358613 IP > syd15s01-in-f14.1e100.net: ICMP echo request, id 61699, seq 0, length 64
21:00:57.692905 IP syd15s01-in-f14.1e100.net > ICMP echo reply, id 61699, seq 0, length 64

where 10.18.x.x is VPN.

Now I want to use this Jail as a default gateway for my external devices. The idea is that I can use the jail IP as a default gateway and all the traffic from these devices would be "automagically" routed through my VPN.

However, when I do that (and I run tcpdump inside the jail) I see only outgoing traffic:

20:53:23.263597 IP > syd15s01-in-f78.1e100.net.https: UDP, length 109
20:53:23.263636 IP > syd15s01-in-f78.1e100.net.https: UDP, length 109

where is my laptop IP address in a non-VPN network.

I guess that instead of I should see something like 10.18.x.x in order to make it work?

So what should I do to make it work and to be able to have my devices traffic going through the jail transparently?

Note that routing isn't done within the jail but on the host. From within the jail you can't add routes or change the network settings (specifically, routing needs to be enabled).
I wonder why you even want to run your VPN service in a jail? I hope you're aware that after the VPN tunnel has been established the jail is no longer in picture at all, the traffic coming in trough the tunnel enters the host system directly. There's very little protection gained in running the VPN daemon in the jail and many additional complications to solve to get the daemon working in the jail because it can't (as already noted) for example modify the system's routing table or network interfaces from inside the jail.
Well, the reason of running VPN in a jail is that I didn't want to mess with the host operation system in the first place. It is not for the network protection so it is OK that the traffic comes to the host system.
I run other stuff in jails/containers too: from my own written daemons and torrent clients to web servers etc. It is just easier to maintain them this way.

But thanks, I think that I start understanding the traffic flow in this case.

Does it mean that if I make a route on the host system to redirect all the traffic from the VPN network (10.x.x.x) to the IP address of the VPN jail it will then work? Or not that simple? And how can I do it if I wanted?
If you really want to do it then a vnet jail should work. It has a seperate network stack from the host. It's a lot more work to set up however. I'm running a PPPoE link for ipv4 and a gif tunnel for ipv6 inside a vnet jail as my gateway for my network.

I have not tried a vpn link however so I don't know if there are any incompatibilities with vnet present.
Hm, from what I can tell I am already using a vnet jail. At least I created it as a VIMAGE one, and I have "epair1b" interface in it which is a member of a "bridge0" interface on the host system. It has its own IP and forwarding is enabled:

# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 1 -> 1

Does it mean that I miss some NAT somewhere around? Can you suggest where to look?

I tried to set up ipfw as:

# ipfw list
00100 nat 1 ip from to any via epair1b
00200 nat 1 ip from any to any in via epair1b
65535 allow ip from any to any

but it doesn't seem to help...
You need to put the nat on the interface of your vpn, which should be tun0 more than likely, and not on epair1b. You also didn't post how you configured your nat 1 instance. It should be something like this:

# ipfw config if tun0 reset deny_in same_ports unreg_only log
This is my full ipfw.rules:

#get epar name
EPAIR=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep epair)

#get tun0 address/mask
INNER="$(/sbin/ifconfig | grep " -->" | cut -d' ' -f2 | cut -d'.' -f1-3).0/24"

ipfw -q -f flush
ipfw -q nat 1 config if ${EPAIR}
ipfw -q add nat 1 all from ${INNER} to any via ${EPAIR}
ipfw -q add nat 1 all from any to any in via ${EPAIR}

TUN=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep tun)
ifconfig ${TUN} name tun0
As I said, the nat must be on the tun, not the epair. Add at bare minimum the deny_in to the nat 1 config.

The nat 1 config line needs to see the interface so you'll have to move your TUN lines higher.