Hi There,
I am set up an Ubuntu 16.0.4 VM for the sole purpose of being an OpenVPN/Transmission server within my LAN and I followed the HTPC guide for a split-tunnel solution based upon limiting VPN traffic to just the OpenVpn user. It has worked quite well except for the problem that it did not support inbound connections on a high-order port making my torrent performance quite poor. I addressed this by opening a forwarded port with my VPN provider which happily opened a fixed port for me which makes things a lot easier than having a dynamic or random port. However, I am finding that in my attempts to only allow inbound traffic on that port I am allowing traffic to every port on this VM's LAN IP by way of the other end of the VPN tunnel. While torrents work great, this is quite the security risk. I have tried a number of iptables configurations but even when I am able to keep the remote port open, trying to limit traffic to that port on the VPN interface prevents Transmission from taking inbound connections. I suspect this is because of a misunderstanding on my part of using iptables and a VPN tunnel which is a bit new to me.
Here is my present config which allows connections to the VPN IP to all connections on my VM. Again, my goal is just to allow inbound connections on this single port unless established. Can someone advise me on what I am doing wrong? It's probably something obvious. Thanks in advance!
#! /bin/bash
# Niftiest Software – http://www.niftiestsoftware.com
# Based on the the split tunnel config from HTPC Guides – http://www.htpcguides.com
# v1.1.15
export INTERFACE="tun0"
export VPNUSER="vpn"
export VPNPORT="1912"
export LOCALIP="192.168.250.15"
export NETIF="ens3"
export FWPORT="13456"
# flushes all the iptables rules, if you have other rules to use then add them into the script
iptables -F -t nat
iptables -F -t mangle
iptables -F -t filter
# mark packets from $VPNUSER
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
RTNETLINK answers: File exists
root@dargo:/etc/openvpn# vi iptables.sh
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
# flushes all the iptables rules, if you have other rules to use then add them into the script
iptables -F -t nat
iptables -F -t mangle
iptables -F -t filter
# mark packets from $VPNUSER
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT -j CONNMARK --save-mark
# allow responses
# I ATTEMPTED THESE BUT ADDING --dport IS BAD SYNTAX FOR IPTABLES
#iptables -A INPUT -i $INTERFACE -p tcp --dport $FWPORT -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
#iptables -A INPUT -i $INTERFACE -p udp --dport $FWPORT -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
# accept all traffic on the forwarded port on the tunnel
iptables -A INPUT -p tcp --dport $FWPORT -i $INTERFACE -j ACCEPT
# UDP NOT NEEDED, ALSO SEEMED TO BREAK INCOMING TRAFFIC TO TRANSMISSION ON FWPORT
#iptables -A INPUT -p udp --dport $FWPORT -i $INTERFACE -j ACCEPT
# only allow incoming traffic on established connections
#iptables -A INPUT -i $INTERFACE -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT
# block everything else incoming on $INTERFACE to prevent accidental exposing of ports
# OR SO I THOUGHT...
iptables -A INPUT -i $INTERFACE -j REJECT
# let $VPNUSER access lo and $INTERFACE
iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT
# all packets on $INTERFACE needs to be masqueraded
iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE
# reject connections from predator IP going over $NETIF
iptables -A OUTPUT ! --src $LOCALIP -o $NETIF -j REJECT
# port forwarding
# APPARENTLY SINCE THE TRAFFIC IS LOCAL TO VM, FORWARDING IS NOT NEEDED
#iptables -I FORWARD -i $INTERFACE -p udp -d $LOCALIP --dport $FWPORT -j ACCEPT
#iptables -I FORWARD -i $INTERFACE -p tcp -d $LOCALIP --dport $FWPORT -j ACCEPT
# THIS WAS THE MAGIC THAT MADE IT ALL WORK, BUT IT APPEARS TO OPEN ALL PORTS!
iptables -t nat -I PREROUTING -i $INTERFACE -p tcp --dport $FWPORT -j DNAT --to-destination $LOCALIP
iptables -t nat -I PREROUTING -i $INTERFACE -p udp --dport $FWPORT -j DNAT --to-destination $LOCALIP
# Start standard HTPC provided routing script tailored to my system
/etc/openvpn/routing.sh
exit 0
I am set up an Ubuntu 16.0.4 VM for the sole purpose of being an OpenVPN/Transmission server within my LAN and I followed the HTPC guide for a split-tunnel solution based upon limiting VPN traffic to just the OpenVpn user. It has worked quite well except for the problem that it did not support inbound connections on a high-order port making my torrent performance quite poor. I addressed this by opening a forwarded port with my VPN provider which happily opened a fixed port for me which makes things a lot easier than having a dynamic or random port. However, I am finding that in my attempts to only allow inbound traffic on that port I am allowing traffic to every port on this VM's LAN IP by way of the other end of the VPN tunnel. While torrents work great, this is quite the security risk. I have tried a number of iptables configurations but even when I am able to keep the remote port open, trying to limit traffic to that port on the VPN interface prevents Transmission from taking inbound connections. I suspect this is because of a misunderstanding on my part of using iptables and a VPN tunnel which is a bit new to me.
Here is my present config which allows connections to the VPN IP to all connections on my VM. Again, my goal is just to allow inbound connections on this single port unless established. Can someone advise me on what I am doing wrong? It's probably something obvious. Thanks in advance!
#! /bin/bash
# Niftiest Software – http://www.niftiestsoftware.com
# Based on the the split tunnel config from HTPC Guides – http://www.htpcguides.com
# v1.1.15
export INTERFACE="tun0"
export VPNUSER="vpn"
export VPNPORT="1912"
export LOCALIP="192.168.250.15"
export NETIF="ens3"
export FWPORT="13456"
# flushes all the iptables rules, if you have other rules to use then add them into the script
iptables -F -t nat
iptables -F -t mangle
iptables -F -t filter
# mark packets from $VPNUSER
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
RTNETLINK answers: File exists
root@dargo:/etc/openvpn# vi iptables.sh
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
# flushes all the iptables rules, if you have other rules to use then add them into the script
iptables -F -t nat
iptables -F -t mangle
iptables -F -t filter
# mark packets from $VPNUSER
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT -j CONNMARK --save-mark
# allow responses
# I ATTEMPTED THESE BUT ADDING --dport IS BAD SYNTAX FOR IPTABLES
#iptables -A INPUT -i $INTERFACE -p tcp --dport $FWPORT -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
#iptables -A INPUT -i $INTERFACE -p udp --dport $FWPORT -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
# accept all traffic on the forwarded port on the tunnel
iptables -A INPUT -p tcp --dport $FWPORT -i $INTERFACE -j ACCEPT
# UDP NOT NEEDED, ALSO SEEMED TO BREAK INCOMING TRAFFIC TO TRANSMISSION ON FWPORT
#iptables -A INPUT -p udp --dport $FWPORT -i $INTERFACE -j ACCEPT
# only allow incoming traffic on established connections
#iptables -A INPUT -i $INTERFACE -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT
# block everything else incoming on $INTERFACE to prevent accidental exposing of ports
# OR SO I THOUGHT...
iptables -A INPUT -i $INTERFACE -j REJECT
# let $VPNUSER access lo and $INTERFACE
iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT
# all packets on $INTERFACE needs to be masqueraded
iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE
# reject connections from predator IP going over $NETIF
iptables -A OUTPUT ! --src $LOCALIP -o $NETIF -j REJECT
# port forwarding
# APPARENTLY SINCE THE TRAFFIC IS LOCAL TO VM, FORWARDING IS NOT NEEDED
#iptables -I FORWARD -i $INTERFACE -p udp -d $LOCALIP --dport $FWPORT -j ACCEPT
#iptables -I FORWARD -i $INTERFACE -p tcp -d $LOCALIP --dport $FWPORT -j ACCEPT
# THIS WAS THE MAGIC THAT MADE IT ALL WORK, BUT IT APPEARS TO OPEN ALL PORTS!
iptables -t nat -I PREROUTING -i $INTERFACE -p tcp --dport $FWPORT -j DNAT --to-destination $LOCALIP
iptables -t nat -I PREROUTING -i $INTERFACE -p udp --dport $FWPORT -j DNAT --to-destination $LOCALIP
# Start standard HTPC provided routing script tailored to my system
/etc/openvpn/routing.sh
exit 0