Mise en place d’un portknocking pour limiter les ports accessibles sur le net

Hello …

Protéger des services non-public (type ssh) d’être accédés par n’importe qui ça peut être assez utile (pour éviter les connexions intempestives pour la prise d’information, tentative de login/bruteforce …), le tout sans avoir à déclarer d’ip, …

On peut utiliser pour cela du portknocking, le but étant de mettre en place une séquence de « toc toc qui est là » qui permettra ensuite d’ouvrir la porte, et si la séquence n’est pas bonne … ^^).

Pour debian/ubuntu on peut utiliser le soft knockd, qui est assez simple à mettre en place.

Pour l’installer :

apt-get install knockd

Pour le configurer, il faut modifier le fichier /etc/knockd.conf :

[options]
    logfile = /var/log/knockd.log
[openSSH]
    sequence    = 7000,8000,9000
    seq_timeout = 10
    tcpflags    = syn
    command     = /usr/sbin/iptables -A INPUT -s %IP% -j ACCEPT
[closeSSH]
    sequence    = 9000,8000,7000
    seq_timeout = 10
    tcpflags    = syn
    command     = /usr/sbin/iptables -D INPUT -s %IP% -j ACCEPT

Et autoriser le lancement du « daemon » dans /etc/default/knockd, puis (re)démarrer le service :

/etc/init.d/knockd restart

Dans ce cas (c’est la config par défaut), il faudra lancer 3 paquets TCP dans l’ordre, d’abord sur le port 7000, puis 8000 et enfin 9000 pour ouvrir le port 22, et pour le fermer, on fait la sequence inverse …

Les « fonctions » bash que l’on peut utiliser pour ouvrir les ports (que l’on peut mettre dans le .bashrc) :

function opssh { telnet ipserver 7000&sleep 1 &&telnet ipserver 8000&sleep 2 &&telnet ipserver 9000& sleep 4 && killall telnet && return; }
function clssh { telnet ipserver 9000&sleep 1 &&telnet ipserver 8000&sleep 2 &&telnet ipserver 7000& sleep 4 && killall telnet && return; }

Il suffira de lancer opssh pour ouvrir le port pour notre ip, et clssh pour fermer la connexion.
A noter que l’on peut changer la commande iptables (pour utiliser des redirections sur différent ports/ips selon les séquences, super utile si l’on a plusieurs serveurs en local derrière une NAT, …).

Pour des idées de redirections (à mettre dans les commandes) :

/sbin/iptables -t nat -A PREROUTING -p tcp --dport 22 -s %IP% -j DNAT --to-destination 1.3.3.7 #redirige le traffic en direction du port 22 sur l'ip 1.3.3.7

Deux Notes :
1- Pour que cela ai un intêret, il faut mettre la « policy » du firewall en DENY

2- Une idée d’utilisation :

Pour protéger votre serveur SSH (par exemple) sans avoir à utiliser de séquences particulière (utilisant du telnet/ou un client de portknock), vous pouvez mettre la séquence sur le port 22 (genre 3 ou 4 syn tcp avant d’ouvrir la connexion) comme ça lors d’un syn scan il faudra le lancer plusieurs fois dans un cours intervalle pour ouvrir le port (c’est donc peu probable que la personne fassent la séquence et ouvre le port). Et lors des autres type de scan … comme c’est pas du syn, ça ne s’ouvre pas ^^.
Et pour fermer l’accès, il suffira d’une seule séquence avec le flag FIN sur le port 22. (Une fois une connexion SSH lancé il n’y a plus de syn de lancé, tous ce fait en stream et se termine par un FIN).

Ce qui donne la conf suivante :

[openSSH]
        sequence    = 22,22,22
        seq_timeout = 15
       command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

[closeSSH]
        sequence    = 22
        seq_timeout = 15
       command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = fin

Voilà ^^.