1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Add nftables support to OMR-DSCP and separate interface and scripts

This commit is contained in:
Ycarus (Yannick Chabanois) 2024-01-10 17:34:13 +01:00
parent f2a1250ccc
commit aecc558e9d
5 changed files with 239 additions and 4 deletions

52
omr-dscp/Makefile Normal file
View file

@ -0,0 +1,52 @@
#
# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=omr-dscp
PKG_VERSION:=0.1
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
DEPENDS:= +dnsmasq-full +LINUX_5_4:iptables +LINUX_5_4:iptables-mod-extra +LINUX_5_4:ipset
TITLE:=OMR-DSCP
endef
define Package/$(PKG_NAME)-nft
SECTION:=net
CATEGORY:=Network
DEPENDS:= +dnsmasq-full
TITLE:=OMR-DSCP nft
endef
define Package/$(PKG_NAME)/description
OMR-ByPass
endef
define Package/$(PKG_NAME)-nft/description
OMR-ByPass nft support
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(CP) ./files/* $(1)/
rm -f $(1)/etc/init.d/omr-dscp-nft
endef
define Package/$(PKG_NAME)-nft/install
$(CP) ./files/* $(1)/
mv $(1)/etc/init.d/omr-dscp-nft $(1)/etc/init.d/omr-dscp
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,$(PKG_NAME)-nft))

View file

@ -0,0 +1,263 @@
config classify
option direction 'both'
option proto 'icmp'
option class 'cs7'
option comment 'ICMP'
config classify
option direction 'both'
option proto 'udp'
option class 'cs4'
option src_port '53,123,5353'
option comment 'DNS udp and NTP'
config classify
option direction 'both'
option proto 'tcp'
option class 'cs4'
option src_port '53,5353'
option comment 'DNS tcp'
config classify
option direction 'both'
option proto 'tcp'
option class 'cs4'
option dest_port '65500'
option comment 'OMR API'
config classify
option direction 'both'
option proto 'tcp'
option class 'cs7'
option dest_port '65001,65301,65401,65011'
option comment 'OMR vpn'
config classify
option direction 'both'
option proto 'udp'
option class 'cs7'
option dest_port '65001,65301'
option comment 'OMR vpn'
config classify
option direction 'both'
option proto 'tcp'
option class 'cs6'
option dest_port '65101,65228'
option comment 'OMR proxy'
config domains
option name 'googlevideo.com'
option class 'cs4'
option comment 'Youtube'
config domains
option name 'nflxvideo.net'
option class 'cs4'
option comment 'NetFlix'
config domains
option name 's3.ll.dash.row.aiv-cdn.net'
option class 'cs4'
option comment 'AmazonVideo'
config domains
option name 'd25xi40x97liuc.cloudfront.net'
option class 'cs4'
option comment 'AmazonVideo'
config domains
option name 'aiv-delivery.net'
option class 'cs4'
option comment 'AmazonVideo'
config domains
option name 'fbcdn.net'
option class 'cs4'
option comment 'Facebook'
config domains
option name 'ttvnw.net'
option class 'cs4'
option comment 'Twitch'
config domains
option name 'vevo.com'
option class 'cs4'
option comment 'VeVo'
config domains
option name 'audio-fa.scdn.com'
option class 'cs4'
option comment 'Spotify'
config domains
option name 'deezer.com'
option class 'cs4'
option comment 'Deezer'
config domains
option name 'sndcdn.com'
option class 'cs4'
option comment 'SoundCloud'
config domains
option name 'last.fm'
option class 'cs4'
option comment 'last.fm'
config domains
option name 'v.redd.it'
option class 'cs4'
option comment 'reddit videos'
config domains
option name 'ttvnw.net'
option class 'cs4'
option comment 'twitch.tv'
config domains
option name 'googletagmanager.com'
option class 'cs2'
option comment 'cdn'
config domains
option name 'googleusercontent.com'
option class 'cs2'
option comment 'cdn'
config domains
option name 'google.com'
option class 'cs2'
option comment 'cdn'
config domains
option name 'fbcdn.net'
option class 'cs2'
option comment 'cdn'
config domains
option name 'akamaihd.net'
option class 'cs2'
option comment 'cdn'
config domains
option name 'whatsapp.net'
option class 'cs2'
option comment 'chat'
config domains
option name 'whatsapp.com'
option class 'cs2'
option comment 'chat'
config domains
option name 'zoom.us'
option class 'cs2'
option comment 'chat'
config domains
option name 'googleapis.com'
option class 'cs2'
option comment 'cdn'
config domains
option name '1e100.net'
option class 'cs2'
option comment 'cdn'
config domains
option name 'hwcdn.net'
option class 'cs2'
option comment 'cdn'
config domains
option name 'download.qq.com'
option class 'cs1'
option comment 'qq download'
config domains
option name 'steamcontent.com'
option class 'cs1'
option comment 'Steam download'
config domains
option name 'gs2.ww.prod.dl.playstation.net'
option class 'cs1'
option comment 'PSN download'
config domains
option name 'dropbox.com'
option class 'cs1'
option comment 'Dropbox'
config domains
option name 'dropboxstatic.com'
option class 'cs1'
option comment 'Dropbox'
config domains
option name 'dropbox-dns.com'
option class 'cs1'
option comment 'Dropbox'
config domains
option name 'log.getdropbox.com'
option class 'cs1'
option comment 'Dropbox'
config domains
option name 'drive.google.com'
option class 'cs1'
option comment 'Google Drive'
config domains
option name 'drive-thirdparty.googleusercontent.com'
option class 'cs1'
option comment 'Google Drive'
config domains
option name 'docs.google.com'
option class 'cs1'
option comment 'Google Docs'
config domains
option name 'docs.googleusercontent.com'
option class 'cs1'
option comment 'Google Docs'
config domains
option name 'gvt1.com'
option class 'cs1'
option comment 'PlayStore Download'
config domains
option name 'mmg-fna.whatsapp.net'
option class 'cs1'
option comment 'WhatsApp Files'
config domains
option name 'upload.youtube.com'
option class 'cs1'
option comment 'Youtube Upload'
config domains
option name 'upload.video.google.com'
option class 'cs1'
option comment 'Youtube Upload'
config domains
option name 'windowsupdate.com'
option class 'cs1'
option comment 'WindowsUpdate'
config domains
option name 'update.microsoft.com'
option class 'cs1'
option comment 'WindowsUpdate'
config domains
option name 'tv.milkywan.fr'
option class 'cs5'
option comment 'MilkyWan TV'

View file

@ -0,0 +1,250 @@
#!/bin/sh /etc/rc.common
# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 :
# shellcheck disable=SC2034
START=90
# shellcheck disable=SC2034
STOP=10
# shellcheck disable=SC2034
USE_PROCD=1
# shellcheck disable=SC1091
. /lib/functions.sh
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IP6TABLES="/usr/sbin/ip6tables-nft"
else
IPTABLES="/usr/sbin/iptables"
IP6TABLES="/usr/sbin/ip6tables"
fi
# Get the lan interface name
lan_device=
config_load network
config_get lan_device lan ifname
config_load dscp
_ipt4() {
$IPTABLES -w -t mangle "$@" 2>&1 >/dev/null
}
_ipt6() {
$IP6TABLES -w -t mangle "$@" 2>&1 >/dev/null
}
_add_dscp_rule() {
_ipt4 -A dscp_prerouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j DSCP --set-dscp-class "$class"
_ipt4 -A dscp_prerouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j RETURN
_ipt4 -A dscp_postrouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j DSCP --set-dscp-class "$class"
_ipt4 -A dscp_postrouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j RETURN
_ipt6 -A dscp_prerouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j DSCP --set-dscp-class "$class"
_ipt6 -A dscp_prerouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j RETURN
_ipt6 -A dscp_postrouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j DSCP --set-dscp-class "$class"
_ipt6 -A dscp_postrouting -p "$proto" -s "$src_ip" -d "$dest_ip" "$@" -m comment --comment "$comment" -j RETURN
}
_add_dscp_domain() {
domain=""; config_get domain "$1" name ""
class=""; config_get class "$1" class ""
[ -n "$domain" ] && [ -n "$class" ] && {
if [ "$(uci -q get dhcp.@dnsmasq[0].ipset | grep /$domain/)" = "" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="/$domain/omr_dscp-$class,omr_dscp6-$class"
else
dnsmasqipset=$(uci -q get dhcp.@dnsmasq[0].ipset | sed 's/ /\n/g')
for dnsipset in $dnsmasqipset; do
if [ "$(echo $dnsipset | cut -d/ -f2)" = "$domain" ]; then
uci -q del_list dhcp.@dnsmasq[0].ipset=$dnsipset
uci -q add_list dhcp.@dnsmasq[0].ipset="$dnsipset,omr_dscp-$class,omr_dscp6-$class"
fi
done
fi
}
}
_add_dscp_domains_rules() {
for class in cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7 ef; do
ipset -q --exist restore <<-EOF
create omr_dscp-$class hash:net hashsize 64
create omr_dscp6-$class hash:net family inet6 hashsize 64
EOF
_ipt4 -A dscp_prerouting -m set --match-set omr_dscp-$class src,dst -m comment --comment "$class" -j DSCP --set-dscp-class "$class"
_ipt4 -A dscp_prerouting -m set --match-set omr_dscp-$class src,dst -m comment --comment "$class" -j RETURN
_ipt4 -A dscp_postrouting -m set --match-set omr_dscp-$class src,dst -m comment --comment "$class" -j DSCP --set-dscp-class "$class"
_ipt4 -A dscp_postrouting -m set --match-set omr_dscp-$class src,dst -m comment --comment "$class" -j RETURN
_ipt6 -A dscp_prerouting -m set --match-set omr_dscp6-$class src,dst -m comment --comment "$class" -j DSCP --set-dscp-class "$class"
_ipt6 -A dscp_prerouting -m set --match-set omr_dscp6-$class src,dst -m comment --comment "$class" -j RETURN
_ipt6 -A dscp_postrouting -m set --match-set omr_dscp6-$class src,dst -m comment --comment "$class" -j DSCP --set-dscp-class "$class"
_ipt6 -A dscp_postrouting -m set --match-set omr_dscp6-$class src,dst -m comment --comment "$class" -j RETURN
done
}
_add_dscp_rules() {
proto="" ; config_get proto "$1" proto all
src_ip="" ; config_get src_ip "$1" src_ip 0.0.0.0/0
src_port="" ; config_get src_port "$1" src_port 0:65535
dest_ip="" ; config_get dest_ip "$1" dest_ip 0.0.0.0/0
dest_port="" ; config_get dest_port "$1" dest_port 0:65535
class="" ; config_get class "$1" class
direction="" ; config_get direction "$1" direction "upload"
comment="" ; config_get comment "$1" comment "-"
src_port="$(echo $src_port | sed 's/-/:/g')"
dest_port="$(echo $dest_port | sed 's/-/:/g')"
case "$direction" in
upload|both)
# Apply the rule locally
case "$proto" in
tcp|udp)
_add_dscp_rule -m multiport --sports "$src_port" -m multiport --dports "$dest_port"
;;
*)
_add_dscp_rule
;;
esac
;;
download|both)
;;
esac
}
_add_prerouting_chain() {
_ipt4 -N "$1"
_ipt4 -I PREROUTING -i "$lan_device" -j "$1"
_ipt6 -N "$1"
_ipt6 -I PREROUTING -i "$lan_device" -j "$1"
}
_add_postrouting_chain() {
_ipt4 -N "$1"
_ipt4 -I POSTROUTING -j "$1"
_ipt6 -N "$1"
_ipt6 -I POSTROUTING -j "$1"
}
_add_fwmark_chain() {
_ipt4 -N dscp_mark
_ipt4 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt4 -A POSTROUTING -j dscp_mark
_ipt6 -N dscp_mark
_ipt6 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt6 -A POSTROUTING -j dscp_mark
for class in cs4 cs5 cs6 cs7; do
# xtun (hex) -> 0x7874756e
_ipt4 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
_ipt6 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
done
}
_add_dscp_output_chain() {
_ipt4 -N dscp_output
_ipt4 -I OUTPUT -j dscp_output
_ipt6 -N dscp_output
_ipt6 -I OUTPUT -j dscp_output
}
_remove_prerouting_chain() {
_ipt4 -F "$1" 2>/dev/null || return
_ipt4 -D PREROUTING -i "$lan_device" -j "$1"
_ipt4 -X "$1" 2>/dev/null
_ipt6 -F "$1" 2>/dev/null || return
_ipt6 -D PREROUTING -i "$lan_device" -j "$1"
_ipt6 -X "$1" 2>/dev/null
}
_remove_postrouting_chain() {
_ipt4 -F "$1" 2>/dev/null || return
_ipt4 -D POSTROUTING -j "$1"
_ipt4 -X "$1" 2>/dev/null
_ipt6 -F "$1" 2>/dev/null || return
_ipt6 -D POSTROUTING -j "$1"
_ipt6 -X "$1" 2>/dev/null
}
_remove_output_chain() {
_ipt4 -F "$1" 2>/dev/null || return
_ipt4 -D OUTPUT -j "$1"
_ipt4 -X "$1" 2>/dev/null
_ipt6 -F "$1" 2>/dev/null || return
_ipt6 -D OUTPUT -j "$1"
_ipt6 -X "$1" 2>/dev/null
}
_remove_ipset_dnsmasq() {
#dnsmasqipset=$(uci -q get dhcp.@dnsmasq[0].ipset | sed 's/ /\n/g' | grep -v omr_dscp)
# Remove DSCP ipset in DNSMASQ and keep others
dnsmasqipset=$(uci -q get dhcp.@dnsmasq[0].ipset | sed 's/ /\n/g')
uci -q delete dhcp.@dnsmasq[0].ipset
if [ -n "$dnsmasqipset" ]; then
for dnsipset in $dnsmasqipset; do
ipsets=""
allipsets=$(echo $dnsipset | cut -d/ -f3 | sed 's/,/\n/g')
for ipset in $allipsets; do
[ "$(echo $ipset | grep -v omr_dscp)" != "" ] && {
[ "$ipsets" != "" ] && ipsets="$ipsets,$ipset"
[ "$ipsets" = "" ] && ipsets="$ipset"
}
done
if [ "$ipsets" != "" ]; then
resultipset="/$(echo $dnsipset | cut -d/ -f2)/$ipsets"
uci -q add_list dhcp.@dnsmasq[0].ipset=$resultipset
fi
done
fi
}
_setup_tunnel() {
# Mark the packets to route through xtun0
_add_fwmark_chain
# tun0: cs0 (default)
# xtun0: cs6
_ipt4 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
_ipt6 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
}
_cleanup() {
_remove_prerouting_chain dscp_prerouting
_remove_prerouting_chain dscp_mark
_remove_postrouting_chain dscp_postrouting
_remove_postrouting_chain dscp_mark
_remove_output_chain dscp_output
_remove_ipset_dnsmasq
uci -q commit dhcp
}
start_service() {
# Cleanup
_cleanup
# Add chains
_add_prerouting_chain dscp_prerouting
_add_postrouting_chain dscp_postrouting
_add_dscp_output_chain
_add_dscp_domains_rules
# Setup the tunnels dscp / marks
_setup_tunnel
# Add rules base on the user configuration
config_foreach _add_dscp_rules classify
config_foreach _add_dscp_domain domains
uci -q commit dhcp
}
stop_service() {
_cleanup
}
reload_service() {
start
}
service_triggers() {
procd_add_reload_trigger dscp glorytun
}

View file

@ -0,0 +1,183 @@
#!/bin/sh /etc/rc.common
# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 :
# shellcheck disable=SC2034
START=90
# shellcheck disable=SC2034
STOP=10
# shellcheck disable=SC2034
USE_PROCD=1
# shellcheck disable=SC1091
. /lib/functions.sh
# Get the lan interface name
lan_device=
config_load network
config_get lan_device lan ifname
#config_load dscp
_add_dscp_domain() {
domain=""; config_get domain "$1" name ""
class=""; config_get class "$1" class ""
[ -n "$domain" ] && [ -n "$class" ] && [ -z "$(uci -q get dhcp.omr_dscp-$class.domain | grep $domain)" ] && {
uci -q batch <<-EOF
add_list dhcp.omr_dscp_$class.domain="$domain"
commit dhcp
EOF
}
}
_add_dscp_domains_rules() {
for class in cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7 ef; do
uci -q batch <<-EOF
set dhcp.omr_dscp_${class}=ipset
add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_4"
add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_6"
commit dhcp
set firewall.omr_dscp_${class}_4=ipset
set firewall.omr_dscp_${class}_4.name="omr_dscp_${class}_4"
set firewall.omr_dscp_${class}_4.match='dest_ip"
set firewall.omr_dscp_${class}_6=ipset
set firewall.omr_dscp_${class}_6.name="omr_dscp_${class}_6"
set firewall.omr_dscp_${class}_6.match='dest_ip"
set firewall.omr_dscp_${class}=rule
set firewall.omr_dscp_${class}.ipset="omr_dscp-${class}_4"
set firewall.omr_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr_dscp_${class}.target='DSCP'
set firewall.omr_dscp_${class}.src='lan'
set firewall.omr_dscp_${class}.dest='*'
set firewall.omr6_dscp_${class}=rule
set firewall.omr6_dscp_${class}.ipset="omr_dscp-${class}_6"
set firewall.omr6_dscp_${class}.target='DSCP'
set firewall.omr6_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr6_dscp_${class}.src='lan'
set firewall.omr6_dscp_${class}.dest='*'
commit firewall
EOF
done
}
_add_dscp_rules() {
proto="" ; config_get proto "$1" proto all
src_ip="" ; config_get src_ip "$1" src_ip 0.0.0.0/0
src_port="" ; config_get src_port "$1" src_port 0:65535
dest_ip="" ; config_get dest_ip "$1" dest_ip 0.0.0.0/0
dest_port="" ; config_get dest_port "$1" dest_port 0:65535
class="" ; config_get class "$1" class
direction="" ; config_get direction "$1" direction "upload"
comment="" ; config_get comment "$1" comment "-"
src_port="$(echo $src_port | sed 's/:/-/g')"
dest_port="$(echo $dest_port | sed 's/:/-/g')"
count=$((count + 1))
[ "$proto" = "all" ] && proto="tcp udp"
case "$direction" in
upload|both)
# Apply the rule locally
uci -q batch <<-EOF
set firewall.omr_dscp_rule$count=rule
set firewall.omr_dscp_rule$count.name="omr_dscp_rule$count"
set firewall.omr_dscp_rule$count.target="DSCP"
set firewall.omr_dscp_rule$count.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr_dscp_rule$count.src="lan"
set firewall.omr_dscp_rule$count.src_ip="$src_ip"
set firewall.omr_dscp_rule$count.dest_ip="$dest_ip"
set firewall.omr_dscp_rule$count.proto="$proto"
EOF
src_port="$(echo $src_port | sed 's/,/ /g')"
dest_port="$(echo $dest_port | sed 's/,/ /g')"
for port in $src_port; do
uci -q set firewall.omr_dscp_rule$count.src_port="$src_port"
done
for port in $src_port; do
uci -q set firewall.omr_dscp_rule$count.dest_port="$dest_port"
done
#_add_dscp_rule -m multiport --sports "$src_port" -m multiport --dports "$dest_port"
;;
download|both)
;;
esac
uci -q commit firewall
}
_add_fwmark_chain() {
_ipt4 -N dscp_mark
_ipt4 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt4 -A POSTROUTING -j dscp_mark
_ipt6 -N dscp_mark
_ipt6 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt6 -A POSTROUTING -j dscp_mark
for class in cs4 cs5 cs6 cs7; do
# xtun (hex) -> 0x7874756e
_ipt4 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
_ipt6 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
done
}
_remove_ipset_dnsmasq() {
[ -n "$(echo $1 | grep omr_dscp)" ] && uci -q delete dhcp.$1
}
_remove_rules() {
[ -n "$(echo $1 | grep omr_dscp)" ] && uci -q delete firewall.$1
}
_setup_tunnel() {
# Mark the packets to route through xtun0
_add_fwmark_chain
# tun0: cs0 (default)
# xtun0: cs6
_ipt4 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
_ipt6 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
}
_cleanup() {
config_load dhcp
config_foreach _remove_ipset_dnsmasq
config_load firewall
config_foreach _remove_rules
uci -q commit dhcp
uci -q commit firewall
fw4 restart
}
start_service() {
# Cleanup
_cleanup
config_load dscp
# Add chains
_add_dscp_domains_rules
# Setup the tunnels dscp / marks
#_setup_tunnel
# Add rules base on the user configuration
count=0
config_foreach _add_dscp_rules classify
config_foreach _add_dscp_domain domains
uci -q commit dhcp
fw4 restart
}
stop_service() {
_cleanup
}
reload_service() {
start
}
service_triggers() {
procd_add_reload_trigger dscp
}