Q: OpenVPN Split Routing for individual user CentOS 7 I am currently trying to configure OpenVPN on CentOS 7 to route all traffic from a specific user (vpn) through the VPN, leaving all other traffic unaffected. I have followed a tutorial based on ubuntu, making the required changes for CentOS 7 however on launching openVPN the server seems to lose all access to the internet across all users. Access is restored upon terminating OpenVPN
OpenVPN worked fine prior to my split routing attempt.
All configuration files are listed at the end of this post

When launched, openVPN displays the following
Shell Output
Main issue seems to be the missing IP address argument from what I can tell. Please let me know if you can spot where I have gone wrong. Still relatively new to Linux and not amazing when it comes to networking so details are greatly appreciated. Happy to provide any additional details or config files that may be required in debugging
server.conf
client
dev tun
proto udp
remote nl.privateinternetaccess.com 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass /etc/openvpn/cred.conf
auth-nocache
comp-lzo
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
script-security 2

up /etc/openvpn/iptables.sh
down /etc/openvpn/update-resolv-conf


iptables.sh
#! /bin/bash
# Niftiest Software – www.niftiestsoftware.com
# Modified version by HTPC Guides – www.htpcguides.com

export INTERFACE="tun0"
export VPNUSER="vpn"
export LOCALIP="192.168.1.103"
export NETIF="enp2s0"

# flushes all the iptables rules, if you have other rules to use then add them into the script
/sbin/iptables -F -t nat
/sbin/iptables -F -t mangle
/sbin/iptables -F -t filter

# mark packets from $VPNUSER
/sbin/iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
/sbin/iptables -t mangle -A OUTPUT ! --dest $LOCALIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
/sbin/iptables -t mangle -A OUTPUT --dest $LOCALIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
/sbin/iptables -t mangle -A OUTPUT --dest $LOCALIP -p tcp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
/sbin/iptables -t mangle -A OUTPUT ! --src $LOCALIP -j MARK --set-mark 0x1
/sbin/iptables -t mangle -A OUTPUT -j CONNMARK --save-mark

# allow responses
/sbin/iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT

# block everything incoming on $INTERFACE to prevent accidental exposing of ports
/sbin/iptables -A INPUT -i $INTERFACE -j REJECT

# let $VPNUSER access lo and $INTERFACE
/sbin/iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
/sbin/iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT

# all packets on $INTERFACE needs to be masqueraded
/sbin/iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE

# reject connections from predator IP going over $NETIF
/sbin/iptables -A OUTPUT ! --src $LOCALIP -o $NETIF -j REJECT

# Start routing script
/etc/openvpn/routing.sh

exit 0

routing.sh
#! /bin/bash
# Niftiest Software – www.niftiestsoftware.com
# Modified version by HTPC Guides – www.htpcguides.com

VPNIF="tun0"
VPNUSER="vpn"
GATEWAYIP=$(/sbin/ifcfg $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 [[ `/sbin/ip rule list | grep -c 0x1` == 0 ]]; then
/sbin/ip rule add from all fwmark 0x1 lookup $VPNUSER
fi
/sbin/ip route replace default via $GATEWAYIP table $VPNUSER
/sbin/ip route append default via 127.0.0.1 dev lo table $VPNUSER
/sbin/ip route flush cache

# run update-resolv-conf script to set VPN DNS
/etc/openvpn/update-resolv-conf

exit 0

update-resolv-conf
#!/usr/bin/env bash
#
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood <jdthood@yahoo.co.uk>
# and Chris Hanson
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL.
# 07/2013 colin@daedrum.net Fixed intet name
# 05/2006 chlauber@bnc.ch
#
# Example envs set from openvpn:
foreign_option_1='dhcp-option DNS 209.222.18.222'
foreign_option_2='dhcp-option DNS 209.222.18.218'
foreign_option_3='dhcp-option DNS 8.8.8.8'
# foreign_option_4='dhcp-option DOMAIN-SEARCH bnc.local'

## The 'type' builtins will look for file in $PATH variable, so we set the
## PATH below. You might need to directly set the path to 'resolvconf'
## manually if it still doesn't work, i.e.
## RESOLVCONF=/usr/sbin/resolvconf
export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin
RESOLVCONF=$(type -p resolvconf)

case $script_type in

up)
  for optionname in ${!foreign_option_*} ; do
    option="${!optionname}"
    echo $option
    part1=$(echo "$option" | cut -d " " -f 1)
    if [ "$part1" == "dhcp-option" ] ; then
      part2=$(echo "$option" | cut -d " " -f 2)
      part3=$(echo "$option" | cut -d " " -f 3)
      if [ "$part2" == "DNS" ] ; then
        IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
      fi
      if [[ "$part2" == "DOMAIN" || "$part2" == "DOMAIN-SEARCH" ]] ; then
        IF_DNS_SEARCH="$IF_DNS_SEARCH $part3"
      fi
    fi
  done
  R=""
  if [ "$IF_DNS_SEARCH" ]; then
    R="search "
    for DS in $IF_DNS_SEARCH ; do
      R="${R} $DS"
    done
  R="${R}
"
  fi

  for NS in $IF_DNS_NAMESERVERS ; do
    R="${R}nameserver $NS
"
  done
  #echo -n "$R" | $RESOLVCONF -x -p -a "${dev}"
  echo -n "$R" | $RESOLVCONF -x -a "${dev}.inet"
  ;;
down)
  $RESOLVCONF -d "${dev}.inet"
  ;;
esac

# Workaround / jm@epiclabs.io 
# force exit with no errors. Due to an apparent conflict with the Network Manager
# $RESOLVCONF sometimes exits with error code 6 even though it has performed the
# action correctly and OpenVPN shuts down.
exit 0
Contact GitHub API Training Shop Blog About
© 2017 GitHub, Inc. Terms Privacy Security Status Help


A: The update-resolv-conf that you're using with the scripts is tailored for Debian. macieks openresolv. This is the link to a Fedora/Centos version. I still haven't figure out how to get the DNS to stick, but the routes definitley split, as I have internet connectivity for my uid, but not the vpn uid. Sorry I can't be of more help, but when i find the rest of the answer, I'll be sure to pass it along.
