refactor: Refactor nft rules to use named sets for interfaces and localv4

This commit is contained in:
Andrey Petelin
2025-09-10 17:52:14 +05:00
parent d0ea39abd0
commit d4b5431db4
3 changed files with 54 additions and 68 deletions

View File

@@ -30,8 +30,6 @@ VALID_SERVICES="russia_inside russia_outside ukraine_inside geoblock block porn
DNS_RESOLVERS="1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 9.9.9.9 9.9.9.11 94.140.14.14 94.140.15.15 208.67.220.220 208.67.222.222 77.88.8.1 77.88.8.8"
CHECK_PROXY_IP_DOMAIN="ip.podkop.fyi"
FAKEIP_TEST_DOMAIN="fakeip.podkop.fyi"
INTERFACES_LIST=""
SRC_INTERFACE=""
RESOLV_CONF="/etc/resolv.conf"
TMP_SING_BOX_FOLDER="/tmp/sing-box"
TMP_RULESET_FOLDER="$TMP_SING_BOX_FOLDER/rulesets"
@@ -324,80 +322,60 @@ route_table_rule_mark() {
fi
}
process_interfaces() {
local iface="$1"
INTERFACES_LIST="$INTERFACES_LIST $iface"
iface_flag=1
}
nft_init_interfaces_set() {
nft_create_ifname_set "$NFT_TABLE_NAME" "$NFT_INTERFACE_SET_NAME"
nft_interfaces() {
local table="$NFT_TABLE_NAME"
iface_flag=0
local interface_list
config_get interface_list "main" "iface" "br-lan"
config_list_foreach "main" "iface" "process_interfaces"
if [ "$iface_flag" -eq 0 ]; then
SRC_INTERFACE="br-lan"
elif [ $(echo "$INTERFACES_LIST" | wc -w) -eq 1 ]; then
SRC_INTERFACE=$INTERFACES_LIST
else
local set_name="interfaces"
if ! nft list set inet $table $set_name &>/dev/null; then
nft add set inet $table $set_name { type ifname\; flags interval\; }
fi
for interface in $INTERFACES_LIST; do
if ! nft list element inet $table $set_name { $interface } &>/dev/null; then
nft add element inet $table $set_name { $interface }
fi
done
SRC_INTERFACE=@$set_name
fi
for interface in $interface_list; do
nft add element inet "$NFT_TABLE_NAME" "$NFT_INTERFACE_SET_NAME" "{ $interface }"
done
}
create_nft_table() {
local table="$NFT_TABLE_NAME"
nft add table inet $table
log "Create nft table"
nft_create_table "$NFT_TABLE_NAME"
nft_interfaces
log "Create localv4 set"
nft add set inet $table localv4 { type ipv4_addr\; flags interval\; }
nft add element inet $table localv4 { \
0.0.0.0/8, \
10.0.0.0/8, \
127.0.0.0/8, \
169.254.0.0/16, \
172.16.0.0/12, \
192.0.0.0/24, \
192.0.2.0/24, \
192.88.99.0/24, \
192.168.0.0/16, \
198.51.100.0/24, \
203.0.113.0/24, \
224.0.0.0/4, \
240.0.0.0-255.255.255.255 }
nft_create_ipv4_set "$NFT_TABLE_NAME" "$NFT_LOCALV4_SET_NAME"
nft add element inet "$NFT_TABLE_NAME" localv4 '{
0.0.0.0/8,
10.0.0.0/8,
127.0.0.0/8,
169.254.0.0/16,
172.16.0.0/12,
192.0.0.0/24,
192.0.2.0/24,
192.88.99.0/24,
192.168.0.0/16,
198.51.100.0/24,
203.0.113.0/24,
224.0.0.0/4,
240.0.0.0-255.255.255.255
}'
log "Create common set"
nft_create_ipv4_set "$NFT_TABLE_NAME" "$NFT_COMMON_SET_NAME"
log "Create interface set"
nft_init_interfaces_set
log "Create nft rules"
nft add chain inet $table mangle { type filter hook prerouting priority -150 \; policy accept \;}
nft add chain inet $table mangle_output { type route hook output priority -150 \; policy accept\; }
nft add chain inet $table proxy { type filter hook prerouting priority -100 \; policy accept \;}
nft add chain inet "$NFT_TABLE_NAME" mangle '{ type filter hook prerouting priority -150; policy accept; }'
nft add chain inet "$NFT_TABLE_NAME" mangle_output '{ type route hook output priority -150; policy accept; }'
nft add chain inet "$NFT_TABLE_NAME" proxy '{ type filter hook prerouting priority -100; policy accept; }'
nft add set inet $table podkop_subnets { type ipv4_addr\; flags interval\; auto-merge\; }
nft add rule inet "$NFT_TABLE_NAME" mangle iifname "@$NFT_INTERFACE_SET_NAME" ip daddr "@$NFT_COMMON_SET_NAME" meta l4proto '{ tcp, udp }' meta mark set 0x105 counter
nft add rule inet "$NFT_TABLE_NAME" mangle iifname "@$NFT_INTERFACE_SET_NAME" ip daddr "$SB_FAKEIP_INET4_RANGE" meta l4proto '{ tcp, udp }' meta mark set 0x105 counter
nft add rule inet $table mangle iifname "$SRC_INTERFACE" ip daddr @podkop_subnets meta l4proto tcp meta mark set 0x105 counter
nft add rule inet $table mangle iifname "$SRC_INTERFACE" ip daddr @podkop_subnets meta l4proto udp meta mark set 0x105 counter
nft add rule inet $table mangle iifname "$SRC_INTERFACE" ip daddr "$SB_FAKEIP_INET4_RANGE" meta l4proto tcp meta mark set 0x105 counter
nft add rule inet $table mangle iifname "$SRC_INTERFACE" ip daddr "$SB_FAKEIP_INET4_RANGE" meta l4proto udp meta mark set 0x105 counter
nft add rule inet "$NFT_TABLE_NAME" proxy meta mark 0x105 meta l4proto '{ tcp, udp }' tproxy ip to 127.0.0.1:1602 counter
nft add rule inet $table proxy meta mark 0x105 meta l4proto { tcp, udp } tproxy ip to 127.0.0.1:1602 counter
nft add rule inet $table mangle_output ip daddr @localv4 return
nft add rule inet $table mangle_output ip daddr @podkop_subnets meta l4proto tcp meta mark set 0x00000105 counter
nft add rule inet $table mangle_output ip daddr @podkop_subnets meta l4proto udp meta mark set 0x00000105 counter
nft add rule inet $table mangle_output ip daddr 198.18.0.0/15 meta l4proto tcp meta mark set 0x00000105 counter
nft add rule inet $table mangle_output ip daddr 198.18.0.0/15 meta l4proto udp meta mark set 0x00000105 counter
nft add rule inet "$NFT_TABLE_NAME" mangle_output ip daddr "@$NFT_LOCALV4_SET_NAME" return
nft add rule inet "$NFT_TABLE_NAME" mangle_output ip daddr "@$NFT_COMMON_SET_NAME" meta l4proto '{ tcp, udp }' meta mark set 0x105 counter
nft add rule inet "$NFT_TABLE_NAME" mangle_output ip daddr "$SB_FAKEIP_INET4_RANGE" meta l4proto '{ tcp, udp }' meta mark set 0x105 counter
}
save_dnsmasq_config() {
@@ -1222,8 +1200,8 @@ import_community_service_subnet_list_handler() {
"discord")
URL=$SUBNETS_DISCORD
nft_create_ipv4_set "$NFT_TABLE_NAME" "$NFT_DISCORD_SET_NAME"
nft add rule inet "$NFT_TABLE_NAME" mangle iifname "$SRC_INTERFACE" ip daddr @podkop_discord_subnets \
udp dport '{ 50000-65535 }' meta mark set 0x105 counter
nft add rule inet "$NFT_TABLE_NAME" mangle iifname "@$NFT_INTERFACE_SET_NAME" ip daddr \
"@$NFT_DISCORD_SET_NAME" udp dport '{ 50000-65535 }' meta mark set 0x105 counter
;;
*) return 0 ;;
esac
@@ -1455,11 +1433,10 @@ section_has_enabled_lists() {
## nftables
nft_list_all_traffic_from_ip() {
local ip="$1"
local table="$NFT_TABLE_NAME"
if ! nft list chain inet $table mangle | grep -q "ip saddr $ip"; then
nft insert rule inet $table mangle iifname "$SRC_INTERFACE" ip saddr $ip meta l4proto { tcp, udp } meta mark set 0x105 counter
nft insert rule inet $table mangle ip saddr $ip ip daddr @localv4 return
if ! nft list chain inet "$NFT_TABLE_NAME" mangle | grep -q "ip saddr $ip"; then
nft insert rule inet "$NFT_TABLE_NAME" mangle iifname "@$NFT_INTERFACE_SET_NAME" ip saddr "$ip" meta l4proto '{ tcp, udp }' meta mark set 0x105 counter
nft insert rule inet "$NFT_TABLE_NAME" mangle ip saddr "$ip" ip daddr @localv4 return
fi
}

View File

@@ -1,7 +1,9 @@
## nft
NFT_TABLE_NAME="PodkopTable"
NFT_LOCALV4_SET_NAME="localv4"
NFT_COMMON_SET_NAME="podkop_subnets"
NFT_DISCORD_SET_NAME="podkop_discord_subnets"
NFT_INTERFACE_SET_NAME="interfaces"
## sing-box
# Log

View File

@@ -13,6 +13,13 @@ nft_create_ipv4_set() {
nft add set inet "$table" "$name" '{ type ipv4_addr; flags interval; auto-merge; }'
}
nft_create_ifname_set() {
local table="$1"
local name="$2"
nft add set inet "$table" "$name" '{ type ifname; flags interval; }'
}
# Add one or more elements to a set
nft_add_set_elements() {
local table="$1"