Suppose I want to block Facebook permanently. To do this, I have followed following processes:

#host -t a www.facebook.com

Sample output:

www.facebook.com has address


#whois | grep CIDR

Sample output:


To prevent outgoing access to www.facebook.com

Approach 1:

#iptables -I FORWARD -p tcp -d -j DROP

Approach 2:

#iptables -I FORWARD -p tcp -d www.facebook.com -j DROP

Both Approaches work well. In approach 1, IP address may be changed so it will not block Facebook permanently. I don't know about approach 2 whether it will block Facebook permanently or not. If above approaches are not right way to block a domain permanently, how can I do it?

  • 3
    Your second option will not do what you want. DNS names are resolved by iptables when the rules are added to the tables. DNS is not used any time after the rules have been added.
    – Zoredache
    Commented Feb 16, 2012 at 8:12

5 Answers 5


Using squid following thing if you use it do the same.

# Mon to Fry time
acl blockfacebooktime time MTWHF 8:30-8:30
# Domain name
acl blockfacebookdotcom  dstdomain .facebook.com
  • 2
    +1, this is the way to do it. There just no way that you can do it at the iptables level.
    – Zoredache
    Commented Feb 16, 2012 at 8:11

Approach 2 will NOT work as you may think. You can read this from iptables manual:

[!] -s, --source address[/mask]
          Source specification. Address can be either a network name, a hostname (please note that specifying any name to be resolved with a remote query  such
          as  DNS  is  a  really bad idea), a network IP address (with /mask), or a plain IP address.

Of course, the same applies on destination option -d. This is because iptables will do DNS lookup only once and use the retrieved IP in the rule. So, it will not work if the IP is changed after that.

A better approach is to use a proxy server as suggested by @neolix. However, your users can try to bypass your proxy unless you are have really strict rules to prevent this.


I achieved the same by redirecting the host to a local IP.

Edit /etc/hosts and add something like this (non-routing IP):      www.facebook.com

Many Thanks to Малъ Скрылевъ !

ipfacebook=$(nslookup www.facebook.com|grep "^Address: [1]"| sed "s/Address://")

sudo iptables -A OUTPUT -d $ipfacebook -j DROP

sudo iptables -A FORWARD -d $ipfacebook -j DROP

This also worked for microsoft.com.


Your are able to use autoscripting chain to block all the IPs for the domain. i.e. just list all the IPs for the domain and block them one-by-one. If the IP already exists in the table, insertion will be just skipped. Do as following:

# nslookup www.facebook.com|grep "^Address: [1-9]"| while read l; do ip=$(sed "s/Address://" <<< "$l"); if [ -z "$(iptables -n -L FORWARD|grep $ip)" ]; then iptables -I FORWARD -j DROP -d $ip; echo Blocked $ip; fi; done

This script can be called from a cron, for example each minute/hour, to renew the addresses.

  • That rather assumes that all the IP addresses to which a domain name can lawfully resolve are returned on a single lookup, which isn't even close to true for some organisations. Try resolving 0.pool.ntp.org to see how fast things change.
    – MadHatter
    Commented Apr 17, 2017 at 7:55
  • @MadHatter not so quickly, but I found out that the pool of addresses is quite stable (and has about 8 records) =) Also I've updated answer Commented Apr 17, 2017 at 9:04
  • It's the wrong way to do it. As Zoredache says above, doing layer-4 filtering with a layer-3 tool will lead to all sorts of horrible kludges (such as yours). Neolix's answer is the right one.
    – MadHatter
    Commented Apr 17, 2017 at 10:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .