Modifications entre les versions 1 et 4 (s'étendant sur 3 versions)
Version 1 à la date du 2012-10-11 20:21:43
Taille: 7562
Commentaire: Copie locale d'une page web en voie de disparition…
Version 4 à la date du 2019-07-23 16:36:15
Taille: 10178
Éditeur: FranckKouyami
Commentaire:
Texte supprimé. Texte ajouté.
Ligne 1: Ligne 1:
Copie locale d'une page web en voie de disparition…
= Port Knocking : Toc Toc c'est moi laisse moi faire du ssh =

<<TableOfContents()>>


== Suite au changement dans buster ==

Séquence toc-toc sur les ports d'exemple 123, 234, 345 et 456

{{{
 #!/usr/bin/env nft -f
flush ruleset

table ip Inet4 {
  set Knocked_1 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_2 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_3 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_4 {
    type ipv4_addr
    flags timeout
    timeout 2m
    gc-interval 4s
  }

  chain Knock_1 {
    set add ip saddr @Knocked_1
  }
  chain Unknock_1 {
    set update ip saddr timeout 0s @Knocked_1
  }
  chain Knock_2 {
    set update ip saddr timeout 0s @Knocked_1
    set add ip saddr @Knocked_2
  }
  chain Unknock_2 {
    set update ip saddr timeout 0s @Knocked_2
  }
  chain Knock_3 {
    set update ip saddr timeout 0s @Knocked_2
    set add ip saddr @Knocked_3
  }
  chain Unknock_3 {
    set update ip saddr timeout 0s @Knocked_3
  }
  chain Knock_4 {
    set update ip saddr timeout 0s @Knocked_3
    set add ip saddr @Knocked_4 log prefix "Port-Knock accepted: "
  }

  chain RefreshKnock {
    set update ip saddr timeout 2m @Knocked_4
  }

  chain PortKnock {
    ct state new ip saddr @Knocked_4 goto RefreshKnock
    tcp dport 456 ct state new ip saddr @Knocked_3 goto Knock_4
    tcp dport 345 ct state new ip saddr @Knocked_3 return
    ip saddr @Knocked_3 ct state new goto Unknock_3
    tcp dport 345 ct state new ip saddr @Knocked_2 goto Knock_3
    tcp dport 234 ct state new ip saddr @Knocked_2 return
    ip saddr @Knocked_2 ct state new goto Unknock_2
    tcp dport 234 ct state new ip saddr @Knocked_1 goto Knock_2
    tcp dport 123 ct state new ip saddr @Knocked_1 return
    ip saddr @Knocked_1 ct state new goto Unknock_1
    tcp dport 123 ct state new goto Knock_1
  }

  chain FilterIn {
    type filter hook input priority 0
    policy drop

    # allow established/related connections
    ct state established,related accept

    # early drop of invalid connections
    ct state invalid drop

    # allow from loopback
    meta iif lo accept

    # allow icmp
    ip protocol icmp accept

    # port-knocking
    jump PortKnock

    # misc. filtering
    # ...
  }

  chain FilterOut {
    type filter hook output priority 0
    policy accept
  }
}}}

Source : https://wiki.nftables.org/wiki-nftables/index.php/Port_knocking_example

Un exemple avec 3 ports au lieu de 4 ici -> https://home.regit.org/2017/07/nftables-port-knocking/

== Avant Débian Buster ==
Ligne 4: Ligne 118:
<<TableOfContents()>>

= Port Knocking : Toc Toc c'est moi laisse moi faire du ssh =
Ligne 19: Ligne 130:
== Le principe == === Le principe ===
Ligne 25: Ligne 136:
== Le script == === Le script ===
Ligne 42: Ligne 153:
== Les explications == === Les explications ===

Port Knocking : Toc Toc c'est moi laisse moi faire du ssh

Suite au changement dans buster

Séquence toc-toc sur les ports d'exemple 123, 234, 345 et 456

 #!/usr/bin/env nft -f
flush ruleset

table ip Inet4 {
  set Knocked_1 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_2 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_3 {
    type ipv4_addr
    flags timeout
    timeout 10s
    gc-interval 4s
  }
  set Knocked_4 {
    type ipv4_addr
    flags timeout
    timeout 2m
    gc-interval 4s
  }

  chain Knock_1 {
    set add ip saddr @Knocked_1
  }
  chain Unknock_1 {
    set update ip saddr timeout 0s @Knocked_1
  }
  chain Knock_2 {
    set update ip saddr timeout 0s @Knocked_1
    set add ip saddr @Knocked_2
  }
  chain Unknock_2 {
    set update ip saddr timeout 0s @Knocked_2
  }
  chain Knock_3 {
    set update ip saddr timeout 0s @Knocked_2
    set add ip saddr @Knocked_3
  }
  chain Unknock_3 {
    set update ip saddr timeout 0s @Knocked_3
  }
  chain Knock_4 {
    set update ip saddr timeout 0s @Knocked_3
    set add ip saddr @Knocked_4 log prefix "Port-Knock accepted: "
  }

  chain RefreshKnock {
    set update ip saddr timeout 2m @Knocked_4
  }

  chain PortKnock {
    ct state new ip saddr @Knocked_4 goto RefreshKnock
    tcp dport 456 ct state new ip saddr @Knocked_3 goto Knock_4
    tcp dport 345 ct state new ip saddr @Knocked_3 return
    ip saddr @Knocked_3 ct state new goto Unknock_3
    tcp dport 345 ct state new ip saddr @Knocked_2 goto Knock_3
    tcp dport 234 ct state new ip saddr @Knocked_2 return
    ip saddr @Knocked_2 ct state new goto Unknock_2
    tcp dport 234 ct state new ip saddr @Knocked_1 goto Knock_2
    tcp dport 123 ct state new ip saddr @Knocked_1 return
    ip saddr @Knocked_1 ct state new goto Unknock_1
    tcp dport 123 ct state new goto Knock_1
  }

  chain FilterIn {
    type filter hook input priority 0
    policy drop

    # allow established/related connections
    ct state established,related accept

    # early drop of invalid connections
    ct state invalid drop

    # allow from loopback
    meta iif lo accept

    # allow icmp
    ip protocol icmp accept

    # port-knocking
    jump PortKnock

    # misc. filtering
    # ...
  }

  chain FilterOut {
    type filter hook output priority 0
    policy accept
  }

Source : https://wiki.nftables.org/wiki-nftables/index.php/Port_knocking_example

Un exemple avec 3 ports au lieu de 4 ici -> https://home.regit.org/2017/07/nftables-port-knocking/

Avant Débian Buster

Source : http://www.kik-it.com/previousblog/#entry070309-073501 (Friday, March 9, 2007, 07:35)

Avoir ssh sur ses serveurs c'est vraiment sympa pour les administrer à distance mais devoir laisser son port ssh accessible 24/7 pour notre petit confort c'est pas top niveau sécurité ...

On peut tenter de verrouiller les accès au port ssh histoire de pas se faire brute forcer son mot de passe avec quelque chose de ce style :

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

ce qui aura pour effet d'ignorer les requêtes arrivant à un rythme supérieur à 3 par minute. C'est pas mal déjà, mais en ce moment la mode est au port Knocking, et c'est pas si compliqué...

Il suffit de 10 lignes dans iptables pour établir un port Knocking de trois "tocs" afin d'ouvrir le port ssh si les bons ports ont été "Knockés" (et dans le bon ordre :)

Le principe

Avant de pouvoir utiliser le port 22 on doit le débloquer en contactant des ports précis dans un ordre précis, ce qui constitue la "clef" pour ouvrir notre port 22.

Dans notre exemple la clef est 103 202 301, si on contacte ces ports dans cet ordre, le port 22 sera ouvert pendant 5 secondes, juste le temps pour nous de faire une connexion ssh qui sera maintenue au delà de 5 secondes grâce aux règles qui acceptent les connexions ESTABLISHED.

Le script

iptables -N Step2
iptables -A Step2 -m recent --name Key1 --remove
iptables -A Step2 -m recent --name Key2 --set

iptables -N Step3
iptables -A Step3 -m recent --name Key2 --remove
iptables -A Step3 -m recent --name Key3 --set

iptables -A INPUT -p tcp --dport 103 -m recent --set --name Key1
iptables -A INPUT -p tcp --dport 202 -m recent --rcheck --name Key1 -j Step2
iptables -A INPUT -p tcp --dport 301 -m recent --rcheck --name Key2 -j Step3

iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name Key3 -j ACCEPT

Les explications

On utilise ici le module "recent" d'iptables : iptables -m recent --help

recent v1.2.11 options:
[!] --set Add source address to list, always matches.
[!] --rcheck Match if source address in list.
[!] --update Match if source address in list, also update last-seen time.
[!] --remove Match if source address in list, also removes that address from list.
--seconds seconds For check and update commands above.
Specifies that the match will only occur if source address last seen within
the last 'seconds' seconds.
--name name Name of the recent list to be used. DEFAULT used if none given.
--rsource Match/Save the source address of each packet in the recent list table (default).
--rdest Match/Save the destination address of each packet in the recent list table.
ipt_recent v0.3.1: Stephen Frost <sfrost@snowman.net>. http://snowman.net/projects/ipt_recent/

Ce module permet de créer des listes dans lesquelles on va pouvoir lire/enregistrer des IPs ...

On créer deux chaînes, Step2 et Step3, pour vérifier que la séquence des tocs sur nos ports est bien respectée :

iptables -N Step2
iptables -A Step2 -m recent --name Key1 --remove
iptables -A Step2 -m recent --name Key2 --set

ici, lorsque le paquet traverse Step2, on ajoute l'adresse source du paquet qui est précédemment passé par le port 103 dans la liste "Key2" et on la retire de "Key1"

iptables -N Step3
iptables -A Step3 -m recent --name Key2 --remove
iptables -A Step3 -m recent --name Key3 --set

ici, lorsque le paquet traverse Step3, on ajoute l'adresse source du paquet qui est précédemment passé par le port 202 dans la liste "Key3" et on la retire de "Key2"

la ligne :

iptables -A INPUT -p tcp --dport 103 -m recent --set --name Key1

ajoute l'adresse source d'un paquet qui arriverait sur le port 103 dans la liste "Key1"

la ligne :

iptables -A INPUT -p tcp --dport 202 -m recent --rcheck --name Key1 -j Step2

ajoute l'adresse source d'un paquet qui arriverait sur le port 202 et dont l'adresse source serait dans "Key1" dans la liste "Key2" (cela se produit en traversant la chaîne "Step2")

la ligne :

iptables -A INPUT -p tcp --dport 301 -m recent --rcheck --name Key2 -j Step3

ajoute l'adresse source d'un paquet qui arriverait sur le port 301 et dont l'adresse source serait dans "Key2" dans la liste "Key3" (cela se produit en traversant la chaîne "Step3")

Enfin, la ligne suivante laisse passer les paquets à destination du port 22 dont l'adresse source est dans la liste "Key3" depuis moins de 5 secondes :

iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name Key3 -j ACCEPT

Un script de test complet pour un serveur pourrait être :

#On fait le ménage
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

#On est pas causant par défaut
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

#On accepte de parler et d'entendre les réponses à nos questions
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state NEW,ESTABLISHED -j ACCEPT

#On met en place un port Knocking afin d'ouvrir le port ssh 5 secondes
iptables -N Step2
iptables -A Step2 -m recent --name Key1 --remove
iptables -A Step2 -m recent --name Key2 --set

iptables -N Step3
iptables -A Step3 -m recent --name Key2 --remove
iptables -A Step3 -m recent --name Key3 --set

iptables -A INPUT -p tcp --dport 103 -m recent --set --name Key1
iptables -A INPUT -p tcp --dport 202 -m recent --rcheck --name Key1 -j Step2
iptables -A INPUT -p tcp --dport 301 -m recent --rcheck --name Key2 -j Step3

iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name Key3 -j ACCEPT

Bon maintenant qu'on a la partie serveur, voyons la partie client :

Il faut faire toc toc sur les ports 103 puis 202 puis 301, certains conseillent d'utiliser telnet avec des commandes du style :

$> alias toc='telnet ip_address'
$> toc 103 ; toc 202 ; toc 301 ; ssh ip_address
puis Ctrl-C 3 fois pour killer les telnets et retomber sur la commande ssh

il m'a semblé que telnet introduisait trop de latence et que globalement ca marchait pas.

Je préfère utiliser un petit script "knock" du style :

nmap -PA103,202,301 -r -M1 $1
ssh $1

Explications : pour être certain que nmap contacte les ports dans l'ordre indiqué on ajoute "-r" et on fixe le maximum de sockets à 1 avec "-M1" pour être bien certain qu'il fera chaque toc l'un après l'autre.

Finalement

sous GNU/Linux on contacte notre serveur ssh avec la commande :

#./knock ip_address

et sous Windows ca marche aussi didon :

il nous faut nmap pour win32 : http://www.insecure.org/nmap/download.html
et winpcap : http://www.winpcap.org/install/default.htm
on met putty dans le dossier d'nmap ...
plus l'équivalent de notre petit script :

----knock.bat----
set IP=%1
if %1.==. set /p IP=Adresse IP ?
nmap -p103,202,301 -r --host_timeout 2000 %IP%
putty %IP%
-----------------

Et voilà Youpi notre port ssh est joignable 5 secondes après 3 tocs secrets et fermé le reste du temps, quel bonheur cet iptables ;)

SSH/TocTocToc (dernière édition le 2019-07-23 16:36:15 par FranckKouyami)