NOTICE to the Moderator: PLEASE MOVE TO THE RIGHT FORUM
Hello,
I want to make a thread about split tunneling through a spezific user. I figured out how it works and want to share it. I use Debian 8/9 but it should work with other distros too.
Openvpn Split tunnel though user
Debian 8 & 9 based
Install openvpn from apt or install it via source
apt-get update -y && apt-get upgrade -y && apt-get install openvpn htop nload dstat sudo apt-utils iptables curl resolvconf -y
nano /etc/systemd/system/openvpn@openvpn.service
Config:
[Unit]
Description=OpenVPN connection to %i
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO
After=network.target
[Service]
RuntimeDirectory=openvpn
PrivateTmp=true
KillMode=mixed
Type=forking
ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid
PIDFile=/run/openvpn/%i.pid
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/etc/openvpn
Restart=on-failure
RestartSec=3
ProtectSystem=yes
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
[Install]
WantedBy=multi-user.target
Enable Service
systemctl enable openvpn@openvpn.service
Download Airvpn/Openvpn config and paste it in there:
nano /etc/openvpn/openvpn.conf
Add this to the config:
nobind
script-security 2
route-noexec
up /etc/openvpn/iptables.sh
down /etc/openvpn/update-resolv-conf
Change DNS
nano /etc/openvpn/update-resolv-conf
foreign_option_1='dhcp-option DNS AIRVPN DNS1'
foreign_option_2='dhcp-option DNS AIRVPN DNS2'
foreign_option_3='dhcp-option DNS 1.1.1.1'
Add user and group
adduser --disabled-login vpn
usermod -aG vpn XXX
usermod -aG XXX vpn
Iptables Flush & Rules
iptables -F
iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
apt-get install iptables-persistent -y
nano /etc/openvpn/iptables.sh
Change INTERFACE, VPNUSER, LOCALIP and NETIF Script:
#! /bin/bash
export INTERFACE="tun0"
export VPNUSER="vpn"
export LOCALIP="192.168.1.130"
export NETIF="eth0"
# 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 --dest $LOCALIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT --dest $LOCALIP -p tcp --dport 53 -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 -j CONNMARK --save-mark
# allow responses
iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT
# block everything incoming on $INTERFACE to prevent accidental exposing of ports
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
# Start routing script
/etc/openvpn/routing.sh
exit 0
chmod +x /etc/openvpn/iptables.sh
nano /etc/openvpn/routing.sh
Change ifconfig to ip if your OS dont support ifconfig anymore or install it.
apt install net-tools
Change VPNIG and VPNUSER if needed Script:
#! /bin/bash
VPNIF="tun0"
VPNUSER="vpn"
GATEWAYIP=`ifconfig $VPNIF | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' | egrep -v '255|(127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})' | tail -n1`
if [[ `ip rule list | grep -c 0x1` == 0 ]]; then
ip rule add from all fwmark 0x1 lookup $VPNUSER
fi
ip route replace default via $GATEWAYIP table $VPNUSER
ip route append default via 127.0.0.1 dev lo table $VPNUSER
ip route flush cache
# run update-resolv-conf script to set VPN DNS
/etc/openvpn/update-resolv-conf
exit 0
chmod +x /etc/openvpn/routing.sh
nano /etc/iproute2/rt_tables
Add
200 vpn
Edit vpn filter
nano /etc/sysctl.d/9999-vpn.conf
Add:
Replace XXXXXX with your eth/wireless interface
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.XXXXXX.rp_filter = 2
net.ipv6.conf.all.rp_filter = 2
net.ipv6.conf.default.rp_filter = 2
net.ipv6.conf.XXXXXX.rp_filter = 2
Apply Rules and show status
sysctl --system
service openvpn status
Test it
IP:
sudo -u vpn -i -- curl ipinfo.io
DNS:
sudo -u vpn -i -- cat /etc/resolv.conf
Enjoy