La solution s'articule autour de trois éléments:
  • Une page web en php ou autre.
  • Un script qui tourne en permanence.
  • Une méthode pour s'assurer que le script ne s'arrête jamais.
Commençons pas la page web. Comme apache tourne en général avec l'uid 48 (apache), et qu'on ne veut pas donner le privilège à apache d'influer sur les tables, on va passer par un fichier intermédiaire. Le principe donc de la page web est donc simplement de créer un fichier (/tmp/sesame) qui contiendra l'adresse IP de l'appelant.

Voici ce que ça donnerait en php:
<?php

$ip=$_SERVER['REMOTE_ADDR'];
system("echo $ip > /tmp/sesame");

?>
Ensuite le petit script qui va tourner en permanence sur la machine. Il s'agit d'un petit script shell qui va simplement attendre que le fichier /tmp/sesame existe. Quand il le trouve, il ajoute une table pour autoriser l'adresse IP contenue dans le fichier:
#!/bin/sh

FILE_IP=/tmp/sesame
IPTABLES_RULE=INPUT
OPTIONS="-p tcp --dport 22"

while :
do
sleep 1
[ -f $FILE_IP ] || continue

IP=`cat $FILE_IP`

if iptables-save | grep -q $IP
then
sleep 1
else
if ipcalc -m $IP >/dev/null 2>&1
then
iptables -I $IPTABLES_RULE -s $IP $OPTIONS -j ACCEPT
iptables -I $IPTABLES_RULE -d $IP -j ACCEPT
fi
fi

echo "`date` `hostname`" | mail -s "SESAME `hostname` $IP" root
rm $FILE_IP 2>/dev/null

done
Enfin, afin que ce script se lance au démarrage, et qu'il ne s'arrête jamais, j'aime utiliser le fichier /etc/inittab. J'ajoute simplement la ligne suivante afin que le tout s'exécute en runlevel 3 :
tc:3:respawn:/root/scripts/sesame.sh
Et afin d'activer le tout, on tape la commande init q qui relit le fichier inittab. Voilà. Maintenant il me suffit d'appeler la page http://monserveur.tld/lenomquejaichoisi.php et la porte s'ouvre par magie....

L'utilisateur root
Bien-sûr il existe d'autres solutions plus sécurisées et plus complètes comme le Port Knocking, mais le fait d'ouvrir l'accès temporairement l'accès à partir d'une machine n'est pas une menace en soi, en tout cas pas pour un serveur ordinaire qui est déjà sécurisé.