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 a Synology NAS which apart from LAN file serving over AFP and WebDAV only serves up an OpenVPN/1194 and a PPTP/1732 server to WAN. 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

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)

### macro names 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 (rtorrent)
### 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 would like 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 then 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.30 (mini with mc server)
Outbound: Allow always TCP port 80 from 10.0.0.30 to any (needed for online account checkups)

This works fine but only when the OpenVPN/Tunnelblick tunnel is down. When up no connection is possible to the minecraft server from outside of LAN, access inside LAN is always OK. Everything else functions as intended. I believe the redirect_gateway push could be 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 usa a static route? But I don't know which WAN IPs will be connecting...stumbles

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