Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
| docs:guide-user:firewall:filtering_traffic_at_ip_addresses_by_dns [2022/05/01 20:18] – plinioseniore | docs:guide-user:firewall:filtering_traffic_at_ip_addresses_by_dns [2024/01/13 12:53] – [Improvements] plinioseniore | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== fw4 Filtering traffic with IP sets by DNS ====== | ====== fw4 Filtering traffic with IP sets by DNS ====== | ||
| - | {{section> | + | {{section> |
| ===== Introduction ===== | ===== Introduction ===== | ||
| Line 11: | Line 11: | ||
| ===== Prerequisites ===== | ===== Prerequisites ===== | ||
| - | - You need a firewall zone without forwarding to **wan**, so that no traffic to the internet is allowed by default | + | - You need a firewall zone without forwarding to **wan**, so that no traffic to the internet is allowed by default. Below this firewall zone is referenced as // |
| - Have **dig** and **grep** installed | - Have **dig** and **grep** installed | ||
| - | - Create a new interface (called //wildlan// in the below example) for which no forward is set in the firewall settings, so that only IP addresses in the //set// will be allowed | ||
| - Is assumed a standard fw4 configuration with //inet fw4// table | - Is assumed a standard fw4 configuration with //inet fw4// table | ||
| - | ===== Command-line instructions ===== | + | This wiki covers two cases, based on the //dnsmasq// running version. The //Case 1// applies only to //dnsmasq// 2.87 or greater. |
| - | In ///etc/rc.local// add the below code to create the **nft set** in which we will save the IP addresses, the proposed code is **ipv4** only but can be extended to cover **ipv6** | + | ===== [CASE 1] Command-line instructions ===== |
| + | |||
| + | Install // | ||
| + | |||
| + | <code bash> | ||
| + | opkg update; cd /tmp/ && opkg download dnsmasq-full; | ||
| + | opkg remove dnsmasq; opkg install dnsmasq-full --cache /tmp/; rm -f / | ||
| + | </ | ||
| + | |||
| + | Confirm the //dnsmasq// that is running with | ||
| + | |||
| + | <code bash> | ||
| + | opkg list-installed dns* | ||
| + | </ | ||
| + | |||
| + | A valid result should looks like // | ||
| + | |||
| + | In ///etc/hotplug.d/ | ||
| + | |||
| + | <code bash> | ||
| + | # Filter wildlan by IP addresses | ||
| + | ## Create a set for "inet fw4" table with name " | ||
| + | nft add set inet fw4 blackhole { type ipv4_addr \;} | ||
| + | nft insert rule inet fw4 forward_wildlan ip daddr @blackhole accept | ||
| + | </ | ||
| + | |||
| + | The //wildlan// zone has no access to internet unless the target IP address is listed in // | ||
| + | |||
| + | Edit **/ | ||
| + | |||
| + | <code bash> | ||
| + | # The IP address corresponding to allowed.url URLs will be saved in the nftset (/4# filters for ipv4) | ||
| + | nftset=/ | ||
| + | nftset=/ | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | Looking to the case in which you want to ensure that only IP addresses resolved via your DNS are allowed, then use # wildcard. This make sense if you want avoid access via direct IP without a filter for specific URLs. | ||
| + | |||
| + | <code bash> | ||
| + | nftset=/#/ | ||
| + | </ | ||
| + | |||
| + | The relevant IP address of the allowed URLs can be listed with the below command, the set will anyhow remain empty till any of the allowed URLs is resolved via // | ||
| + | |||
| + | <code bash> | ||
| + | nft list set inet fw4 blackhole | ||
| + | </ | ||
| + | |||
| + | ===== [CASE 2] Command-line instructions ===== | ||
| + | |||
| + | This applies only for //OpenWrt 22.03//, //OpenWrt 22.03.1// and //OpenWrt 22.03.2// that have an older release of // | ||
| + | |||
| + | In /// | ||
| <code bash> | <code bash> | ||
| Line 27: | Line 79: | ||
| ## Add element to " | ## Add element to " | ||
| for address in $(dig a -f / | for address in $(dig a -f / | ||
| - | nft add element inet fw4 blackhole {$address} | + | nft add element inet fw4 blackhole {$address |
| done | done | ||
| - | ## Allow packes in " | ||
| nft insert rule inet fw4 forward_wildlan ip daddr @blackhole accept | nft insert rule inet fw4 forward_wildlan ip daddr @blackhole accept | ||
| </ | </ | ||
| Line 47: | Line 98: | ||
| Based on this forward chain only the traffic with destination to the IP addresses included in @blackhole will be allowed. | Based on this forward chain only the traffic with destination to the IP addresses included in @blackhole will be allowed. | ||
| - | The //rc.local// is executed at boot time, so that @blackhole will be filled with IP addresses only at that stage. That **set** shall be periodically updated for two reasons: | + | The /// |
| 1. The IP addresses may change | 1. The IP addresses may change | ||
| 2. In case of DNS Load Balancing, the same DNS query will result in different IP addresses (all valid) based on time of request. | 2. In case of DNS Load Balancing, the same DNS query will result in different IP addresses (all valid) based on time of request. | ||
| Line 56: | Line 107: | ||
| </ | </ | ||
| - | In the /// | + | In the /// |
| <code bash> | <code bash> | ||
| ## Add element to " | ## Add element to " | ||
| for address in $(dig a -f / | for address in $(dig a -f / | ||
| - | nft add element inet fw4 blackhole {$address} | + | nft add element inet fw4 blackhole {$address |
| done | done | ||
| </ | </ | ||
| Line 78: | Line 129: | ||
| ===== Limitations ===== | ===== Limitations ===== | ||
| - | This approach will query periodically the DNS with all domains included in /// | ||
| - | With this type of approach the DNS query executed by a device that want to connect | + | In //CASE 1// any URL and sub-URL |
| - | ===== Further improvement ===== | + | In //CASE 2// the script will periodically query the DNS with all domains included in ///etc/sets-ipdns/wildlan-urls.list// so that list should be reasonably small. |
| - | If the goal is to enforce | + | |
| - | - List of the IP addresses served by the DNS into a //set// using a timeout on the entries | + | |
| - | | + | |
| - | This will require //dnsmasq 2.87// and // | + | ===== Next Improvements ===== |
| + | The command line instructions are included in /// | ||
| + | The rules will be reapplied at next change in status of any interface, that could also be trigged on purpose to rebuild the rules. | ||
| + | If in next released will be included a custom file for NFT commands that is trigged at any firewall rebuild, this problem will be solved. | ||