Nov 032010
 

FirewallIn rete ci sono molte guide relative ad iptables, il firewall incluso in tutte le ultime distribuzioni Linux, ma per parlare di iptables bisogna anche comprendere Netfilter.

Netfilter è un componente del kernel del sistema operativo Linux, che permette l’intercettazione e manipolazione dei pacchetti che attraversano il computer. Netfilter permette di realizzare alcune funzionalità di rete avanzate come la realizzazione di firewall basata sul filtraggio stateful dei pacchetti o configurazioni anche complesse di NAT, un sistema di traduzione automatica degli indirizzi IP, tra cui la condivisione di un’unica connessione Internet tra diversi computer di una rete locale, o ancora la manipolazione dei pacchetti in transito.



Per configurare netfilter si usa il programma iptables, che permette di definire le regole per i filtri di rete e il reindirizzamento NAT. Spesso con il termine iptables ci si riferisce all’intera infrastruttura, incluso netfilter.

Per una guida base di iptables vi suggerisco l’ottima guida di Ubuntu: https://help.ubuntu.com/community/IptablesHowTo

In questo articolo proverò a mostravi qualche utilizzo unusuale del comando.

Compito 1 bloccare host compromessi dal raggiungere la vostra macchina

wget -qO - http://infiltrated.net/blacklisted|awk '!/#|[a-z]/&&/./{print "iptables -A INPUT -s "$1" -j DROP"}'

Blacklisted è un elenco compilato di tutti gli host compromessi noti (botnet, spammer, bruteforcers, ecc) che viene aggiornato su base oraria. Questo comando ottiene l’elenco e creare le regole per te, se vuoi li blocca automaticamente, aggiungendo un |sh alla fine della riga di comando. Una soluzione più pratica è quella di bloccare tutti gli host e consentire solo quelli noti, ci sono molti che non hanno o non possono fare questo, e per loro questo script sarà utile.

Compito 2 sbloccare una certa porto dopo che si è bussato

knock < host > 3000 4000 5000 && ssh -p
user@host && knock < host > 5000 4000 3000

In questo esempio non si vede l’utilizzo diretto di iptables, ma iptables si utilizza nel file di configurazione di knockd.
Il requisito è quindi quello di installare knockd.

Ecco un file di configurazione di esempio per sshd (porta 22):

[options]
logfile = /var/log/knockd.log
[openSSH]
sequence = 3000,4000,5000
seq_timeout = 5
command = /sbin/iptables -A INPUT -i eth0 -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 5000,4000,3000
seq_timeout = 5
command = /sbin/iptables -D INPUT -i eth0 -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn

Compito 3 Fare una redirezione da una porta alta alla porta 80

iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-port 9001

Questo è veramente utile quando si vuole dare ad un normale utente la possibilità di eseguire un demone su una porta alta, ma mostrando il servizio su una porta standard. In questo esempio si può dare a un utente normale la possibilità di fare avvio/arresto di un apache che ascolto sulla porta 9.001, mostrando il sito web relativo sulla porta 80.

Compito 4 usare il proxy solo per IP non nella propria rete privata

iptables -t nat -A OUTPUT -d ! 10.0.0.0/8 -p tcp --dport 80 -j DNAT --to-destination 10.1.1.123:3128

Rimpiazzate 10.0.0.0/8 con la vostra rete privata. Rimpiazzate 10.1.1.123:3128 con l’ip del vostro proxy. Attenzione, questo funziona solo per proxy configurati per funzionare con un setup passivo.

Adesso il vostro firefox andrà in maniera trasparente sul vostro proxy, per oggetti fuori dalla vostra rete privata, mentre non lo utilizzerà per tutto ciò che è nella vosta intranet.

Compito 5 – Limitare a 10 il numero di connessioni SSH

/sbin/iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 10 -j REJECT

Con questo codice potete limitare il numero di accessi ad una determinata porta, può essere utile anche per limitare il numero di connessioni verso una certa porta di apache con :

/sbin/iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 -j REJECT --reject-with tcp-reset

Compito 6 – Limitare ad 1 connessione ogni 15 secondi ssh

iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT

Queste due regole di iptables richiedono 15 secondi tra le nuove connessioni dallo stesso IP sulla porta 22 (la porta di SSH). Usate ACCEPT se si utilizza un firewall che ha la propria regola per accettare le connessioni ssh.

Compito 7 Dare più direttive con un unico comando

iptables -A INPUT -p tcp -m multiport --dports 22,80,143,6000:6003 -j ACCEPT

Il modulo multiport di iptables vi permette di indicare con un unico comando più porte di destinazione a cui applicare una regola.
Questo permette di avere una manutenzione molto più facile delle nostre configurazioni e meno consumo di CPU.

Popular Posts:

Flattr this!

  8 Responses to “7 Usi non comuni di Iptables”

  1. The black list isn’t that comprehensive, because most of the spam still gets through. Having a script that puts each IP address in its own command, instead of using the comma separator makes iptables unnecessarily long. Analyzing a month worth of data only provides 2 unique matches against this list on port 25. Checking all incoming traffic only has about 18 unique matches in a month.
    iptables –list
    now takes a crazy amount of time because we didn’t list at least 5 ip’s per line
    iptables.save is now 30000+ lines long because of above.

    script doesn’t integrate well with an existing rules set.
    If this could be worked into an integrated script/process and then use cron to download it once an hour that would be awesome.

  2. the firewall starting using 100% of the cpu and my bandwidth dropped in half with 3ghz of cpu processing power. Doesn’t anybody verify these tips are good idea before sharing them with others.

  3. The listed usages are not “uncommon”.

    • Thanks forr the visit,
      And well the “common” use it’s, for me, the plain firewall usage that most of the people do of Iptables…wait no, most of the people don’t even use it 😉

      Bye

  4. […] Have you ever wanted to block brute force attacks, blacklist IP addresses, send “knocks” to open secret ports on your server, reroute port 9001 to 80, limit the number of connections to a port, or limit the amount of time a port is open? Iptables can do all of this and more. […]

  5. I was really motivated by your blacklist example. ipset(8) is really fast in comparison to blocking individual IP CIDRs or IP addresses. Here are my iptables rules for working with the ipset:
    iptables –new-chain BLACKLISTLOG
    # create the ipset so the below iptables rules work
    ipset create -exist BLACKLIST_DROP hash:ip 2>/dev/null
    # ensure no incoming packets are in the hash:ip space
    iptables –append INPUT –in-interface $IN –match set –match-set BLACKLIST_DROP src –jump BLACKLISTLOG
    iptables –append BLACKLISTLOG –match limit –limit 1/s –jump LOG –log-prefix “[BLACKLIST] ”
    iptables –append BLACKLISTLOG –jump DROP
    Here is my cron script to create the BLACKLIST_DROP ipset … it installs the blacklist above in about 60 seconds
    on my firewall:
    // —- start installIpsetFromNet.sh
    #!/bin/bash
    ###############################################################################
    # File:
    #
    # Description:
    #
    # History:
    # Brian Micek – March 2012
    ###############################################################################

    readonly ME=$( basename $0 )

    # —————————————————————————–
    # – help() – prints help
    # —————————————————————————–
    function help() {
    cat – <<EOF
    $ME $ME
    NAME
    $ME – Installs an ipset(8) address space in your kernel for iptables(8)

    SYNOPSIS
    $ME list-URL kernel-list-name [hash:net|hash:ip]

    TYPICAL USAGE
    $ME "http://www.ipdeny.com/ipblocks/data/countries/us.zone&quot; \\
    "us_cidrs" hash:net

    DESCRIPTION
    This bash script installs an ipset(8) IP address space in your kernel. The
    purpose of an ipset address space is to discriminate (typically incoming)
    IP packets against the list for ACCEPT, REJECT or DROP dispositions

    OPTIONS
    None

    NOTES:
    Logging by this program is sent to syslog(8) and also stderr.
    $ME $ME
    EOF
    }
    # —————————————————————————–
    # – log() – delivers log messages to stderr and syslogd
    # —————————————————————————–
    function log() { #<– variable arguments for logging
    logger -s -t $ME $@
    }

    # —————————————————————————–
    # – getList() – gets an IP or CIDR list from the net
    # —————————————————————————–
    function getList() { #<– 1 argument of URL
    log Fetching and parsing $@
    wget -qO – $@ |
    awk -F "." '/^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/ {
    if ( NF == 4 ) {
    for ( i = 1; i = 1 ) {
    if ( ar[ 1 ] 255 ) {
    next
    }
    }
    if ( n >= 2 ) {
    if ( ar[ 2 ] 32 ) {
    next
    }
    }
    }
    print
    }
    }’
    }

    # —————————————————————————–
    # – appendList() – Inserts rules into the custom chain to accept and log
    # – the candidate IP address
    # —————————————————————————–
    function appendList() { #<– 2 arguments, list-name, cidr
    local listname=$1
    local cidr=$2
    ipset add -exist $listname $cidr
    return $?
    }
    # —————————————————————————–
    # – addList() – Reads records from stdin and add them to the ipset IP space
    # —————————————————————————–
    function addList() { #<– 2 args, type and name
    local type=$1
    local name=$2

    readonly TEMP_SET=TEMP_$2
    log Creating temporary ipset $TEMP_SET
    ipset create -exist $TEMP_SET $type
    # in case it already existed, flush it
    ipset flush $TEMP_SET

    local c=0
    # Insert each successful CIDR into iptables. W
    while read cidr
    do
    c=$[ $c + 1 ]
    local v=$[ c % 1000 ]
    if [ $v -eq 0 ]
    then
    log Installed $c rules on $TEMP_SET
    fi
    appendList $TEMP_SET $cidr
    if [ $? -ne 0 ]
    then
    log List append error
    break
    fi
    done
    if [ $c -gt 1 ]
    then
    log Finished, installed $c CIDRs on $TEMP_SET
    log Swapping new list $TEMP_SET with $name
    ipset swap $TEMP_SET $name
    if [ $? -ne 0 ]
    then
    # Probably this is the first time this program was run
    # and the destination does not exist yet.
    log IP set doesnt apprear to exist, renaming
    ipset rename $TEMP_SET $name
    if [ $? -ne 0 ]
    then
    log ERROR ERROR ERROR issuing ipset swap $TEMP_SET $name $type
    # I'm not quite sure what to do here, most likely the
    # new set was created with a differing type
    exit 1
    fi
    else
    # else the swap worked and TEMP_SET now holds old data
    log Flushing old data in $TEMP_SET
    ipset flush $TEMP_SET
    log Deleting old data in $TEMP_SET
    ipset destroy $TEMP_SET
    fi
    else
    # Else we were not able to install any darn rules
    log ERROR did not install any rules destined for $name
    # Leave the old chain intact and flush and delete TEMP_SET
    log Flushing old data in $TEMP_SET
    ipset flush $TEMP_SET
    log Deleting old data in $TEMP_SET
    ipset destroy $TEMP_SET
    fi
    log $( ipset list -terse $name )
    }
    # —————————————————————————–
    # MAIN
    # —————————————————————————–
    # installChain "http://www.ipdeny.com/ipblocks/data/countries/us.zone&quot; "us_cidrs" hash:net
    #
    if [ $# -lt 2 ]
    then
    help
    exit 1
    elif [ $# -eq 2 ]
    then
    type="hash:net"
    else
    type=$3
    fi
    case "$type" in
    "hash:net") ;;
    "hash:ip") ;;
    *) help ;;
    esac
    url="$1"
    name="$2"
    start=$( date +%s )
    installChain $type $url $name
    stop=$( date +%s )
    delta=$[ $stop – $start ]
    log Finished, took $delta seconds for $name

    // —- end installIpsetFromNet.sh

    Now in /etc/cron.daily, something like this will update the blacklist every night
    installIpsetFromNet.sh http://infiltrated.net/blacklisted BLACKLIST_DROP hash:ip

  6. I’m sorry about the indentation, whitespace was stripped from my upload

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*