Signed-off-by: Stan Grishin <stangri@melmac.net> vpnbypass: fixed renamed option in stop_service Signed-off-by: Stan Grishin <stangri@melmac.net> vpnbypass: fixed typo in makefile, switch FW_MARK to 0x010000 to play nice with SQM/mwan (thanks Hannu) Signed-off-by: Stan Grishin <stangri@melmac.net> vpnbypass: proper masking in setting mark Signed-off-by: Stan Grishin <stangri@melmac.net> vpnbypass: separating luci-app-vpnbypass into different tree Signed-off-by: Stan Grishin <stangri@melmac.net> vpnbypass: fixed incorrect use of procd_add_reload_interface_trigger according to http://wiki.prplfoundation.org/wiki/Procd_reference Signed-off-by: Stan Grishin <stangri@melmac.net>lilik-openwrt-22.03
@ -0,0 +1,53 @@ | |||
# Copyright (c) 2017 Stan Grishin (stangri@melmac.net) | |||
# This is free software, licensed under the GNU General Public License v3. | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=vpnbypass | |||
PKG_VERSION:=1.0.0 | |||
PKG_RELEASE:=4 | |||
PKG_LICENSE:=GPL-3.0+ | |||
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net> | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/$(PKG_NAME) | |||
SECTION:=net | |||
CATEGORY:=Network | |||
DEPENDS:=+ip-full +ipset +iptables +ubox +dnsmasq-full | |||
CONFLICTS:=ip dnsmasq | |||
TITLE:=Simple VPN Bypass Service | |||
PKGARCH:=all | |||
endef | |||
define Package/$(PKG_NAME)/description | |||
This service can be used to enable simple VPN split tunnelling. | |||
Supports accessing domains, IP ranges outside of your VPN tunnel. | |||
Also supports dedicating local ports/IP ranges for direct internet access (outside of your VPN tunnel). | |||
Please see the README for further information. | |||
endef | |||
define Package/$(PKG_NAME)/conffiles | |||
/etc/config/vpnbypass | |||
endef | |||
define Build/Prepare | |||
endef | |||
define Build/Configure | |||
endef | |||
define Build/Compile | |||
endef | |||
define Package/$(PKG_NAME)/install | |||
$(INSTALL_DIR) $(1)/etc/init.d | |||
$(INSTALL_BIN) ./files/vpnbypass.init $(1)/etc/init.d/vpnbypass | |||
$(INSTALL_DIR) $(1)/etc/config | |||
$(INSTALL_CONF) ./files/vpnbypass.conf $(1)/etc/config/vpnbypass | |||
$(INSTALL_DIR) $(1)/etc/hotplug.d/firewall | |||
$(INSTALL_DATA) ./files/vpnbypass.hotplug $(1)/etc/hotplug.d/firewall/90-vpnbypass | |||
endef | |||
$(eval $(call BuildPackage,$(PKG_NAME))) |
@ -0,0 +1,47 @@ | |||
# OpenWrt Simple VPNBypass | |||
A simple PROCD-based vpnbypass init script for OpenWrt/LEDE Project. Useful if your router accesses internet thru VPN client/tunnel, but you want specific traffic (ports, IP ranges, domains or local IP ranges) to be routed outside of this tunnel. | |||
# Features | |||
- Routes Plex Media Server traffic outside of the VPN tunnel. | |||
- Allows you to define IPs/ranges in local network so that their traffic is routed outside of the VPN tunnel. | |||
- Allows you to define list of domain names which are accessed outside of the VPN tunnel (useful for Netflix, Hulu, etc). | |||
- Doesn't stay in memory -- creates the iptables rules which are automatically updated on WAN up/down. | |||
# Requirements | |||
This service requires following packages to be installed on your router: ip-full ipset iptables dnsmasq-full (dnsmasq-full requires you uninstall dnsmasq first). Run the following commands to satisfy the requirements: | |||
```sh | |||
opkg update | |||
opkg remove dnsmasq ip; opkg install ip-full ipset iptables dnsmasq-full | |||
``` | |||
# How to install | |||
```sh | |||
opkg update | |||
opkg install vpnbypass luci-app-vpnbypass | |||
``` | |||
Default install routes Plex Media Server traffic (port 32400) outside of the VPN tunnel, routes LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel and also routes internet traffic from local IPs 192.168.1.80-192.168.1.88 outside of the VPN tunnel. | |||
# Documentation / Discussion | |||
Please head to OpenWrt/LEDE Project Forums for discussion of this script. | |||
# What's New | |||
1.0.0: | |||
- Hotplug script created during install. | |||
0.1.0: | |||
- Package built. | |||
- Support for user-defined ports implemented. | |||
- Support for user-defined routes implemented. | |||
- Support for user-defined local ranges implemented. | |||
0.0.1: | |||
- Initial release. | |||
# Known Issues | |||
Until user-defined domains are supported within vpnbypass config, you can set domains to be accessed outside of VPN tunnel like so: | |||
```sh | |||
uci add_list dhcp.@dnsmasq[-1].ipset='/github.com/plex.tv/google.com/vpnbypass' | |||
uci add_list dhcp.@dnsmasq[-1].ipset='/hulu.com/netflix.com/nhl.com/vpnbypass' | |||
uci commit dhcp | |||
/etc/init.d/dnsmasq restart | |||
``` |
@ -0,0 +1,5 @@ | |||
config vpnbypass 'config' | |||
option enabled '1' | |||
list localport '32400' | |||
list remotesubnet '25.0.0.0/8' | |||
list localsubnet '192.168.1.80/28' |
@ -0,0 +1,2 @@ | |||
#!/bin/sh | |||
[ "$ACTION" = "reload" ] && /etc/init.d/vpnbypass reload |
@ -0,0 +1,76 @@ | |||
#!/bin/sh /etc/rc.common | |||
START=90 | |||
USE_PROCD=1 | |||
TID="200"; FW_MARK="0x010000"; IPSET="vpnbypass"; | |||
output() { | |||
[ -z "$verbosity" ] && config_get verbosity 'config' 'verbosity' '2' | |||
[ -n "$2" -a $((verbosity)) -ne $(($2)) ] && return 0; | |||
[ -t 1 ] && echo -e -n "$1" | |||
[ $(echo -e -n "$1" | wc -l) -gt 0 ] && logger -t "vpnbypass[$$]" "$(echo -e -n ${logmsg}${1})" && logmsg='' || logmsg=${logmsg}${1} | |||
} | |||
vpnbypass_enabled() { | |||
config_get_bool enabled 'config' 'enabled' 0 | |||
[ $((enabled)) -gt 0 ] && return 0 || { output "VPNBypass is not enabled in the config file!\nTo enable, run 'uci set vpnbypass.config.enabled=1; uci commit vpnbypass'\n"; return 1; } | |||
} | |||
boot() { ubus -t 30 wait_for network.interface && rc_procd start_service || output 'ERROR: Failed to settle network interface!\n'; } | |||
start_service() { | |||
local ll | |||
config_load vpnbypass | |||
vpnbypass_enabled || return 1 | |||
[ -d /etc/openvpn ] || return 1 | |||
config_get lports 'config' 'localport' | |||
config_get rports 'config' 'remoteport' | |||
config_get routes 'config' 'remotesubnet' | |||
config_get ranges 'config' 'localsubnet' | |||
config_get domains 'config' 'domain' | |||
procd_open_instance | |||
procd_set_param stdout 1 | |||
procd_set_param stderr 1 | |||
procd_close_instance | |||
. /lib/functions/network.sh; network_get_ipaddr wanip wan; network_get_gateway gwip wan; network_get_ipaddr lanip lan | |||
[ ! "$wanip" ] && output 'ERROR: Could not get wan ip\n' && exit 0 | |||
[ ! "$gwip" ] && output 'ERROR: Could not get wan gateway\n' && exit 0 | |||
for ll in ${routes}; do (ip route del $ll; ip route add $ll via $gwip) >/dev/null 2>&1; done | |||
(ip rule del fwmark $FW_MARK table $TID; iptables -t mangle -F; ipset -F $IPSET; ipset -X $IPSET) >/dev/null 2>&1 | |||
(ip route flush table $TID; ip route flush cache) >/dev/null 2>&1 | |||
(ip route add default via $gwip table $TID; ip route flush cache) >/dev/null 2>&1 | |||
(modprobe xt_set || modprobe ip_set; insmod ip_set_hash_ip) >/dev/null 2>&1 | |||
(ipset -N $IPSET iphash -q; ipset -F $IPSET) >/dev/null 2>&1 | |||
for ll in ${lports}; do iptables -t mangle -A PREROUTING -p tcp -m multiport --sport $ll -j MARK --set-mark $FW_MARK/$FW_MARK -m comment --comment "vpnbypass"; done | |||
for ll in ${rports}; do iptables -t mangle -A PREROUTING -p tcp -m multiport --dport $ll -j MARK --set-mark $FW_MARK/$FW_MARK -m comment --comment "vpnbypass"; done | |||
for ll in ${ranges}; do iptables -t mangle -I PREROUTING -s $ll -j MARK --set-mark $FW_MARK/$FW_MARK -m comment --comment "vpnbypass"; done | |||
iptables -t mangle -A PREROUTING -m set --match-set $IPSET dst -j MARK --set-mark $FW_MARK/$FW_MARK -m comment --comment "vpnbypass" | |||
ip rule add fwmark $FW_MARK table $TID | |||
output "vpnbypass started with TID: $TID FW_MARK: $FW_MARK\n" | |||
} | |||
stop_service() { | |||
local ll | |||
config_load vpnbypass | |||
vpnbypass_enabled || return 1 | |||
config_get routes 'config' 'remotesubnet' | |||
[ -d /etc/openvpn ] || return 1 | |||
rm -f /etc/hotplug.d/firewall/${START}-${IPSET} | |||
. /lib/functions/network.sh; network_get_ipaddr wanip wan; network_get_gateway gwip wan; network_get_ipaddr lanip lan | |||
[ ! "$wanip" ] && output 'ERROR: Could not get wan ip\n' && exit 0 | |||
[ ! "$gwip" ] && output 'ERROR: Could not get wan gateway\n' && exit 0 | |||
for ll in ${routes}; do ip route del $ll >/dev/null 2>&1; done | |||
# iptables-save | grep -Fv -- "vpnbypass" | iptables-restore | |||
(ip rule del fwmark $FW_MARK table $TID; iptables -t mangle -F; ipset -F $IPSET; ipset -X $IPSET) >/dev/null 2>&1 | |||
(ip route flush table $TID; ip route flush cache) >/dev/null 2>&1 | |||
output "vpnbypass stopped\n" | |||
} | |||
service_triggers() { | |||
procd_add_reload_trigger 'vpnbypass' | |||
procd_add_reload_interface_trigger 'wan' | |||
} |