Page 1 of 1

Configuring VPN Server on OS X 10.8.2 as Router with NAT !

Posted: Tue Oct 02, 2012 10:24 pm
by viktorf768
Until today i could not google the information how to configure a VPN Server on OS X 10.8.2 as a router with NAT. The network traffic has to be routed from network interface "tun01" to "en0" (in most cases the interface of the network cable). In all located informations there is one required command missing. Without this command the VPN Server does not act as router with NAT for forwarding an request to the Gateway of the Servers LAN.

The commands for configuring a VPN Server on OS X 10.8.2 to work as a router with NAT are:

Code: Select all

sysctl -w net.inet.ip.fw.enable=1
sysctl -w net.inet.ip.forwarding=1
natd -interface en0
ipfw add divert natd ip from any to any via en0
The command "sysctl -w net.inet.ip.fw.enable=1" is missing in all public hints that can be found over google.
I could solve the problem, cause there was one dependency to this system variable mentioned in the manual pages of the command "ipfw" (man ipfw). It was very difficult to find this additional dependency, and it would be great if this information can be published on many places.

Thanks.

Configuration of OS X 10.8.2 with OpenVPN, routing and NAT

Posted: Mon Oct 22, 2012 11:35 am
by viktorf768
If the commands for configuring OS X 10.8.2 as router with NAT are executed at startup with a DaemonLaunch Process , there has to be a "sleep 15" in the script, cause the network interface needs time to be up, otherwise the network interface wont work at all.

Complete solution for routing and NAT after restart of OS X 10.8.2 server:

1) Create directory and script for executing the command:

Code: Select all

su
mkdir /Library/Application\ Support/vpn
vi /Library/Application\ Support/vpn/enable-vpn-forward-nat.sh
Content for "enable-vpn-forward-nat.sh":

Code: Select all

#!/bin/bash
#
# Sleep is necessary cause network has to be up at the time of following commands
# Otherwise the network will not work at all
#
sleep 15
#
sysctl -w net.inet.ip.fw.enable=1
sysctl -w net.inet.ip.forwarding=1
natd -interface en0
ipfw add divert natd ip from any to any via en0
Set file "enable-vpn-forward-nat.sh" executable:

Code: Select all

chmod 755 /Library/Application\ Support/vpn/enable-vpn-forward-nat.sh
Create LaunchDaemon "enable-vpn-forward-nat.plist":

Code: Select all

su
vi /Library/LaunchDaemons/enable-vpn-forward-nat.plist
Content for "enable-vpn-forward-nat.plist":

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
        <key>Label</key>
                <string>enable-vpn-forward-nat</string>
        <key>ProgramArguments</key>
                <array>
                        <string>/Library/Application Support/vpn/enable-vpn-forward-nat.sh</string>
                </array>
        <key>RunAtLoad</key>
                <true/>
</dict>
</plist>
Imporant: A path with spaces (as ".../Application Support/...") does not get the "\" as escape character in the .plist file.

Test load of Daemon (check errors in console):

Code: Select all

launchctl load enable-vpn-forward-nat.plist
Now routing and NAT are also available after a restart (= permanently)

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Wed Oct 24, 2012 2:50 pm
by stvs
Thank you very much! This was necessary to get a working OpenVPN server on OS X Server up and running. See here for a terse description.

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Thu Nov 08, 2012 4:23 pm
by stvs
I'd like to get this working with a firewall, but am running into DNS problems. Any suggestions for the correct ipfw ruleset would be appreciated.

This ruleset works great:

Code: Select all

add 500 divert natd ip from any to any via en0
add 65535 allow ip from any to any
This ruleset breaks DNS -- I can hit a webserver on the LAN by its IP via an OpenVPN client, but not domain name:

Code: Select all

# Loopback
add 10 allow all from any to any via lo0
add 11 deny all from any to 127.0.0.0/8
add 12 deny all from 127.0.0.0/8 to any

# Devices
add 300 allow all from any to any via en0
# VPN tun
add 301 allow all from any to any via tun0

# statefull
add 400 check-state
add 401 allow tcp from any to any established
add 402 allow tcp from any to any out
add 403 allow udp from me to any

# OpenVPN
# NAT
add 500 divert natd ip from any to any via en0
# OpenVPN ports
add 501 allow udp from any to any 443,1194

# ssh
add 12302 allow tcp from any to any 22
# all the other services ... 

# Block rule
add 65534 deny ip from any to any
The line that breaks things is the last one -- the whole purpose of the firewall. I would have thought that I added all necessary rules above that so that DNS for OpenVPN clients would work, but apparently not. What rule am I missing?

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Sun May 05, 2013 9:54 pm
by ecchi
Hi, I've attempted to use the suggested commands, but it appears to break things even more - the server is no longer accessible by the clients, and all internet access goes down (remote in or ping from the server to an external website doesn't work).

Any thoughts?

Thread basically repeating what I'm asking: topic12822.html

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Sun Oct 27, 2013 12:31 am
by stvs
This worked great on Mountain Lion, but no longer works on Mavericks. Now OpenVPN no longer works, and if I run this ipfw script, it breaks my server's internet and LAN access as well! It looks like ipfw and natd are obsolete on OS X, and it's finally time to learn how to implement divert using pfctl.

Has anyone used pfctl with OpenVPN? What are the command to obtain a divert, as done above with natd/ipfw?

The natd command throws the error on Mavericks:
natd: Unable to bind divert socket.: Address already in use

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Fri Nov 08, 2013 3:11 pm
by stvs
I read The Boof of PF and figured it out. The essential pfctl NAT and filter rules are

Code: Select all

nat on en0 from 10.0.0.0/8 to any -> (en0)
pass from { lo0, 10.0.0.0/8 } to any keep state
and you have to do a lot of trial-and-error to make sure you don't break your access while integrating these rules into OS X Server's basic rule set. A description of the complete setup with the following pf.conf is here.

sudo vi /etc/pf.conf

Code: Select all

# References for modifications:
# The Book of PF by Peter N.M. Hansteen
# http://hints.macworld.com/article.php?story=20121011004626997
# http://blog.scottlowe.org/2013/05/15/using-pf-on-os-x-mountain-lion/
# http://krypted.com/mac-security/a-cheat-sheet-for-using-pf-in-os-x-lion-and-up/

# Options

set block-policy drop
set fingerprints "/etc/pf.os"
set ruleset-optimization basic

set skip on lo0

# Normalization

# Scrub incoming packets
scrub in all no-df

#
# com.apple anchor point
#
scrub-anchor "com.apple/*"

# Queueing

# Translation

# OpenVPN Server NAT
#
# The Book of PF, p. 21
int_if = "en0" # macro for internal interface
localnet = "10.0.0.0/8"
nat on $int_if from $localnet to any -> ($int_if)

nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

# Filtering

lan_server = 10.0.1.3

# Antispoof
antispoof log quick for { lo0 en0 }

# Block by default
block in log

# Allow outgoing traffic from NAT'd { lo0, $localnet }
# The Book of PF, p. 21
pass from { lo0, $localnet } to any keep state

# Block to/from illegal destinations or sources
block in log quick from no-route to any

# Allow critical system traffic
pass in quick inet proto udp from any port 67 to any port 68

# Allow ICMP from home LAN
pass in log proto icmp from $lan_server:network

# Allow outgoing traffic
pass out inet proto tcp from any to any keep state
pass out inet proto udp from any to any keep state

# Internet services
internet_udp_services = "{ https, 500, 1194, 1701, 4500, 5060, 5190, 5297, 5298, 5678, 16384 }"
internet_tcp_services = "{ ssh, smtp, https, 143, 587, 993, 995, 1640, 2170, 2195, 2196, 4190,\
5218, 5223, 5190, 5220, 5222, 5298, 8008, 8443, 8800, 8843 }"
pass in quick inet proto tcp from any to { lo0, $lan_server } port $internet_tcp_services
pass in quick inet proto udp from any to { lo0, $lan_server } port $internet_udp_services

# LAN services: block access, except from localnet
lan_udp_services = "{ 5001 }"
lan_tcp_services = "{ domain, auth, nntp, www, 311, 3128, 5001, 5900:5909, 8118, 8123 }"
pass in quick inet proto tcp from { lo0, $localnet } to { lo0, $lan_server } port $lan_tcp_services
pass in quick inet proto udp from { lo0, $localnet } to { lo0, $lan_server } port $lan_udp_services

Re: Configuring VPN Server on OS X 10.8.2 as Router with NAT

Posted: Sat Sep 26, 2015 5:17 pm
by stvs
There's a github for this with updated pf.conf rules here: https://github.com/essandess/osx-openvpn-server