What's new

Run OpenVPN Client and server at same time?

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Thank you very much for offering. I'll give it a try in the next few days with the caveat that this is our only router in the house so breaking it would be a problem.

I had found a few guides online and none of them suggested using ip route. Is it because openwrt is more barebones? Just wondering
 
I had found a few guides online and none of them suggested using ip route. Is it because openwrt is more barebones? Just wondering

I'm guessing the other guides just push all traffic trough the tunnel, and only want to block transmission from communicating with internet if VPN tunnel is down.
 
Really! o_O
What about us others? Are we not worthy your trick(s)? :'(
:)
Please Mr Gerrits!

Because you are asking so nicely ;)

The only issue I have, is that some of the code might be conflicting with the bypassvpnip from your add-on. (because that one also does similar things with ip route and ip rule)

So ppl who have your addon installed, must disable execution of addon_bypassvpnip.sh via
Code:
chmod -x /usr/bin/addon_bypassvpnip.sh

then create (or edit if it exists) /opt/scripts/firewall-start.sh and place this code in there:
Code:
#!/bin/sh

   iptables -t mangle -N MARKFORCEVPN
   iptables -t mangle -A MARKFORCEVPN -j MARK --set-mark 0x32
   iptables -t mangle -A MARKFORCEVPN -j CONNMARK --save-mark
##if you want some logging in dmesg, uncomment next line
   #iptables -t mangle -A MARKFORCEVPN -j LOG --log-prefix "[MARKFORCEVPN] "

   iptables -t mangle -N MARKNOVPN
   iptables -t mangle -A MARKNOVPN -j MARK --set-mark 0x64
   iptables -t mangle -A MARKNOVPN -j CONNMARK --save-mark
##if you want some logging in dmesg, uncomment next line
   #iptables -t mangle -A MARKNOVPN -j LOG --log-prefix "[MARKNOVPN] "
 
    # get the mark on the packet that belongs to an existing connection (outbound from lan)
    iptables -t mangle -A PREROUTING -i br0 -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
    # get the mark on the packet that belongs to an existing connection (outbound from router)
    iptables -t mangle -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark

######## ONLY MAKE CHANGES BENEATH HERE ###########################

#below this line, add rules for traffic that you want to push to a different route.
#Should mainly be used to make exceptions on process level (uid-owner or gid-owner; only for processes on the router itself) or port / ipaddress level (also for traffic from or to other devices)
#i.e. if you have an ip rule that routes all traffic from a host via the VPN tunnel, then you can override this for a specific port, or destination IP the traffic must go directly

##if you have a configured a process on the router to run with gid vpnroute, then you can route its traffic to go via VPN by:
  # iptables -t mangle -A OUTPUT -m owner --gid-owner vpnroute -m state --state NEW -j MARKFORCEVPN

##if you have port-forwarding enabled (for example 80 & 443) and use a static public IP address with static DNS name, you can route  traffic of those ports to always go directly via wan interface via:
#iptables -t mangle -A PREROUTING -d <public-ip> -p tcp -m multiport --dports 80,443 -m state --state NEW -j MARKNOVPN

##or for allowing access to the OpenVPN server:
#iptables -t mangle -A PREROUTING -d <public-ip> -p tcp -m multiport --dports 12973,12974 -m state --state NEW -j MARKNOVPN
##or
#iptables -t mangle -A PREROUTING -d <public-ip> -p udp -m multiport --dports 12973,12974 -m state --state NEW -j MARKNOVPN

##if you'd want to force usenet traffic of a specific internal client to go via VPN then you could use:
#iptables -t mangle -A PREROUTING -s <ip.of.internal.client> -p tcp --dport 119 -m state --state NEW -j MARKFORCEVPN
#iptables -t mangle -A PREROUTING -s <ip.of.internal.client> -p tcp --dport 565 -m state --state NEW -j MARKFORCEVPN



## below this line put commands to prevent some traffic from falling back to regular internet connection

##if you have a configured a process on the router to run with gid vpnroute then this would prevent the process from communicating if the VPN is down. (tun21 for OpenVPN; replace with wg0 for WireGuard
 #iptables -I OUTPUT 1 -m owner --gid-owner vpnroute ! -o tun21 -m state --state NEW -j REJECT

## and this would block usenet traffic from internal client if VPN is down:
  #iptables -t filter -I FORWARD 1 ! -o tun21 -m state --state NEW -j REJECT

do a net-wall restart and confirm that you have no errors
check iptables -L -n -v and iptables -t mangle -L -n -v to see that these above lines are added to the rules.

then create a new script (for example /opt/scripts/change-routing.sh), make it executable and enter this code:
Code:
#!/bin/sh
   TID="213"
   NOVPN_TABLE="novpn"
   [ "$(grep -c "novpn$" /etc/iproute2/rt_tables)" -eq "0" ] && [ "$(grep -c "^$TID" /etc/iproute2/rt_tables)" -eq "0" ] && echo "$TID $NOVPN_TABLE" >> /etc/iproute2/rt_tables

   # cleanup if script ran before
   while [ "$(ip rule list | grep -cF "lookup $NOVPN_TABLE" )" != "0" ]; do ip rule del table $NOVPN_TABLE 2>/dev/null; done
   while [ "$(ip rule list | grep -vF "from all lookup main" | grep -cF "lookup main")" != "0" ]; do ip rule del lookup main 2>/dev/null; done
   [ "$(ip rule list | grep -cF "from all lookup main")" = "0" ] && ip rule add table main priority 32766

   ip route flush table $NOVPN_TABLE
   ip route flush cache
   sleep 1

   # copy all non-VPN routes from table main to table novpn

     if [ -e /etc/init.d/openvpn-client ]; then
        tun="$(grep "^tun=" /etc/init.d/openvpn-client|head -n1|awk -F'"|=' '{print $NF}')"
        [ -z "$tun" ] && tun="$(grep "grep -q tun" /etc/init.d/openvpn-client|head -n1|awk '{print $NF}')"
        [ -z "$tun" ] && tun="tun21"
     fi

     ip route show table main | grep -vE "$tun|wg0" | while read -r route; do
        # shellcheck disable=SC2086
        ip route add $route table $NOVPN_TABLE
     done

    if ifconfig | grep -qF 'wg0'; then
      # WAN_IF="brwan" only if PPP not used (All other: PPTP, L2TP, PPPoE(gives ppp0 instead) )
      WAN_IF="$(ip route | awk '/^default/{print $NF}')"
      # Take care of the case when no default route exist, as with Wireguard Client
      [ -z "$WAN_IF" ] && ifconfig ppp0 >/dev/null 2>&1 && WAN_IF='ppp0' || WAN_IF=$(nvram get wan_ifname)
      # Get wan gateway ip address:
      WAN_GWAY="$(ip route | awk '/^default/{print $3}')"
      # Take care of the case when no default route exist, as with Wireguard Client
      if [ -z "$WAN_GWAY" ]; then WAN_GWAY="$(ip route | awk '/via/ && /dev "$WAN_IF"/ && !/default/{print $3}')";fi
       ip route add default via "$WAN_GWAY" dev "$WAN_IF" table "$NOVPN_TABLE"
     fi

######## ONLY MAKE CHANGES BENEATH HERE ###########################


     # if you want to bypass vpn for clients that connect via OpenVPN server (tun0), uncomment next line
     # or again comment it if you want this to go via VPN
     #[ "$(ip rule list | grep -c "iif tun0 lookup $NOVPN_TABLE")" = "0" ] && ip rule add iif tun0 table $NOVPN_TABLE

     # if you want to bypass vpn for the router itself, uncomment next line
     # or again comment it if you want this to go via VPN
     # this allows DDNS to register the real wan ip-address and allows port-forwarding to work.
     [ "$(ip rule list | grep -c "iif lo lookup $NOVPN_TABLE")" = "0" ] && ip rule add iif lo table $NOVPN_TABLE

     # if you want to bypass vpn for all clients on the lan, uncomment next line
     # or again comment it if you want this to go via VPN
     [ "$(ip rule list | grep -c "iif br0 lookup $NOVPN_TABLE")" = "0" ] && ip rule add iif br0 table $NOVPN_TABLE

     # if you want a specific IP address to always go via VPN then use the following: (replace <IPaddress> with real IP in both places)
     #[ "$(ip rule list | grep -c "<IPaddress> lookup main")" = "0" ] && ip rule add from <IPaddress> table main

     # if you want a specific IP address to always go directly  then use the following: (replace <IPaddress> with real IP in both places)
     #[ "$(ip rule list | grep -c "<IPaddress> lookup $NOVPN_TABLE")" = "0" ] && ip rule add from <IPaddress> table $NOVPN_TABLE

    ## the later the rule is inserted, the higher the priority. So first force a big group to go in one direction and then later overrule with more specific rules.


######## ONLY MAKE CHANGES ABOVE HERE ###########################

     #allow for exceptions on port level for traffic that is marked with 0x64 (novpn) or 0x32 (forcevpn), via /opt/scripts/firewall-start.sh
     #this exception rule must always be added last, so it has the higest priority (= lowest priority number)
     [ "$(ip rule list | grep -c "fwmark 0x64 lookup $NOVPN_TABLE")" = "0" ] && ip rule add fwmark 0x64 table $NOVPN_TABLE priority 0
     #and this rule allows to force traffic marked with 0x32 through the tunnel
     [ "$(ip rule list | grep -c "fwmark 0x32 lookup main")" = "0" ] && ip rule add fwmark 0x32 table main priority 0

execute the script and test if everything works as expected.
check with ip rule list and ip route show table novpn

If so, then add a line to the end of /opt/scripts/firewall-start.sh to call this second script.
This way the routing tables will be re-created automatically if something changes.
 
Last edited:
:( I just updated the bypassvpnip to handle wireguard!

Kidding, not sad at all!

This is a fantastic trick you just pulled.:D
One day when I feel good, I'll try it out, and maybe we can find a way for it to co-exist with my add-on!

Thank you very much @R. Gerrits !
You are very skilled, and generous to spread your knowledge! :cool:
Because you are asking so nicely ;)

The only issue I have, is that some of the code might be conflicting with the bypassvpnip from your add-on. (because that one also does similar things with ip route and ip rule)

So ppl who have your addon installed, must disable execution of addon_bypassvpnip.sh via
Code:
chmod -x /usr/bin/addon_bypassvpnip.sh
 
Hello,

many thanks to R. Guerrits and Kamoj. I am very impatient to see how it is possible to make co-exist the port forwarding VPNclient and the add-on VPNbypass of Kamoj.
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top