Can I have two routes for two different IP lists?

You can have more than one of these. Reduce ranges of IPs to subnets as much as possible. Individual IPs would be /32.

Keep in mind, that the disadvantage of static routes is the need for a static gateway.
This can be critical if the client is roaming between different ISPs, or the gateway is dynamic.
The gateway is necessary unless the interface represents a tunnel.
In addition, static routes don't scale as well as IP sets for a large number of entries.

1 Like

I have a very long list, so I need a very efficient way.

Do you mean that it will put a load on the router just like PBR? By the way, did you makeup anything about where the problem is in my config?

Yep, it can bloat the config greatly increasing the time required to properly process it by the service, specifically if you plan to add 800+ CIDR entries from above.

Sorry, I'm unable to access that page:

You can try cpaste.org as an alternative.

I have PBR enabled on my router. Can that be the problem?
And what do I have to do everytime for changes to take effect? Do I have to restart the router everytime or uci commit firewall and uci commit network is enough?

Different PBR methods are not compatible in general case.
You need to remove the PBR app to proceed with netifd.

This depends on the method you make the changes.

Committing is necessary to write runtime changes to persistent config files.
Restarting the the services or the router is also necessary to apply the changed configs.

Can't I just add a rule with more priority to the main routing table and have it co-exist with PBR?

It looks like the latest version of PBR app now allows overriding own rules with custom ones.
I guess, a custom rule with a priority of about 25000 should be optimal.

Great! Do I have to do it in a special way?
Because if I just add a rule to the pbr_wan table, it gets deleted after router restart

The code I posted above should still work if you adjust the rule priority.

I executed your code, added 2 subnets to the created ipset just for testing and changed the priority to 22000. It didn't work! :frowning:
I can confirm that the IPset , the firewall mark rule and the ipv4 rule are created. But, the ip rule show command doesn't show the rule, and by checking luci, I confirmed that it hasn't been activated.
The nft list ruleset also shows this:

table inet fw4 {
	set wan {
		type ipv4_addr
		flags interval
		auto-merge
		elements = { 2.57.3.0/24, 2.144.0.0/14 }
	}

	set pbr_wan_4_src_ip_cfg046ff5 {
		type ipv4_addr
		flags interval
		auto-merge
		comment "lan2wan"
		elements = { 192.168.3.0/24 }
	}

	chain input {
		type filter hook input priority filter; policy accept;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "lan2" jump input_lan2 comment "!fw4: Handle lan2 IPv4/IPv6 input traffic"
		iifname "wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
		iifname "sstp-Tor" jump input_VPN comment "!fw4: Handle VPN IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "lan2" jump forward_lan2 comment "!fw4: Handle lan2 IPv4/IPv6 forward traffic"
		iifname "wan" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname "sstp-Tor" jump forward_VPN comment "!fw4: Handle VPN IPv4/IPv6 forward traffic"
		jump handle_reject
	}

	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "lan2" jump output_lan2 comment "!fw4: Handle lan2 IPv4/IPv6 output traffic"
		oifname "wan" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
		oifname "sstp-Tor" jump output_VPN comment "!fw4: Handle VPN IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
		iifname "lan2" jump helper_lan2 comment "!fw4: Handle lan2 IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_lan {
		jump accept_from_lan
	}

	chain output_lan {
		jump accept_to_lan
	}

	chain forward_lan {
		jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
		jump accept_to_VPN comment "!fw4: Accept lan to VPN forwarding"
		jump accept_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname "br-lan" counter packets 36 bytes 2304 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname "br-lan" counter packets 4 bytes 512 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain input_lan2 {
		jump accept_from_lan2
	}

	chain output_lan2 {
		jump accept_to_lan2
	}

	chain forward_lan2 {
		jump accept_to_wan comment "!fw4: Accept lan2 to wan forwarding"
		jump accept_to_lan2
	}

	chain helper_lan2 {
	}

	chain accept_from_lan2 {
		iifname "lan2" counter packets 0 bytes 0 accept comment "!fw4: accept lan2 IPv4/IPv6 traffic"
	}

	chain accept_to_lan2 {
		oifname "lan2" counter packets 2 bytes 192 accept comment "!fw4: accept lan2 IPv4/IPv6 traffic"
	}

	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
		icmp type echo-request counter packets 0 bytes 0 accept comment "!fw4: Allow-Ping"
		meta nfproto ipv4 meta l4proto igmp counter packets 5 bytes 180 accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 90 bytes 5760 accept comment "!fw4: Allow-ICMPv6-Input"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
		jump reject_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		jump reject_to_wan
	}

	chain accept_to_wan {
		oifname "wan" counter packets 4 bytes 600 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname "wan" counter packets 234 bytes 41245 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain reject_to_wan {
		oifname "wan" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain input_VPN {
		jump reject_from_VPN
	}

	chain output_VPN {
		jump accept_to_VPN
	}

	chain forward_VPN {
		jump reject_to_VPN
	}

	chain accept_to_VPN {
		oifname "sstp-Tor" counter packets 78 bytes 4316 accept comment "!fw4: accept VPN IPv4/IPv6 traffic"
	}

	chain reject_from_VPN {
		iifname "sstp-Tor" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject VPN IPv4/IPv6 traffic"
	}

	chain reject_to_VPN {
		oifname "sstp-Tor" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject VPN IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "wan" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
		oifname "sstp-Tor" jump srcnat_VPN comment "!fw4: Handle VPN IPv4/IPv6 srcnat traffic"
	}

	chain srcnat_wan {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
	}

	chain srcnat_VPN {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 VPN traffic"
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
		jump pbr_prerouting comment "Jump into pbr prerouting chain"
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
		jump pbr_postrouting comment "Jump into pbr postrouting chain"
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
		iifname "br-lan" ip daddr @wan counter packets 0 bytes 0 meta mark set 0x00000001 comment "!fw4: Mark-LAN-WAN"
		jump pbr_input comment "Jump into pbr input chain"
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
		jump pbr_output comment "Jump into pbr output chain"
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
		jump pbr_forward comment "Jump into pbr forward chain"
	}

	chain pbr_forward {
	}

	chain pbr_input {
	}

	chain pbr_output {
	}

	chain pbr_prerouting {
		ip saddr @pbr_wan_4_src_ip_cfg046ff5 goto pbr_mark_0x010000 comment "lan2wan"
	}

	chain pbr_postrouting {
	}

	chain pbr_mark_0x010000 {
		counter packets 0 bytes 0 meta mark set meta mark & 0xff01ffff | 0x00010000
		return
	}

	chain pbr_mark_0x020000 {
		counter packets 0 bytes 0 meta mark set meta mark & 0xff02ffff | 0x00020000
		return
	}

	chain pbr_mark_0x030000 {
		counter packets 0 bytes 0 meta mark set meta mark & 0xff03ffff | 0x00030000
		return
	}
}

Any ideas what is wrong?

If you need to include or exclude the whole country, use geoip matcher for this purpose.

Specify destination zone as asterisk on the mark firewall rule to make it use the prerouting chain.
You may also need to use a specific firewall mark to avoid being re-marked by the PBR app.
Traffic counters on the firewall rules can help you identify whether the rules work or not.

is this a package?

That didn't work either

I currently solved this by using the custom user file option, the IP list from ipdeny.com and the script provided in this post: Policy-Based-Routing (pbr) package discussion - #127 by stangri
I don't know how heavy is this method, but for now, everything is smooth and working

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.