Ipset block voor China

denkenInleiding

Enige tijd geleden heb ik een artikel (Blacklist met iptables) geschreven over het gebruik van iptables om een blacklist te maken.  Dit werd weer actueel omdat mijn vriendin (je weet wel… van HappyMinds) zich meer en meer ging ergeren aan de “bezoekers” uit China en Rusland. Er is een meer dan sterk vermoeden dat die alleen maar langs komen voor rottigheid, temeer omdat haar site slechts heel beperkt te lezen is in een andere taal dan Nederlands. De bedoeling is dan ook om een uitbreiding te maken op de blacklist door een ipset block te maken voor bijvoorbeeld China.

Komt bij dat ik overgestapt ben (weer terug naar eigenlijk) naar Ubuntu als server platform. Een leuke gelegenheid om de verschillen eens te bekijken.

chinese hackerHet idee

In het vorige artikel beschreef ik hoe je van een lijst met IP nummers een ipset tabel kan maken die vervolgens weer gebruikt kan worden in een iptables firewall.

Om landen/regio’s te blokkeren volstaat het niet om elk IP nummer van dat land op te nemen in een lijst. Je kunt dan veel beter uit de voeten met een lijst van subnetten.  De mensen van IpDeny zijn zo vriendelijk om per landcode lijsten met subnet nummers te publiceren.  Deze lijst kun je vervolgend – net als de IP nummers uit het vorige artikel – toevoegen aan een ipset tabel.

ipsetDe uitvoering

Het script om de lijst met subnetten te downloaden en in een ipset tabel te zetten lijkt heel erg op het script uit het vorige artikel. Er zijn slechts een paar kleine verschillen. Bij mij heet het script make_zone_blacklist.sh, als je andere naam kiest vergeet dan niet om dit ook aan te passen in het firewall script. De landcodes die gebruikt worden kunnen bij Ipdeny opgezocht worden.

#! /bin/bash

# make_zone_blacklist
# load the zone blacklist for an iptables based firewall
# Written by Peter Kaagman <prjv.kaagman@gmail.com>;
# version 1.0.0 20150718

# Set the path so you know which executable you run
# being paranoid?
PATH=/usr/bin:/usr/sbin:/sbin:/bin
# The base url for the list at ipdeny
url=http://www.ipdeny.com/ipblocks/data/countries
# The zones we are going to deny access
zones="cn ru"

function load_blacklist {
  #
  # Load the blacklist in a copy list
  ipset destroy zone_blacklist2 >& /dev/null # destroy is if needed
  ipset create zone_blacklist2 hash:net # (re)create it
  #
  # Iterate the zones
  for zone in $zones
  do
    # Download the new list
    # and itterate it
    for CIDR in `wget -q $url/$zone.zone -O -|grep -v ^#`; do
      # add the ip to the newly created blacklist2
      ipset add zone_blacklist2 $CIDR
    done
  done
  #
  # Swap this list with the excisting one
  # The list blacklist should be created by you iptables script
  ipset swap zone_blacklist zone_blacklist2
  #
  # Remove zone_blacklist2
  ipset destroy zone_blacklist2
}

#echo Creating blacklist
load_blacklist

Ook dit script (make_zone_blacklist) gaat er vanuit dat de ipset tabel (zone_blacklist) al bestaat. Deze moet weer in het firewall script aangemaakt worden.

Er zijn wat kleine verschillen:

  • Het type van ipset tabel is anders om subnetten te kunnen bevatten in plaats van IP nummers.
  • Uiteraard is de bron van de lijst anders
  • De mogelijkheid om verschillende landcode’s te downloaden is ingebouwd

iptablesHet firewall script

Ook deze keer voeg ik wat regels toe aan mijn firewall script om de ipset tabel te kunnen gebruiken. Achtereenvolgens:

Een variabele toevoegen voor het laden van de tabel

iptables=/sbin/iptables
ipset=/sbin/ipset
make_blacklist=/home/pkn/scripts/bash/firewall/make_blacklist.sh
make_zone_blacklist=/home/pkn/scripts/bash/firewall/make_zone_blacklist.sh
int_if=eth0			# internal (local) interface, e.g. eth0
int_ip=192.168.178.2		# internal (local) IP, e.g. 192.168.1.94

Ik werk vaak met dergelijk variabelen. Als ik het script nog eens verplaats hoef ik maar 1 regel code aan te passen. Als je dit script gebruikt dan zul je dit zeker aan moeten passen aan jouw situatie.

De ipset tabel maken en de filter regels

# default policy
$iptables -P INPUT   DROP
$iptables -P FORWARD DROP
$iptables -P OUTPUT  DROP

# drop zone_blacklist
# first create the ipset zone_blacklist
# make_zone_blacklist assumes it excists
$ipset create zone_blacklist hash:net >& /dev/null
# no network at the moment,
# so we load the list later on

# log on match
$iptables -A INPUT -m set --match-set zone_blacklist src -p TCP -j LOG --log-prefix 'Zone_BlackListed '
# and drop on match
$iptables -A INPUT -m set --match-set zone_blacklist src -p TCP -j DROP

# drop blacklist
# first create the ipset blacklist
# make_blacklist assumes it excists
$ipset create blacklist hash:ip >& /dev/null
# no network at the moment,
# so we load the list later on

# log on match
$iptables -A INPUT -m set --match-set blacklist src -p TCP -j LOG --log-prefix 'BlackListed '
# and drop on match
$iptables -A INPUT -m set --match-set blacklist src -p TCP -j DROP

# drop broadcast (do not log)

Ik heb er voor gekozen om eerst de zone_blacklist te droppen. Dit omdat die lijst de meeste kans heeft om succesvol te zijn. In het kader van “zo snel mogelijk ongewild verkeer droppen” dus.

De ipset tabel laden

# log all the rest before dropping
$iptables -A INPUT   -j LOG --log-prefix "IN "
$iptables -A INPUT   -j REJECT --reject-with icmp-port-unreachable
$iptables -A OUTPUT  -j LOG --log-prefix "OU "
$iptables -A OUTPUT  -j REJECT --reject-with icmp-port-unreachable
$iptables -A FORWARD -j LOG --log-prefix "FW "
$iptables -A FORWARD -j REJECT --reject-with icmp-port-unreachable

# firewall loaded, so lets load the blacklists
echo "Loading blacklist"
$make_blacklist
echo "Loading zone_blacklist"
$make_zone_blacklist

Het laden van de blacklists doe ik direct na het logging blok van het firewall script. Op dat punt zullen alle verbindingen die we willen toestaan weer mogelijk zijn.

ubuntu bootingEen reboot overleven

In het vorige artikel heb ik al uitgelegd hoe de firewall een reboot op een CentOS systeem kan overleven. Het kwam er eigenlijk op neer dat er een stukje script uitgevoerd wordt zodra de interface online komt. In Ubuntu is dat eigenlijk niet anders… al is de uitvoering op een Ubuntu systeem – naar mijn mening – eenvoudiger. ubuntu heeft een directory (/etc/network/if-up.d) waar je een script kunt neerzetten. Alle scripts in die directory worden uitgevoerd als de interface online komt, als het goed is staan er al een paar. Ik heb het volgende script in die directory neergezet:

#! /bin/bash

/home/pkn/scripts/bash/firewall/firewall.sh start

Ik heb het firewall genoemd en executable gemaakt.
Voor de refresh van de blacklist kun je hetzelfde script in de directory /etc/cron.daily zetten. De firewall wordt dan dagelijk opnieuw geladen en de blacklists dus ververst. Eventueel kun je er voor kiezen om via cron alleen de scripts voor de blacklists te verversen. De firewall blijft in dat geval geladen.

reflectieZijn we nu dan klaar?

Nou… ik weet weinig dingen zeker… maar ik weet wel zeker dat je nooit helemaal klaar bent. Met dit soort filters loop je eigenlijk altijd achter de feiten aan. Dus nee… we zijn niet klaar.
Spamhaus heeft twee lijsten die wel interessant lijken: drop en edrop. Ik wil eens gaan kijken of ik die kan implementeren. Daarnaast lijkt het analyseren van log bestanden me altijd nog een leuke optie. Maar eerst ga ik maar eens werken aan kijken hoe effectief het gene is wat ik nu heb. Iets met Tobi Oetiker zijn bibliotheek: ik ben een regelrechte junk voor wat betreft statistieken :D.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *