#!/bin/zsh
##
## autodisconnect
##
## Made by stransky
## Login stransky <stransky@crans.org>
##
## Started on  ven 25 jan 2002 22:24:26 CEST Nicolas STRANSKY
## Last update lun 03 nov 2003 07:38:51 CET Nicolas STRANSKY
##
## script de surveillance automatique de l'upload.
## à lancer par cron.

export LANG=fr_FR@euro

LIMITE_SOFT=100
LIMITE_HARD=700
MAIL_INTERVAL=100
LOG=/var/log/autodisconnect.log
LOGFILE=/var/log/net-acct/net-acct.log
outpF=$(mktemp)
TEMPFILE=/tmp/uploaders
LISTFILE=/tmp/liste
EMPREINTE_NEW=/tmp/empreinte-new
EMPREINTE=/tmp/empreinte
HABITUES=/tmp/habitues		# Liste des habitués du système
BLACKLISTES=/tmp/blacklistes
BLACKLISTES_NEW=${BLACKLISTES}-new
BLACKLISTE_ZAMOK=/var/zamok/CRANS/blacklist.cf
VERIF=0 # on envoie un mail à disconnect si VERIF=1
RENEW=1 # si cette valeur reste à 1 on vide le fichier empreinte.
date=$(date +%A\ %d\ %B\ %Y\ \ %T)
date2=$(date +%A\ %d\ %B\ %Y)
date3=$(date +%d-%m-%Y-%T)
DIR=/usr/scripts/analyse_komaz

# Si /tmp/exempts.pickle n'existe pas, on relance exempts.py
if [ ! -f /tmp/exempts.pickle ]; then
   $DIR/exempts.py
fi

# On renforce déjà la blacklist (au cas où le firewall a été relancé)
if [ -f $BLACKLISTES ]; then
    while read machine ; do
	if ! (/sbin/iptables -nL BLACKLIST_SRC | grep -q "^REJECT.*$machine "); then
    	    /sbin/iptables -I BLACKLIST_SRC -s $machine -j REJECT
		echo blacklist $machine
	fi
    done < $BLACKLISTES
fi

# Retourne l'adresse email correspondant à la machine donnée en paramètre
# Le premier paramètre est le nom de la machine en FQDN (lucas.crans.org)
getAdresseMail() {
    # Quel est l'adhérent de la machine ?
    aid=$(ldapsearch -LLL -H ldaps://sila.crans.org -x -D "cn=admin,dc=crans,dc=org" \
                -w $(cat /etc/ldap.secret)  -b "ou=data,dc=crans,dc=org" \
                host=$1 dn | head -1 | awk -F, '{print $2}')
    # On affiche son adresse email
    mail=$(ldapsearch -LLL -H ldaps://sila.crans.org -x -D "cn=admin,dc=crans,dc=org" \
                -w $(cat /etc/ldap.secret)  -b "ou=data,dc=crans,dc=org" $aid \
                mail | awk -F': ' '($1 ~ /^mail$/) {if ($2 ~ /@/) print $2; else print $2"@crans.org"}')
    if [[ -z $mail ]]; then
       echo disconnect@crans.org
    else
       echo $mail
    fi
}

echo $date > $LISTFILE
echo " " >> $LISTFILE

#/usr/scripts/analyse.pl -u -n 10 -f $LOGFILE --noperiod | egrep -v "zamok|komaz|sila" | \
                 #grep -v "Ko" | awk '{print $1" "$3}' | sed 's/Mo/ /g' | sed 's/\.[0-9]*Go/000 /g' > $TEMPFILE

$DIR/nacct.py -n -N 25| grep -v 'NoDNS_' > $outpF
if [ $? -eq 255 ]; then
    echo "Problème avec nacct.py : lock"
    exit 1
fi

cat $outpF | tail -25 | awk -F "|" '{print $1" "$7}' | egrep -v "136\.(1|2|3|4|6|8|9|10)$"  > $TEMPFILE

# Pour conserver un historique de la sortie de nacct.py
echo -e "\n$date" >> /tmp/nacct_history
cat $outpF >> /tmp/nacct_history

if ! grep -q "^===========================================================================" $outpF ; then
    echo "Pas de données ; problème avec nacct"
    exit 1
fi

rm $outpF

    while read upload machine ; do # On lit dans $TEMPFILE
	if ! (/sbin/iptables -nL BLACKLIST_SRC | grep -q "^REJECT.*$machine ") && [ $( echo $upload | cut -d '.' -f 1 ) -ge $LIMITE_SOFT ]
	    then # Si la machine dépasse la limite soft et n'est pas déjà blacklistée,
		RENEW=0 # on ne vide pas le fichier empreinte
		hostname=`host $machine | awk '/Name:/ {print $2}'`
		if  [ $( echo $upload | cut -d '.' -f 1 ) -ge $LIMITE_HARD ]
		   then
			/sbin/iptables -I BLACKLIST_SRC -s $machine -j REJECT
			echo blacklist $hostname
			echo "$hostname FIREWALISÉ ! ($upload Mo)" >> $LISTFILE
			echo "$date3 $hostname $upload" >> $LOG
			echo "$machine" >> $BLACKLISTES
			VERIF=1
			# Envoi d'un mail pour prévenir la personne (à modifier pour éventuellement utiliser sendmail)
			# On doit tester la variable EMAIL ?
			EMAIL=$(getAdresseMail $hostname)
			echo $EMAIL
			cat <<EOF | mail -s "Deconnexion temporaire de $hostname" -a "From: disconnect@crans.org" -a "Reply-To: disconnect@crans.org" $EMAIL
Bonjour,

Ta machine $hostname a été temporairement déconnectée parce que tu uploadais
une quantité importante de données. Tu recevras dans moins de 24h
un mail indiquant ta reconnexion. Tu as toujours accès au web ainsi qu'à tes mails
mais les autres services sont suspendus. Si cela se renouvelle trop souvent, tu
risques d'être déconnecté entièrement pour une durée plus importante. Il 
t'appartient donc de surveiller cela de plus près et de faire en sorte que ta 
machine n'uploade pas de manière excessive à l'avenir.

Pour plus d'informations, tu peux consulter la page:
http://wiki.crans.org/moin.cgi/VieCrans_2fD_e9connexionPourUpload
Si tu as des questions, contacte disconnect@crans.org
EOF
		elif ! (grep -q $hostname $EMPREINTE) # si la machine n'a pas encore été repérée par autodisconnect
		    then
			EMAIL=$(getAdresseMail $hostname)
			# On évince les habitués, ils reçoivent assez de mails comme ça
			if ! (grep -q $EMAIL $HABITUES); then
			    echo "$hostname uploade ($upload Mo)" >> $LISTFILE
			    echo "$hostname $upload" >> $EMPREINTE_NEW
			    VERIF=1 # Pas d'envoi de mail dans ce cas
			    cat <<EOF | mail -s "Ta machine $hostname uploade" -a "From: disconnect@crans.org" -a "Reply-To: disconnect@crans.org" $EMAIL
Bonjour,

Ta machine $hostname uploade une quantité importante de données vers l'extérieur 
(actuellement, $upload Mo). Si cela continuait, elle serait automatiquement 
déconnectée pour une durée d'environ 24 heures. Il t'appartient donc de 
surveiller cela de plus près et de faire en sorte que ta machine n'uploade pas 
de manière excessive à l'avenir.

Pour plus d'informations, tu peux consulter la page:
http://wiki.crans.org/moin.cgi/VieCrans_2fD_e9connexionPourUpload
Si tu as des questions, contacte disconnect@crans.org
EOF
			fi

		elif [ `echo $upload | cut -d '.' -f 1` -gt `echo $(cat $EMPREINTE | \
		       awk -v MACHINE=$hostname '$0 ~ MACHINE {print $2}')"/1+$MAIL_INTERVAL"|bc` ] 
		# si la machine a uploadé $MAIL_INTERVAL Mo de plus que la dernière 
		# fois qu'on a envoyé un mail à son sujet, on renvoie un mail.
		    then
			echo "$hostname uploade encore. ($upload Mo)" >> $LISTFILE
			echo "$hostname $upload" >> $EMPREINTE_NEW
		else # sinon on conserve les infos sur la machine
			cat $EMPREINTE | grep $hostname >> $EMPREINTE_NEW
		fi
	fi
    done < $TEMPFILE

    
if [ $RENEW -eq 1 ] ; then cat /dev/null > $EMPREINTE ; fi
if [ -f $EMPREINTE_NEW ] ; then mv $EMPREINTE_NEW $EMPREINTE ; fi

# Reconnexion des machines déconnectées

rm -f $BLACKLISTES_NEW
if [ -f $BLACKLISTES ]; then
    while read machine ; do
	# Est-ce que cette machine est toujours dans le TOP 12 ?
	
		# Juste pour vérifier où se situe le problème -- Nico
		echo "$machine firewalisé en est encore à : $(awk '($2 == "'$machine'") {print $1}' $TEMPFILE)"

	if ! (grep -q $machine'$' $TEMPFILE) || \
		[ $LIMITE_SOFT -ge $(awk '($2 == "'$machine'") {print $1}' $TEMPFILE | cut -d '.' -f 1 ) ]; then
	    VERIF=1
	    # On doit la reconnecter : on la vire de BLACKLISTES
	    grep -v $machine $BLACKLISTES > $BLACKLISTES_NEW
	    hostname=`host $machine | awk '/Name:/ {print $2}'`
	    # Reconnexion
	    if ! (grep -q "^$(echo $hostname | cut -f1 -d.)" $BLACKLISTE_ZAMOK )
	        then # Si la machine est blacklistée sur zamok on ne reconnecte pas
		    /sbin/iptables -D BLACKLIST_SRC -s $machine -j REJECT
		    echo "La machine $hostname a été reconnectée. ($(awk '($2 == "'$machine'") {print $1}' $TEMPFILE) Mo)" >> $LISTFILE
		    EMAIL=$(getAdresseMail $hostname)
		    cat <<EOF  | mail -s "Reconnexion de $hostname"  -a "From: disconnect@crans.org" -a "Reply-To: disconnect@crans.org" $EMAIL
Bonjour,
    
Ta machine $hostname avait été temporairement déconnectée, elle est maintenant
reconnectée. Vérifie que tu ne fais plus d'upload pour éviter de te faire
déconnecter une nouvelle fois.
EOF
	        else
		    echo "La machine $hostname reste blacklisstée sur zamok. ($(awk '($2 == "'$machine'") {print $1}' $TEMPFILE) Mo)" >> $LISTFILE
	    fi
	    echo reconnexion $machine
	fi
    done < $BLACKLISTES
fi

# Bug, on n'enlève qu'une machine à chaque fois, pas trop grave
if [ -f $BLACKLISTES_NEW ]; then cat $BLACKLISTES_NEW > $BLACKLISTES; fi
# Eventuellement, appel de firewall blacklist si on n'a pas encore reconnecté

if [ $VERIF -eq 1 ] 
	then
	echo -e "\n-- \ncréé par autodisconnect."  >> $LISTFILE

	cat $LISTFILE | /usr/bin/mail -s "upload temps réel - $date2"  -a "From: disconnect@crans.org" -a "Reply-To: disconnect@crans.org" pessoles@crans.org
fi

exit 0
