I would like to block sites using iptables
. How do I go about this, and how do I ensure that the iptables
rules are saved?
-
What linux distribution are you using?– PaulNov 16, 2011 at 0:45
-
I'm using the Gentoo Linux.– gustavosiqNov 16, 2011 at 0:55
-
Why not use /etc/hosts? cf. this– GeremiaAug 16, 2017 at 17:10
6 Answers
Blocking sites with iptables rules is a very bad idea, mainly because iptables (as most firewalls) deals with the IP addresses, and relationship between a site and its IP address(es) is rather loose:
One site can have many IP addresses, which can be changed rather frequently. Once iptables rules are created, even if you specify a site's name as part of a rule, the first IP address at that moment is used. If site's address changes, your iptables rules will be out of date.
One IP address can host many sites (and it happens often). This will only get more frequent, because of the IP address scarcity. If you block an IP address, you block all sites hosted on it.
So, even though other answers explain how you do it, I urge you to seek some other solution. For example, installing a transparent http proxy will achieve what you need. This transparent HTTP proxy HOWTO is a bit outdated, but it will help you get started.
Once you have a transparent proxy, you can add arbitrary rules to it to block specific sites, you don't even need to use the caching feature of squid, if you don't want it.
There are other ways to handle site blocking (other firewalls, proxies, etc.), but iptables rules is pretty much one of the worst possible ways to handle it.
-
This answer is no longer relevant due to @PetaspeedBeaver's answer below, which does not depend on addresses.– Purple PJun 28, 2020 at 7:28
You can use iptables string matching to achieve this:
iptables -A OUTPUT -p tcp -m string --string "block-me.com" --algo kmp -j REJECT
-A OUTPUT
adds the following rule to the OUTPUT
chain.
-m string --string "block-me.com" --algo kmp
tells iptables to look for the string block-me.com
using the Knuth-Morris-Pratt matching algorithm.
The easiest way to make your iptables are restored when you restart your machine is to install the package iptables-persistent
if available on your system. If you install the package after you set the new rules you will be asked if you want to save the presently used rules for permanent use. iptables-persistent
basically just loads the rules saved in files /etc/iptables/rules.v4
and /etc/iptables/rules.v6
.
If you change your rules again, to save changes and restore them at a reboot, you have to save them to the above mentioned files using the commands
iptables-save > /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v6
They will now be restored at a reboot.
Actually you don't need iptables-persistent
either. This question has another almost as simple solution.
Note that you need to run iptables-save
as root, or with sudo
like this:
sudo bash -c "iptables-save > /etc/iptables/rules.v4"
If you just run sudo iptables-save > /etc/iptables/rules.v4
you will get an "access denied" message for rules.v4
.
-
@artificerpi Hello, nice with your input, but I think you should make it a question if you want it answered. Have a good day! Aug 2, 2019 at 11:49
-
This will work fine for most sites, but
youtube.com
andgooglevideo.com
, which do not use TCP but UDP, cannot be blocked unless you substitute-p tcp
with-p all
.– Purple PJul 8, 2023 at 3:23
There are multiple way we can restrict https sites.
1- Squid Proxy
2- IPtables
With Squid Proxy Server
--> Open you squid configuration in my case (vim /etc/squid/squid.conf)
--> Place the rules as defined.
acl badsite dstdomain .facebook.com .soundcloud.com .playit.pk .songs.com
http_reply_access deny badsite # This line blocks HTTP
http_access deny CONNECT badsite # This Line block HTTPS
--> After this restart your squid
With Iptables Need to put rules as define here
iptables -N STREAM
iptables -I OUTPUT -m string --string "www.facebook.com" --algo bm --from 1 --to 600 -j STREAM
iptables -I OUTPUT -m string --string "facebook.com" --algo bm --from 1 --to 600 -j STREAM
iptables -I FORWARD -m string --string "www.facebook.com" --algo bm --from 1 --to 600 -j STREAM
iptables -I FORWARD -m string --string "facebook.com" --algo bm --from 1 --to 600 -j STREAM iptables -A STREAM -j REJECT
Under gentoo, to save the iptables rules you have added, use
/etc/init.d/iptables save
However, you'll also need to make sure that the iptables init script (whose purpose is to reload the rules) is run at boot:
rc-update add iptables default
Both commands should be run as root (via sudo if you have it installed)
ok, Lets say you want to block the IP address 192.168.1.5, just enter this at command prompt in your shell script:
iptables -A INPUT -s 192.168.1.5 -j DROP
Then you can block outoging IP address 192.168.1.2 from the server with this command:
iptables -A OUTPUT -d 192.168.1.2 -j DROP
and it should block that site from ever bothering you again. hope this helps.
-
Alright. And for save the rules ? For example to restart the machine, continue with the same rules. Without the rules is lost ? Thanks a lot! Nov 16, 2011 at 1:14
-
i think so, although i never quite got the hang of linux, and switched to mac OSX soon after. but from what i know, it should work. Nov 16, 2011 at 1:17
-
No, it won't without specifically stating the rules should be saved. The iptables command just tells the kernel to block various things. At boot, these commands would need to be replayed.– PaulNov 16, 2011 at 1:39
-
@thatguy - I edited out the
-p tcp
from your outgoing block, as it would only stop tcp packets outbound, rather than all packets.– PaulNov 16, 2011 at 1:45
-A INPUT -p tcp -m tcp -d www.facebook.com -j DROP
we just have studied it today
Debian 7
if you want to let them ping this site, just add --dport 80,443
after the name of the website