Create a virtual host for the forbidden domain.
It'll want it's own directory (which could be shared between multiple forbidden domains).
As the default content, use this index.php:
<?php
// contents of FORBIDDEN.YourDomain.com/index.php
// spits out one UDP packet at the web visitor's port 911
// the 911 packet is intended to be detected, processed and dropped with firewall rules
$remoteaddr = $_SERVER['REMOTE_ADDR'];
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_sendto($sock, "NOPE", 4, 0, $remoteaddr, 911);
socket_close($sock);
Now the firewall rule.
(A) first create a new ipset (timeout: 1 day = 86400 seconds)
/usr/sbin/ipset create ipset_temp_blocklist \
hash:ip \
family inet \
hashsize 4096 \
maxelem 65536 \
timeout 86400 \
counters \
comment
(B) then create a new iptables rule chain
/usr/sbin/iptables -N ADD_TEMP_BAN
(optional) chain rule 1: log the offending packet
/usr/sbin/iptables -A ADD_TEMP_BAN -j NFLOG --nflog-prefix "add-temp-ban="
chain rule 2: add the offender (the destination for the '911' UDP packet) to the blocklist ipset
/usr/sbin/iptables -A ADD_TEMP_BAN -j SET --add-set ipset_temp_blocklist dst
chain rule 3: end of chain rule: just drop the UDP packet
/usr/sbin/iptables -A ADD_TEMP_BAN -j DROP
(C) now make the new rulechain be called when we see an outgoing '911' UDP packet
/usr/sbin/iptables -A OUTPUT -p udp -dport 911 -j ADD_TEMP_BAN
(D) now to use the blocklist, add a rule to drop all incoming packets to web service from IP addresses listed
/usr/sbin/iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m set --match-set ipset_temp_blocklist src -j DROP
note this last rule does the following:
- append to the end of INPUT rule chain (you might want to put it earlier your rules)
- only applies to packets on interface 'eth0' (you might prefer 'all' or some other interface)
- only protocol tcp ('-p all' would block everything, pings, etc etc)
- only tcp packets going to ports 80 and 443 (you could add 8080 if you use that, etc)
- only packets whose source is in the blocklist
- DROP the packet.
You can list the blocked IPs like this:
/usr/sbin/ipset list ipset_temp_blocklist
Name: ipset_temp_blocklist
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536 timeout 864000 counters
Size in memory: 123880
References: 2
Number of entries: 1331
Members:
xx.35.112.155 timeout 528177 packets 4 bytes 240
xx.199.52.104 timeout 681175 packets 4 bytes 240
xx.230.7.65 timeout 490347 packets 4 bytes 240
xx.63.11.235 timeout 782713 packets 5 bytes 300
xx.159.102.65 timeout 351110 packets 1 bytes 40
xx.206.244.232 timeout 837758 packets 4 bytes 240
xx.162.105.161 timeout 490665 packets 3 bytes 180
And see the activity of the iptables chain like this (the numbers are [packets:bytes]):
/usr/sbin/iptables-save -c | grep -E "ADD_TEMP_BAN|ipset_temp_blocklist"
:ADD_TEMP_BAN - [0:0]
[1333:73200] -A OUTPUT -p udp -dport 911 -j ADD_TEMP_BAN
[1333:73200] -A ADD_TEMP_BAN -j NFLOG --nflog-prefix "add-temp-ban="
[1333:73200] -A ADD_TEMP_BAN -j SET --add-set ipset_temp_blocklist dst
[1333:73200] -A ADD_TEMP_BAN -j DROP
[5187:305169] -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m set --match-set ipset_temp_blocklist src -j DROP
Adjust to taste.