I am trying to filter the dns requests from my local network. Only authorize requests to specific dns and deny the rest, but it has not worked for me. This is my rule (with dns google example):
internal=enp2s1 external=enp2s0 iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT echo 1 > /proc/sys/net/ipv4/ip_forward # default 0 echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 # default 0 echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6 # default 0 echo 1 > /proc/sys/net/ipv6/conf/lo/disable_ipv6 # default 0 iptables -A INPUT -p all -i lo -j ACCEPT iptables -A INPUT -s 192.168.0.10 -j ACCEPT iptables -A OUTPUT -p all -o lo -j ACCEPT iptables -A OUTPUT -p all -s 127.0.0.1 -j ACCEPT iptables -t mangle -A PREROUTING -p all -i lo -j ACCEPT iptables -t mangle -A PREROUTING -p all -s 127.0.0.1 -j ACCEPT iptables -t nat -A PREROUTING -p all -i lo -j ACCEPT iptables -t mangle -A PREROUTING -i lo -s 127.0.0.0/8 -j ACCEPT iptables -t mangle -A PREROUTING -i lo -d 127.0.0.0/8 -j ACCEPT iptables -t mangle -A PREROUTING -i $internal -s 255.255.255.0/32 -j ACCEPT iptables -t mangle -A PREROUTING -i $internal -d 255.255.255.0/32 -j ACCEPT iptables -t mangle -A PREROUTING -i $internal -s 192.168.0.0/24 -j ACCEPT iptables -t mangle -A PREROUTING -i $internal -d 192.168.0.0/24 -j ACCEPT iptables -t mangle -A PREROUTING -p udp --dport 853 -j DROP iptables -t mangle -A PREROUTING -p tcp --dport 853 -j DROP dns="8.8.8.8 8.8.4.4" for ip in $dns; do iptables -A INPUT -s $ip -p udp --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT done iptables -A FORWARD -p udp --dport 53 -j REJECT
For example, if I put manually cloudflare dns on a PC on my local network (1.1.1.1 1.0.0.1) the PC has internet access
PD:
The rule “-m state –state RELATED,ESTABLISHED” is in this question selected as correctThe blocking rule is in this question selected as correct- I have tried the same blocking rule on all chains (INPUT, Mangle, OUTPUT, FORWARD) and change REJECT with DROP and it does not block
- I added additional blocking rules for src and it also does not block. Example:
iptables -A FORWARD -s $ip -p udp --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT # and block iptables -A FORWARD -p udp --sport 53 -j DROP
Note: These rules are also for TCP (but not to repeat them I do not put them)
Update:
I changed dns rule to:
dns="8.8.8.8 8.8.4.4" for ip in $dns; do iptables -A INPUT -s $ip -p udp --sport 53 -j ACCEPT iptables -A OUTPUT -d $ip -p udp --dport 53 -j ACCEPT iptables -A FORWARD -d $ip -p udp --dport 53 -j ACCEPT done iptables -A INPUT -p udp --sport 53 -j DROP iptables -A OUTPUT -p udp --dport 53 -j DROP iptables -A FORWARD -p udp --dport 53 -j DROP
But it doesn’t do the blocking correctly either
Note: INPUT rule with or without “-m state –state RELATED,ESTABLISHED -j ACCEPT” it is irrelevant because what interests me is to block the connection and it is what does not happen
thanks
Answer
Short summary
iptables -A OUTPUT -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
rules should be:
iptables -A OUTPUT -d $ip -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -j ACCEPT
Explanation
I’ll use client IP 192.168.100.100
and port 12345
as example.
When a client (192.168.100.100) in your network sends a DNS request, it sends a UDP packet from port 12345 to DNS server’s port 53.
When the packet goes via your Linux router box, the router creates a connection tracking entry for the DNS query. This connection tracking entry has multiple states, one of them ESTABLISHED
.
Now, in your original rules, you require ESTABLISHED
state for the first outgoing DNS query packets. In the example case, client 192.168.100.100
sending UDP packet from port 12345
to 8.8.8.8
port 53
, there is no ESTABLISHED
entry for that quintuple. Therefore the firewall drops the packet.
When the match state is removed from outgoing rules, then all outgoing packets to DNS server port 53 are approved, and connection tracking entry is created properly.
Then you can match the return direction using the -m state --state ESTABLISHED
, because the connection tracking entry exists.
Attribution
Source : Link , Question Author : acgbox , Answer Author : Tero Kilkanen