2010/04/30

Permission de sortie : 30 minutes

Le Besoin

Les ingrédients

Recette

PF

scrub in all
set skip on lo0
pass out all
block in all
table <allowips> persist
pass in quick inet proto tcp port https keep state
pass in quick inet proto tcp from <allowips> to port 8080 keep state

Voila tout simple tout beau, en gros on bloque tout sauf le https. On autorise toutes les ips qui sont contenu dans la table allowips

Problème : comme rajouter des adresses IPs dans la table allowips et surtout comment les supprimer au bout de 30 minutes

CGI shell

Nous créons donc un script cgi qui après une authentification "ultra basique" ajoutera l'adresse IP du demandeur dans la table allowips et schedulera la supression de celle ci

#!/bin/sh
if [ "$REQUEST_METHOD" = "POST" ];then
	query="dd count=$CONTENT_LENGTH bs=1 2> /dev/null"
else
	echo "Bad request"
	return
fi

# Ceci n'est pas super clean, il y a mieux à faire mais flemme :)
eval $query

if [ -z $passwd ]; then
	echo "Bad request"
	return
fi

decodedpasswd=$(echo $passwd | awk '"'BEGIN{for(i=0;i<10;i++)hex[i]=i;hex["A"]=hex["a"]=10;hex["B"]=hex["b"]=11;hex["C"]=hex["c"]=12;hex["D"]=hex["d"]=13;hex["E"]=hex["e"]=14;hex["F"]=hex["f"]=15;}{gsub(/\+/," ");i=$0;while(match(i,/%../)){;if(RSTART>1);printf"%s",substr(i,1,RSTART-1);printf"%c",hex[substr(i,RSTART+1,1)]*16+hex[substr(i,RSTART+2,1)];i=substr(i,RSTART+RLENGTH);}print i;}'"')

if [ -f /usr/local/etc/authpasswd ]; then
	read encryptpasswd < /usr/local/etc/authpasswd
else
	echo "No password file"
	return
fi

cryptpasswd=$(echo $decodedpasswd | /sbin/sha256)
if [ "$cryptpasswd" = "$encryptpasswd" ]; then
	/usr/local/bin/sudo /sbin/pfctl -t allowips -T add $REMOTE_ADDR
	echo "/usr/local/bin/sudo /sbin/pfctl -t allowips -T delete $REMOTE_ADDR" | /usr/bin/at now + 30 minute
	echo "Acces granted for 30 minutes"
else
	echo "Acces refused"
fi

C'est pas terrible mais suffisant : le mot de passe de référence est stocké dans /usr/local/etc/authpasswd et est en sha256

Il faut maintenant autoriser l'utilisateur www à pouvoir utiliser at :

$ echo "www" > /var/at/at.allow

Ensuite rajouter les entrées sudo qui vont bien dans /usr/local/etc/sudoers

%www	ALL=NOPASSWD:	/sbin/pfctl -t allowips *

Il vous reste à faire un fichier html qui appelle le script CGI via la méthode POST en lui fournissant le mot de passe donné dans une variable "passwd". Mettre le tout à dispo via un serveur web supportant le CGI.

Après on me demande pourquoi j'aime les Unix...

EDIT : alors on me dit dans l'oreillette que pfctl -t allowips -T expire 1800 lancé toutes les minutes dans une crontab ferait le même boulot mais je préfère ma solution à coup de at puisque at est géré par cron sous FreeBSD et que ce n'est exécuté qu'au besoin et non toutes les minutes

Name :
URL (optional) :
Write here: "ETOOMUCHSPAM"
Comments :