# Tunneling Internet over OpenVPN



## zipitup (Nov 2, 2014)

Hi guys,

I have been cracking my head for the past few weeks on this. Appreciate some help.

I have managed to get connected to my FreeBSD server via OpenVPN with TunnelBlick.
I can connect to my server, no problem. Except that I cannot get connected to the Internet during the VPN session - I want to route all Internet via the VPN session.

I have done the following:
1) IP forwarding enabled on FreeBSD
net.inet.ip.forwarding is 1
2) I have disabled ipfw just to get that out of the way. I also run `tail -f /var/log/security` during the VPN session to make sure nothing is being blocked.
3) gateway_enable=YES in rc.conf
4) This is also in the openvpn server configuration file:

```
push "redirect-gateway def1"
```
5) I also tried natd_enable=YES (interface "vtnet0", flags "-dynamic -m")

So, when I do `tcpdump -i tun0` I see all the traffic request from my laptop.
When I look at `tcpdump -i vtnet0` (Internet facing interface) - I see nothing.

To me, this looks like it is not redirecting traffic.

What am I missing? Some help would be appreciated..

Thank you.


----------



## zipitup (Nov 2, 2014)

This is my `netstat -nr`:


```
root@1:~ # netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            108.61.206.1       UGS         0       36 vtnet0
10.8.0.0/24        10.8.0.1           UGS         0        0   tun0
10.8.0.1           link#4             UH          0        0   tun0
10.99.0.0/16       link#2             U           0        0 vtnet1
10.99.0.10         link#2             UHS         0        0    lo0
108.61.206.0/23    link#1             U           0        0 vtnet0
108.61.206.158     link#1             UHS         0        0    lo0
127.0.0.1          link#3             UH          0        0    lo0
169.254.0.0/16     52:54:00:47:ae:b1  US          0        0 vtnet0
```

And openvpn.conf:


```
root@1:/usr/local/etc/openvpn # cat openvpn.conf
port 443
proto tcp
;proto udp
dev tun
topology subnet

ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/keys/server.crt
key /usr/local/etc/openvpn/keys/server.key
dh /usr/local/etc/openvpn/keys/dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 3
;mute 20
```


----------



## obsigna (Nov 2, 2014)

I cannot tell anything about OpenVPN, however I can tell that besides any VPN software, you need some other requisites in place in order to achieve your objective – Tunneling Internet over OpenVPN:

You need to have NAT enabled on the WAN (= internet) interface of the gateway
You need to get OpenVPN somehow to establish proxy-arp for the virtual IP address of the connected VPN client
You mentioned TunnelBlick, which is a OpenVPN-GUI-Client for Mac OS X. Perhaps you know, that Mac OS X comes with a built-in L2TP/IPsec client. And you can install a L2TP/IPsec dial-in server on FreeBSD, which does exactly what you want to achieve, only with another VPN technology.

Some years ago I wrote a HowTo on this utilizing security/ipsec-tools and net/mpd5 – see: http://forums.freebsd.org/threads/howto-set-up-a-l2tp-ipsec-vpn-dial-in-server-part-i-to-iii.26755/

security/ipsec-tools got its issues, and recently I switched my setup to security/strongswan, and I am very satisfied, as far it goes for Mac OS X and iOS clients. My new setup is summarized on my BLog: http://blog.obsigna.net/?p=520.

It is written in German, however, I found the Google-Translator does a pretty good job translating it in any other target language: This would be the link to translate it into Portuguese: https://translate.google.com/translate?sl=de&tl=*pt*&js=y&ie=UTF-8&u=http%3A%2F%2Fblog.obsigna.net%2F%3Fp%3D520

Replace *pt* to whatever target language you need.


----------



## kpa (Nov 2, 2014)

Proxy-ARP is not needed with OpenVPN, I've never seen any OpenVPN guide mention it and I've never had to use it on the VPN setups I've set up myself.


----------



## obsigna (Nov 2, 2014)

kpa said:


> Proxy-ARP is not needed with OpenVPN, I've never seen any OpenVPN guide mention it


Which perhaps only tells us, that you haven't seen everything yet, how about this one: http://www.nimlabs.org/dirtynat.html



kpa said:


> I've never had to use it on the VPN setups I've set up myself.



Do you positively confirm herewith that your OpenVPN-Clients can connect to the internet and all traffic is routed by the way of your VPN gateway? In this case you want to tell to the OP, how you achieved that without Proxy-ARP.


----------



## zipitup (Nov 2, 2014)

Thanks obsigna, I could try your implementation as my last resort. I however would still prefer to get OpenVPN working as I have Asus routers that I would like to create a site-to-site VPN link. I did a quick google, Asus router only support PPTP and OpenVPN.

kpa: Mind sharing your setup with me?


----------



## zipitup (Nov 2, 2014)

I was just reading more, but the articles are pretty old.

Would we still need to recompile the kernel with the following options on the current FreeBSD?

```
options IPFIREWALL
options DUMMYNET
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPDIVERT
```


----------



## obsigna (Nov 2, 2014)

zipitup said:


> Would we still need to recompile the kernel with the following options on the current FreeBSD?
> 
> ```
> options IPFIREWALL
> ...



The above options compile the ipfw(8) modules into the kernel. Since all of these are available as loadable modules, you do not need to build a custom kernel. It would be sufficient to place the following in your /etc/rc.conf:


```
firewall_enable="YES"
firewall_type="open"
# replaces the old NAT over divert mechanism by modern in kernel NAT
firewall_nat_enable="YES"
# optional if you don't use a custom firewall script for setting up NAT
firewall_nat_interface="<WAN interface>"
firewall_nat_flags="<the flags you want>"

# traffic shaping
dummynet_enable="YES"
```

However, I fail to see how traffic shaping would help you in the given respect. Perhaps, it would be better to enable it later, when you got the other stuff running.


----------



## kpa (Nov 3, 2014)

Why do you think Proxy-ARP is needed with OpenVPN? You have either the tun(4) or the tap(4) adapter. With the first one point-to-point semantics are used and arp(8) doesn't come to play, with the latter the interface does proper arp(8) on its own. The only time I've seen Proxy-ARP needed on a VPN is with the PPTP VPN on pfSense (when I was still using it) because the only way you can get it working is handing addresses from the LAN address pool to the clients and you have "fake" the ARP for those addresses used for the VPN clients. OpenVPN doesn't need to use such tricks to work.

I don't have my road warrior set up to share right now but there's really not a whole lot to the set up or do differently than on other OSes. The examples in the OpenVPN distribution do work on FreeBSD pretty much out of the box but you have to make sure you set up outbound NAT properly for the VPN subnet as already noted in this thread.


----------



## kpa (Nov 3, 2014)

Here's a trick that might help you. It is using up/down scripts for setting up and tearing down the NAT for the VPN subnet automatically at service start/shutdown. This is for PF but you adapt them for other packet filters easily.

I have these settings in my openvpn.conf:

```
script-security 2
# Passes the name of the WAN interface to the up/down scripts.
setenv-safe wan vr0
setenv-safe anchor openvpn
...
up /usr/local/etc/openvpn/up.sh
down /usr/local/etc/openvpn/down.sh
```

Then the scripts themselves, up.sh:


```
#!/bin/sh

ANCHOR="${OPENVPN_anchor}"

/sbin/pfctl -a "${ANCHOR}" -F rules
/sbin/pfctl -a "${ANCHOR}" -F nat

/sbin/pfctl -a "${ANCHOR}" -f - <<EOT
nat on "${OPENVPN_wan}" inet from "${dev}:network" to any -> ("${OPENVPN_wan}:0") port 1024:65535
pass quick on "${dev}" all
pass in quick on "${OPENVPN_wan}" inet proto udp from any to (${OPENVPN_wan}) port "${local_port_1}"
EOT
```

The down.sh script:


```
#!/bin/sh

ANCHOR="${OPENVPN_anchor}"

/sbin/pfctl -a "${ANCHOR}" -F rules
/sbin/pfctl -a "${ANCHOR}" -F nat
```


----------



## zipitup (Nov 3, 2014)

Ok I have given up on using ipfw with natd. It seems like it does not work no matter what - or no one wants to document it online to help.

Please feel free to prove me wrong.

Mean time there are many other implementations with pf.

For future googlers coming here to look for a solution, here is what I did (besides enabling pf in rc.conf):

In /etc/pf.conf:

```
ext_if="vtnet0" #external / Internet facing interface
nat on $ext_if inet from !($ext_if) -> ($ext_if:0)
```

The reference came from http://www.reddit.com/r/freebsd/comments/2fwy6e/openvpn_help_cannot_access_internet/

This will set a permanent NAT for any other interface.

kpa's implementation above may work as well, but I did not test it. From how it looks, it only creates NAT when a VPN session is established, and NAT-ing all/specific ports (? I still need to study pf command lines).


----------



## kpa (Nov 3, 2014)

zipitup said:


> kpa's implementation above may work as well, but I did not test it. From what it looks, it only creates NAT when a VPN session is established, and NAT-ing all/specific ports (? I still need to study pf command lines).



It creates the rules when the openvpn(8) service is started and removes them when the service is shut down. In addition it allows all traffic on the tunnel interface, this should be modified if you have a need to filter anything on the VPN interface.


----------

