Preferably something similar to iptables. Basically, I want to do domain filtering/whitelisting/blacklisting like I would with IPs in iptables. Are there any recommendations on how to do this?
-
what/why are you trying to block? Are you trying to filter outgoing/incoming HTTP or SMTP or NTP? Different tools can be used for different scenarios. – Creek Jun 18 '14 at 19:37
-
1Couple of suggestions that might help you are http://denyhosts.sourceforge.net/faq.html and http://www.fail2ban.org/wiki/index.php/Main_Page. – Ramesh Jun 18 '14 at 19:44
-
1@josten ideally you would use an HTTP proxy like [Squid](http://www.squid-cache.org/). Blocking domain names in `iptables` can be [done](https://www.webhostingtalk.com/showthread.php?t=1055023) but it may be dicey – Creek Jun 18 '14 at 19:58
5 Answers
If you drop traffic using name resolution with iptables rules, the names will be resolved during the creation of that rule. If something change, you rule will not be valid anymore. This could be a solution(not a beautyfull one...):
# iptables -I FORWARD -p udp --dport 53 -m string --hex-string "|03|www|08|facebook|03|com" --algo bm -j DROP
From another host inside the LAN:
# host www.facebook.com
www.facebook.com A record not found, try again
Basically, your are saying to every dns packet(udp/53) that have the hexadecimal string of www.facebook.com to be dropped. Note that this will drop name resolution, and not the http traffic itself.
The hex numbers separated with pipes(|03|www|08|facebook|03|com) are the representation of the dot. simbol on dns queries. It will say how many of the following charaters will represent each part of a FQDN(host, domain, top-level domain) Example:
host: mail.google.com
hex representation: 04 6d 61 69 6c 06 67 6f 6f 67 6c 65 03 63 6f 6d
"visual" representation: 04mail06google03com
Getting the packet with tcpdump:
# tcpdump -i eth0 -X dst port 53
15:50:11.643672 IP xxx.xxx.xxx.xxx:xxx > ns4.google.com.domain: 16530 A? mail.google.com. (33)
0x0000: 4500 003d 779a 4000 4011 b390 c949 4742 E..=w.@[email protected]
0x0010: d8ef 260a 8424 0035 0029 0fc0 4092 0000 ..&..$.5.)..@...
0x0020: 0001 0000 0000 0000 046d 6169 6c06 676f .........mail.go
0x0030: 6f67 6c65 0363 6f6d 0000 0100 01 ogle.com.....
But, remember:
- If your are trying to filter more specific traffig like smtp, ftp or http, a proxy of that protocol should be better.
- You are "hijacking" dns queries and not blocking the domain. Users are not that dumb ;)
-
-
Algorithm Boyer-Moore - https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm – Oct 02 '17 at 23:14
Maybe the answer to your question is too late, but recently I needed to solve a similar problem and google brings me here
After unsuccessful searches I wrote a small utility in C that intercepts DNS-responses, compares the domain name in it against given regex and lists matched IP addresses. Here it is: https://github.com/vmxdev/sidmat/
You don't need to set up your own DNS server, utility can catch DNS responses from any server
For example, to see facebook.com (and subdomains) ip addresses which are resolved right now you can run
# ./sidmat eth0 "^facebook\.com$|\.facebook\.com$"
173.252.120.6
...
where eth0 is network interface on router (or where DNS responses pass)
You can easily integrate it with iptables (or iptables with ipset)
But:
- utility is really simple. It does not performs many checks, so attacker can cheat it
- this technique is useless if users do not use DNS for name resolution
- 51
- 1
- 1
-
This is a cool little app. (with a few bugs, but still, very informative). One problem with DNS, though, is that it could have been cached. And as you mentioned, some DNS requests are now done through HTTPS. – Alexis Wilke Nov 10 '20 at 21:12
For blacklisting easiest way is probably to use dnsmasq
Install dnsmasq
$ sudo apt-get install dnsmasq
and add this line to /etc/dnsmasq.conf
address=/facebook.com/127.0.0.1
This will block facebook.com and all its subdomains.
Note: For ubuntu see this post.
- 1,475
- 15
- 15
If running a local caching bind9 it is often realized by a dummy-block
zone "facebook.com" { type master; file "dummy-block"; };
and the dummy-block file:
$TTL 604800
@ IN SOA localhost. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
@ IN A 127.0.0.1
* IN A 127.0.0.1
See also:
Running BIND9 and ISC-DHCP with facebook.com example.
For block badomain.com add these lines to /etc/hosts:
127.0.0.1 badomain.com
It will force badomain.com use local IP (127.0.0.1) instead of IP from DNS server
- 1