Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
docs:guide-user:firewall:fw3_configurations:dns_ipset [2021/02/27 12:03] – [Persistent IP sets] clarify vgaeteradocs:guide-user:firewall:fw3_configurations:dns_ipset [2023/11/17 09:13] (current) – [Command-line instructions] vgaetera
Line 1: Line 1:
-====== DNS-based firewall with IP sets ====== +====== Filtering traffic with IP sets by DNS ====== 
-{{section>meta:infobox:howto_links#cli_skills&noheader&nofooter&noeditbutton}}+{{section>meta:infobox:howto_links#basic_skills&noheader&nofooter&noeditbutton}}
  
 ===== Introduction ===== ===== Introduction =====
-  * This how-to describes the method for setting up DNS-based firewall with [[wp>Netfilter#ipset|IP sets]] on OpenWrt. +  * This how-to configures traffic filtering with [[https://wiki.nftables.org/wiki-nftables/index.php/Sets|IP sets]] by DNS on OpenWrt. 
-  * It relies on [[docs:guide-user:base-system:dhcp.dnsmasq|Dnsmasq]][[packages:pkgdata:ipset-dns|ipset-dns]] and firewall with [[docs:guide-user:firewall:firewall_configuration#ip_sets|IP sets]] to resolve and filter domains+  * It relies on [[packages:pkgdata:resolveip]] and [[docs:guide-user:firewall:overview|firewall]] with [[docs:guide-user:firewall:firewall_configuration#ip_sets|IP sets]] to resolve and filter domains.
-  * Follow [[docs:guide-user:firewall:fw3_configurations:intercept_dns|DNS hijacking]] to intercept DNS queries from your LAN clients.+
  
 ===== Goals ===== ===== Goals =====
-  * Filter LAN client traffic based on DNS with IP sets.+  * Filter LAN client traffic with IP sets by DNS.
  
-===== Instructions ===== +===== Command-line instructions ===== 
-Install the packages and configure IP sets for domains to filter+Install the required packages. 
-Set up firewall rules to filter LAN client traffic which destination matches the IP sets. +Filter LAN client traffic with firewall and IP sets. 
-Configure the domains which addresses should be stored in the IP sets.+Set up [[docs:guide-user:advanced:ipset_extras|IP set extras]] and [[docs:guide-user:advanced:hotplug_extras|Hotplug extras]] to automatically populate IP sets.
  
 <code bash> <code bash>
 # Install packages # Install packages
 opkg update opkg update
-opkg install dnsmasq ipset ipset-dns+opkg install resolveip
  
 # Configure IP sets # Configure IP sets
-uci -q delete firewall.filter +uci -q delete dhcp.filter 
-uci set firewall.filter="ipset" +uci set dhcp.filter="ipset" 
-uci set firewall.filter.name="filter" +uci add_list dhcp.filter.name="filter" 
-uci set firewall.filter.family="ipv4+uci add_list dhcp.filter.name="filter6
-uci set firewall.filter.storage="hash+uci add_list dhcp.filter.domain="example.com
-uci set firewall.filter.match="ip" +uci add_list dhcp.filter.domain="example.net
-uci -q delete firewall.filter6 +uci commit dhcp
-uci set firewall.filter6="ipset+
-uci set firewall.filter6.name="filter6" +
-uci set firewall.filter6.family="ipv6" +
-uci set firewall.filter6.storage="hash" +
-uci set firewall.filter6.match="ip"+
  
 # Filter LAN client traffic with IP sets # Filter LAN client traffic with IP sets
-uci -q delete firewall.filter_fwd +for IPV in 4 6 
-uci set firewall.filter_fwd="rule" +do 
-uci set firewall.filter_fwd.name="Filter-IPset-DNS-Forward" +uci -q delete firewall.fwd_filter${IPV%4} 
-uci set firewall.filter_fwd.src="lan" +uci set firewall.fwd_filter${IPV%4}="rule" 
-uci set firewall.filter_fwd.dest="wan" +uci set firewall.fwd_filter${IPV%4}.name="Filter-IPset-DNS-Forward" 
-uci set firewall.filter_fwd.ipset="filter dest" +uci set firewall.fwd_filter${IPV%4}.src="lan" 
-uci set firewall.filter_fwd.family="ipv4" +uci set firewall.fwd_filter${IPV%4}.dest="wan" 
-uci set firewall.filter_fwd.proto="all" +uci set firewall.fwd_filter${IPV%4}.proto="all" 
-uci set firewall.filter_fwd.target="REJECT" +uci set firewall.fwd_filter${IPV%4}.family="ipv${IPV}
-uci -q delete firewall.filter6_fwd +uci set firewall.fwd_filter${IPV%4}.ipset="filter${IPV%4} dest" 
-uci set firewall.filter6_fwd="rule" +uci set firewall.fwd_filter${IPV%4}.target="REJECT" 
-uci set firewall.filter6_fwd.name="Filter-IPset-DNS-Forward" +done
-uci set firewall.filter6_fwd.src="lan" +
-uci set firewall.filter6_fwd.dest="wan" +
-uci set firewall.filter6_fwd.ipset="filter6 dest" +
-uci set firewall.filter6_fwd.family="ipv6" +
-uci set firewall.filter6_fwd.proto="all" +
-uci set firewall.filter6_fwd.target="REJECT"+
 uci commit firewall uci commit firewall
-/etc/init.d/firewall restart 
  
-Configure ipset-dns +Populate IP sets 
-uci set ipset-dns.@ipset-dns[0].ipset="filter" +ipset setup
-uci set ipset-dns.@ipset-dns[0].ipset6="filter6" +
-uci commit ipset-dns +
-/etc/init.d/ipset-dns restart +
- +
-# Resolve race conditions for ipset-dns +
-cat << "EOF" > /etc/firewall.ipsetdns +
-/etc/init.d/ipset-dns restart +
-EOF +
-cat << "EOF" >> /etc/sysupgrade.conf +
-/etc/firewall.ipsetdns +
-EOF +
-uci -q delete firewall.ipsetdns +
-uci set firewall.ipsetdns="include" +
-uci set firewall.ipsetdns.path="/etc/firewall.ipsetdns" +
-uci set firewall.ipsetdns.reload="1" +
-uci commit firewall +
-/etc/init.d/firewall restart +
- +
-# Configure domains to filter +
-uci add_list dhcp.@dnsmasq[0].server="/example.com/127.0.0.1#53001" +
-uci add_list dhcp.@dnsmasq[0].server="/example.net/127.0.0.1#53001" +
-uci commit dhcp +
-/etc/init.d/dnsmasq restart+
 </code> </code>
  
Line 92: Line 56:
 <code bash> <code bash>
 # Restart services # Restart services
-/etc/init.d/log restart; /etc/init.d/firewall restart +service firewall restart
-/etc/init.d/ipset-dns restart; /etc/init.d/dnsmasq restart +
- +
-# Log and status +
-logread -e dnsmasq; netstat -l -n -p | grep -e dnsmasq +
-logread -e ipset-dns; netstat -l -n -p | grep -e ipset-dns+
  
 # Runtime configuration # Runtime configuration
-pgrep -f -a dnsmasq; pgrep -f -a ipset-dns +nft list ruleset
-iptables-save; ip6tables-save; ipset list+
  
 # Persistent configuration # Persistent configuration
-uci show firewall; uci show dhcp; uci show ipset-dns+uci show firewall; crontab -l
 </code> </code>
  
Line 110: Line 68:
 ==== Web interface ==== ==== Web interface ====
 If you want to manage the settings using web interface. If you want to manage the settings using web interface.
-  * Navigate to **[[http://openwrt.lan/|LuCI]] -> Network -> Firewall -> Traffic Rules -> Filter-IPset-DNS-Forward** to manage firewall rules. +  * Navigate to **LuCI -> Network -> Firewall -> Traffic Rules -> Filter-IPset-DNS-Forward** to manage firewall rules. 
-  * Navigate to **[[http://openwrt.lan/|LuCI]] -> Network -> DHCP and DNS -> General Settings -> DNS forwardings** to manage domains.+  * Navigate to **LuCI -> Network -> DHCP and DNS -> IP sets** to manage domains
 +Reboot the router to apply the changes.
  
-==== Preresolve domains ==== +==== Manage domains ==== 
-Preresolve domains at startup.+Add/remove domains to/from the filtering list.
  
 <code bash> <code bash>
-Preresolve domains +Add domains 
-cat << "EOF" > /etc/firewall.dnsmasq +uci add_list dhcp.filter.domain="example.com
-/etc/init.d/dnsmasq restart +uci add_list dhcp.filter.domain="example.net"
-uci get dhcp.@dnsmasq[0].server \ +
-| sed -e "s/\s/\n/g"+
-| sed -n -e "s/^\///;s/\/.*$//p+
-| while read -r IPSET_DOMAIN +
-do nslookup "${IPSET_DOMAIN}" localhost +
-done +
-EOF +
-cat << "EOF" >> /etc/sysupgrade.conf +
-/etc/firewall.dnsmasq +
-EOF +
-uci -q delete firewall.dnsmasq +
-uci set firewall.dnsmasq="include" +
-uci set firewall.dnsmasq.path="/etc/firewall.dnsmasq" +
-uci set firewall.dnsmasq.reload="1" +
-uci commit firewall +
-/etc/init.d/firewall restart +
-</code>+
  
-==== Persistent IP sets ==== +# Remove domains 
-Disable domain preresolving+uci del_list dhcp.filter.domain="example.com" 
-Use persistent IP sets. +uci del_list dhcp.filter.domain="example.net"
-Save IP sets daily at midnight.+
  
-<code bash> +Save and apply 
-Disable domain preresolving +uci commit dhcp 
-uci set firewall.dnsmasq.enabled="0" +ipset setup
- +
-# Use persistent IP sets +
-cat << "EOF" > /etc/firewall.ipset-save +
-ipset save > /etc/ipset.save +
-EOF +
-cat << "EOF" > /etc/firewall.ipset-restore +
-ipset -! restore < /etc/ipset.save +
-EOF +
-cat << "EOF" >> /etc/sysupgrade.conf +
-/etc/firewall.ipset-save +
-/etc/firewall.ipset-restore +
-/etc/ipset.save +
-EOF +
-uci -q delete firewall.ipset +
-uci set firewall.ipset="include" +
-uci set firewall.ipset.path="/etc/firewall.ipset-restore" +
-uci set firewall.ipset.reload="1" +
-uci commit firewall +
-/etc/init.d/firewall restart +
- +
-# Populate and save IP sets +
-sh /etc/firewall.dnsmasq +
-sh /etc/firewall.ipset-save +
- +
-# Save IP sets daily +
-cat << "EOF" >> /etc/crontabs/root +
-0 0 * * * sh /etc/firewall.ipset-save +
-EOF +
-/etc/init.d/cron restart+
 </code> </code>
  
Line 182: Line 94:
 <code bash> <code bash>
 # Apply source restriction # Apply source restriction
-for FW_RULE in filter_fwd filter6_fwd+for IPV in 4 6
 do do
-uci add_list firewall.${FW_RULE}.src_mac="11:22:33:44:55:66" +uci add_list firewall.fwd_filter${IPV%4}.src_mac="11:22:33:44:55:66" 
-uci add_list firewall.${FW_RULE}.src_mac="aa:bb:cc:dd:ee:ff"+uci add_list firewall.fwd_filter${IPV%4}.src_mac="aa:bb:cc:dd:ee:ff"
 done done
 uci commit firewall uci commit firewall
-/etc/init.d/firewall restart+service firewall restart
 </code> </code>
  
 ==== Time restriction ==== ==== Time restriction ====
 [[docs:guide-user:firewall:fw3_configurations:dns_ipset#established_connections|Reorder firewall rules]] and enable time restriction to keep the rules active. [[docs:guide-user:firewall:fw3_configurations:dns_ipset#established_connections|Reorder firewall rules]] and enable time restriction to keep the rules active.
 +[[docs:guide-user:base-system:system_configuration#daylight_saving_time|Reload kernel timezone]] to properly apply DST.
  
 <code bash> <code bash>
 # Apply time restriction # Apply time restriction
-for FW_RULE in filter_fwd filter6_fwd+for IPV in 4 6
 do do
-uci set firewall.${FW_RULE}.start_time="21:00:00" +uci set firewall.fwd_filter${IPV%4}.start_time="21:00:00" 
-uci set firewall.${FW_RULE}.stop_time="09:00:00" +uci set firewall.fwd_filter${IPV%4}.stop_time="09:00:00" 
-uci set firewall.${FW_RULE}.weekdays="Mon Tue Wed Thu Fri"+uci set firewall.fwd_filter${IPV%4}.weekdays="Mon Tue Wed Thu Fri"
 done done
 uci commit firewall uci commit firewall
-/etc/init.d/firewall restart+service firewall restart
 </code> </code>
  
Line 211: Line 124:
 <code bash> <code bash>
 # Reorder firewall rules # Reorder firewall rules
-cat << "EOF" > /etc/firewall.estab +cat << "EOF" > /etc/nftables.d/estab.sh 
-for IPT in iptables ip6tables +ER_RULE="$(nft -a list chain inet fw4 forward 
-do ${IPT}-save -c -t filter +| sed -n -e "/\sestablished,related\saccept\s/p")" 
-| sed -e "/FORWARD.*ESTABLISHED.*ACCEPT/d; +RJ_RULE="$(nft -a list chain inet fw4 forward 
-/FORWARD.*reject/$(${IPT}-save -c -t filter +| sed -n -e "/\shandle_reject\s/p")" 
-| sed -n -e "/FORWARD.*ESTABLISHED.*ACCEPT/p")" \ +nft delete rule inet fw4 forward handle ${ER_RULE##} 
-${IPT}-restore -c -T filter +if [ -n "${RJ_RULE}" ] 
-done +then nft insert rule inet fw4 forward position ${RJ_RULE##* } ${ER_RULE} 
-EOF +else nft add rule inet fw4 forward ${ER_RULE} 
-cat << "EOF" >> /etc/sysupgrade.conf +fi
-/etc/firewall.estab+
 EOF EOF
 uci -q delete firewall.estab uci -q delete firewall.estab
 uci set firewall.estab="include" uci set firewall.estab="include"
-uci set firewall.estab.path="/etc/firewall.estab+uci set firewall.estab.path="/etc/nftables.d/estab.sh"
-uci set firewall.estab.reload="1"+
 uci commit firewall uci commit firewall
-/etc/init.d/firewall restart+service firewall restart
 </code> </code>
  
  • Last modified: 2023/11/17 09:13
  • by vgaetera