How to open a server port outside of an OpenVPN tunnel with a pf firewall on OSX (BSD)

Posted by Timbo on Super User See other posts from Super User or by Timbo
Published on 2012-10-22T22:34:01Z Indexed on 2012/10/22 23:05 UTC
Read the original article Hit count: 177

Filed under:
|
|
|
|

I have a Mac mini that I use as a media server running XBMC and serves media from my NAS to my stereo and TV (which has been color calibrated with a Spyder3Express, happy). The Mac runs OSX 10.8.2 and the internet connection is tunneled for general privacy over OpenVPN through Tunnelblick. I believe my anonymous VPN provider pushes "redirect_gateway" to OpenVPN/Tunnelblick because when on it effectively tunnels all non-LAN traffic in- and outbound. As an unwanted side effect that also opens the boxes server ports unprotected to the outside world and bypasses my firewall-router (Netgear SRX5308). I have run nmap from outside the LAN on the VPN IP and the server ports on the mini are clearly visible and connectable.

The mini has the following ports open: ssh/22, ARD/5900 and 8080+9090 for the XBMC iOS client Constellation.

I also have Synology NAS which apart from LAN file serving over AFP and WebDAV only serves up an OpenVPN/1194 and a PPTP/1732 server. When outside of the LAN I connect to this from my laptop over OpenVPN and over PPTP from my iPhone. I only want to connect through AFP/548 from the mini to the NAS.

The border firewall (SRX5308) just works excellently, stable and with a very high throughput when streaming from various VOD services. My connection is a 100/10 with a close to theoretical max throughput. The ruleset is as follows

Inbound:
PPTP/1723        Allow always to 10.0.0.40 (NAS/VPN server)
                 from a restricted IP range >corresponding to possible cell provider range
OpenVPN/1194     Allow always to 10.0.0.40 (NAS/VPN server) from any

Outbound: Default outbound policy: Allow Always
OpenVPN/1194     TCP Allow always from 10.0.0.40 (NAS) to a.b.8.1-a.b.8.254 (VPN provider)
OpenVPN/1194 UDP Allow always to 10.0.0.40 (NAS) to a.b.8.1-a.b.8.254 (VPN provider)
Block always from NAS to any

On the Mini I have disabled the OSX Application Level Firewall because it throws popups which don't remember my choices from one time to another and that's annoying on a media server. Instead I run Little Snitch which controls outgoing connections nicely on an application level. I have configured the excellent OSX builtin firewall pf (from BSD) as follows

pf.conf (Apple App firewall tie-ins removed) (# replaced with % to avoid formatting errors)

### macro name for external interface.
eth_if = "en0"
vpn_if = "tap0"
    ### wifi_if = "en1"
### %usb_if = "en3"

ext_if = $eth_if

LAN="{10.0.0.0/24}"

### General housekeeping rules ###
### Drop all blocked packets silently
set block-policy drop

### all incoming traffic on external interface is normalized and fragmented
### packets are reassembled.
scrub in on $ext_if all fragment reassemble
scrub in on $vpn_if all fragment reassemble

scrub out all

### exercise antispoofing on the external interface, but add the local
### loopback interface as an exception, to prevent services utilizing the
### local loop from being blocked accidentally.
### set skip on lo0
antispoof for $ext_if inet
antispoof for $vpn_if inet

### spoofing protection for all interfaces
block in quick from urpf-failed

#############################

block all

### Access to the mini server over ssh/22 and remote desktop/5900 from LAN/en0 only
pass in on $eth_if proto tcp from $LAN to any port {22, 5900, 8080, 9090} 

### Allow all udp and icmp also, necessary for Constellation. Could be tightened.
pass on $eth_if proto {udp, icmp} from $LAN to any

### Allow AFP to 10.0.0.40 (NAS)
pass out on $eth_if proto tcp from any to 10.0.0.40 port 548

### Allow OpenVPN tunnel setup over unprotected link (en0) only to VPN provider IPs
### and port ranges
pass on $eth_if proto tcp from any to a.b.8.0/24 port 1194:1201 

### OpenVPN Tunnel rules. All traffic allowed out, only in to ports 4100-4110
### Outgoing pings ok
pass in on $vpn_if proto {tcp, udp} from any to any port 4100:4110
pass out on $vpn_if proto {tcp, udp, icmp} from any to any 

So what are my goals and what does the above setup achieve? (until you tell me otherwise :)

1) Full LAN access to the above ports on the mini/media server (including through my own VPN server) 2) All internet traffic from the mini/media server is anonymized and tunneled over VPN 3) If OpenVPN/Tunnelblick on the mini drops the connection, nothing is leaked both because of pf and the router outgoing ruleset. It can't even do a DNS lookup through the router.

So what do I have to hide with all this? Nothing much really, I just got carried away trying to stop port scans through the VPN tunnel :)

In any case this setup works perfectly and it is very stable.

The Problem at last!

I want to run a minecraft server and I installed that on a separate user account on the mini server (user=mc) to keep things partitioned. I don't want this server accessible through the anonymized VPN tunnel because there are lots more port scans and hacking attempts through that than over my regular IP and I don't trust java in general. So I added the following pf rule on the mini:

### Allow Minecraft public through user mc
pass in on $eth_if proto {tcp,udp} from any to any port 24983 user mc
pass out on $eth_if proto {tcp, udp} from any to any user mc

And these additions on the border firewall:
Inbound: Allow always TCP/UDP from any to 10.0.0.40 (NAS)
Outbound: Allow always TCP port 80 from 10.0.0.40 to any (needed for online account checkups)

This works fine but only when the OpenVPN/Tunnelblick tunnel is down. When up no connection is possbile to the minecraft server from outside of LAN. inside LAN is always OK. Everything else functions as intended. I believe the redirect_gateway push is close to the root of the problem, but I want to keep that specific VPN provider because of the fantastic throughput, price and service.

The Solution?

How can I open up the minecraft server port outside of the tunnel so it's only available over en0 not the VPN tunnel?

Should I a static route? But I don't know which IPs will be connecting...stumbles

How secure would to estimate this setup to be and do you have other improvements to share?

I've searched extensively in the last few days to no avail...If you've read this far I bet you know the answer :)

© Super User or respective owner

Related posts about osx

Related posts about security