Jump to content
Not connected, Your IP: 3.16.137.229
ucode

[Tutorial] Split-Tunneling via User

Recommended Posts

Posted ... (edited)

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

Edited ... by ucode
Please move to the right forum....

Share this post


Link to post

Holy shit, that's genius! I didn't know you could create tables based on a username with ip. So any program started as $VPNUSER will use the tunnel. I have a few remarks, though.

You want to use the most recent version of OpenVPN which is available from build.openvpn.net directly, even for archaic distribution versions (Debian 7, Ubuntu 12.04). I'd suggest to add a few steps to add that repo and install the newest version instead of relying on what the distribution's version is.
 

On 6/20/2019 at 4:27 PM, ucode said:

Add this to the config:


nobind
disable-occ
script-security 2
route-noexec
up /etc/openvpn/iptables.sh
down /etc/openvpn/update-resolv-conf

As a result, disable-occ here is a discouraged option in the OpenVPN 2.4 documentation and should be omitted because it's not needed.
 
On 6/20/2019 at 4:27 PM, ucode said:

Change DNS


nano /etc/openvpn/update-resolv-conf

foreign_option_1='dhcp-option DNS 1.1.1.1'
foreign_option_2='dhcp-option DNS 1.0.0.1'
foreign_option_3='dhcp-option DNS 209.222.18.222'

If NetworkManager is used, setting DNS this way won't work continuously when NetworkManager is used. Eventually, it will simply override whatever you set here, when the DHCP lease runs out at the latest. So if you're using Linux with a desktop environment, create a new profile in your network settings, set IPv4 and IPv6 to DHCP (addresses only) and enter the DNS servers there.
I wouldn't recommend your choice of DNS server, either. First and foremost, AirDNS IPv6 should be used, then its IPv4 (both are found in the specs) and then maybe something like 1.1.1.1 as a fallback if you really need it. The third DNS server in there looked like an OpenDNS server to me and I was about to advise against it because it blocks certain more or less harmful things itself, contradicting AirVPN's mission, but something seemed wrong with it. So I dug deeper and found this post suggesting it was a PrivateInternetAccess DNS server, which also means a PIA user was somehow involved in the creation of this guide. :D Omit or adjust to AirVPN's needs.
 
On 6/20/2019 at 4:27 PM, ucode said:

Change ifconfig to ip if your OS dont support ifconfig anymore or install it.


apt install net-tools

This shouldn't be used as well. Unmaintained, very obsolete. I'd stick to ip. Gateway address could be pulled by something like
ip r|grep -E "dev tun0.*src"|cut -d " " -f9
Then, the installation of net-tools can be omitted.
 
On 6/20/2019 at 4:27 PM, ucode said:

Add:


net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.XXXXXX.rp_filter = 2

Shouldn't this also be done for IPv6?

Other than that, completely genius! Think about the changes and a mod might just move it to the How-To forum! Well done! ❤️ 

NOT AN AIRVPN TEAM MEMBER. USE TICKETS FOR PROFESSIONAL SUPPORT.

LZ1's New User Guide to AirVPN « Plenty of stuff for advanced users, too!

Want to contact me directly? All relevant methods are on my About me page.

Share this post


Link to post
43 minutes ago, giganerd said:

Holy shit, that's genius! I didn't know you could create tables based on a username with ip. So any program started as $VPNUSER will use the tunnel. I have a few remarks, though.

You want to use the most recent version of OpenVPN which is available from build.openvpn.net directly, even for archaic distribution versions (Debian 7, Ubuntu 12.04). I'd suggest to add a few steps to add that repo and install the newest version instead of relying on what the distribution's version is.
 


As a result, disable-occ here is a discouraged option in the OpenVPN 2.4 documentation and should be omitted because it's not needed.
 
If NetworkManager is used, setting DNS this way won't work continuously when NetworkManager is used. Eventually, it will simply override whatever you set here, when the DHCP lease runs out at the latest. So if you're using Linux with a desktop environment, create a new profile in your network settings, set IPv4 and IPv6 to DHCP (addresses only) and enter the DNS servers there.
I wouldn't recommend your choice of DNS server, either. First and foremost, AirDNS IPv6 should be used, then its IPv4 (both are found in the specs) and then maybe something like 1.1.1.1 as a fallback if you really need it. The third DNS server in there looked like an OpenDNS server to me and I was about to advise against it because it blocks certain more or less harmful things itself, contradicting AirVPN's mission, but something seemed wrong with it. So I dug deeper and found this post suggesting it was a PrivateInternetAccess DNS server, which also means a PIA user was somehow involved in the creation of this guide. :D Omit or adjust to AirVPN's needs.
 
This shouldn't be used as well. Unmaintained, very obsolete. I'd stick to ip. Gateway address could be pulled by something like

ip r|grep -E "dev tun0.*src"|cut -d " " -f9
Then, the installation of net-tools can be omitted.
 
Shouldn't this also be done for IPv6?

Other than that, completely genius! Think about the changes and a mod might just move it to the How-To forum! Well done! ❤️ 

Thanks you for your exellent improvements. I'll add it these weeks and release it with an autoinstaller script. I personally disable ipv6 but some users might need it.
If you have other nice improvements let me know and we can talk and change it.

Kindly Regards,
ucode

Share this post


Link to post

Maybe also scriptically identifying which tunX interface is used by the openvpn process and using that in the ip commands instead of hardcoding tun0.. it's only an idea. Should be possible.
 

$ sudo lsof /dev/net/tun
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
openvpn 2098 root    4u   CHR 10,200     0t52 16675 /dev/net/tun
 

NOT AN AIRVPN TEAM MEMBER. USE TICKETS FOR PROFESSIONAL SUPPORT.

LZ1's New User Guide to AirVPN « Plenty of stuff for advanced users, too!

Want to contact me directly? All relevant methods are on my About me page.

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Security Check
    Play CAPTCHA Audio
    Refresh Image

×
×
  • Create New...