Table des matières
Protéger ses serveurs
Voyez aussi: observer votre serveur.
En cas de compromission, la meilleure solution reste la réinstallation à partir de zéro. Et donc, il FAUT avoir des sauvegardes régulières, et qui marchent!
Scaleway facilite grandement le travail avec ses "snapshots", qu'il est trivial de faire depuis la console internet. C'est pratique, mais ce n'est pas automatisé!
Attention aux "bare metal" chez Scaleway, car ils requièrent un arrêt complet pour leurs sauvegardes (qui se retrouvent être des "snapshots" de chacun de vos disques). De plus, les arrêts et redémarrages de ces serveurs prennent une dizaine de minutes (il y a donc un "downtime" d'une vingtaine de minutes pour vos services).
Sauvegarde par soi-même
Voyez cette page dédiée à la sauvegarde
Protection
Droits sur les fichiers
Bonne pratique: ne jamais faire un aveugle chmod 777
sur un serveur linux! On trouve sur internet des personnes qui le recommandent pour régler un problème d'accès mais c'est une grave erreur de sécurité. Une personne qui trouverait un accès "imprévu" pourrait utiliser ces droits anormaux pour corrompre votre serveur!
Il est très important de comprendre les droits en premier lieu plutot que de risquer des changements abrupts et qui laissent trop de marge pour d'éventuelles attaques.
Un fichier ou un dossier
- appartient à un "utilisateur"
- et aussi à un "groupe"
- et aussi à une troisième catégorie "tout le monde" (n'importe quel utilisateur du système).
Si on liste en détail ls -l /var
on verra par exemple la ligne suivante:
drwxrwxr-x 8 root syslog 4096 Nov 27 09:16 log/
La première colonne, drwxrwxr-x
encode les droits sur le dossier log/
correspondant.
On peut le décomposer ainsi:
d
indique qu'il s'agit d'un dossier (l
serait un lien et-
un simple fichier)- le premier
rwx
(user) encode les droits de l'utilisateur propriétaire (root
) - le second
rwx
(group) encode les droits du groupe propriétaire (les droits pour tous les utilisateurs qui font partie du groupesyslog
) - le troisième
r-x
(others) encode les droits de tous les autres utilisateurs existants sur la machine
Lettres rwx
Lettres utilisées:
r
(read) signifie que la lecture est possiblew
(write) que l'écriture est possiblex
pour un fichier signale qu'il est "exécutable" en tapant son nom (ex. script shell ou application).x
pour un dossier indique que l'on peut en lister le contenu
A props des scripts "non exécutables", par exemple un fichier source bash deploy.sh
a qui il manque le x
pour etre exécuté en tant que ./deploy.sh
pourra toutjours l'être sous l'appel bash deploy.sh
: le retrait du flag "exécutable" n'est PAS une protection décente. Il existe une "protection" de ce type au niveau de la partition elle-même (cf.
/etc/fstab
et l'option ro
readonly).
Le principe des droits unix est franchement simplifié si l'on raisonne en "contenu":
- les droits que l'on a sur le contenu d'un fichier (lecture ou écriture) sont trivials à comprendre. Ainsi,
chmod -r unfichier
retire le droit de lire le contenu, mais pas celui de voir la présence du fichier. - car l'autorisation de créer, détruire ou de renommer un fichier ne dépend pas de lui mais du dossier qui contient le fichier: en effet celui qui peut modifier le dossier en contrôle le contenu, ce qui s'y trouve. Il suffit de se souvenir que sous Linux un dossier n'est finalement qu'un fichier qui contient une liste de fichiers!
Changer les droits sur les fichiers et dossiers
Il existe plusieurs commandes pour régler ces droits (utilisez man
ou google pour davantage d'options):
chown
: changer le propriétaire (owner):chown -R dupond /tmp/test
le fera récursivement.chgrp
: changer le groupe qui possède la cible:chgrp admin /opt/tool
chmod
: changer les droits (ci-dessous)vigr
: permet d'inscrire ou de retirer des utilisateur aux groupes existants (oui, il existe des commandes plus spécifiques, mais moins intuitives). Attention si vous vous changez vos propres groupes, ils ne seront relu qu'après s'être re-loggué!
Exemples pour chmod
:
chmod -R go-rwx ~/.ssh
retire les droits de lecture, écriture, execution (listage) sur son dossier ssh personnel. Les doits de l'utilisateur lui-même sont inchangés.chmod g+w partage
permet aux membre du groupe propriétaire d'écrire dans le dossier (on ne change pas lex
du groupe, qui lui permettra ou non de lister le contenu et donc de voir les autres fichiers du dossiers)chmod ugo-w archive/
empêche de modifier le contenu du dossier pour tout le monde. Attention il s'agit du contenu du dossier: ce sont les opérations d'ajout ou de supression de fichiers dans le dossiers qui sont interdites, mais la modifiction du contenu d'un fichier dans le dossier reste possible (selon les droits sur le fichier en question).
Notez enfin qu'un utilisateur garde toujours le droit de modifier les droits de ses fichiers.
Notation octale: obsolète et dangereuse
Etrangement on voit encore parfois la notation en "octal". C'est une forme particulière de binaire: 3 bits codés en décimal, donc de 0 à 7.
Ainsi, le fameux chmod 777
correspond en effet à chmod ugo+rwx
: user, group et others ont les doits de lecture, d'écriture et d'exécution (littéralement rwx-rwx-rwx, encodé 111-111-111 en binaire, et donc 7-7-7 en octal). C'est excessivement rare que l'on veuille vraiment faire cela: il vaut mieux régler le problème via l'appartenance à des groupes (ex. le groupe www-data
avec un accès +w
pour écrire dans lea zone du serveur web /var/www
alors que l'on n'est pas soi meme l'utilisateur homonyme www-data
). Il est très important d'investir un petit peu dans ce système de droits.
Mais franchement on n'est plus au moyen âge! L'usage de l'octal est pervers pour les néophytes car il rend la chose obscure et difficile à maitriser!
Utilisateurs
En règle générale, évitez de créer des utilisateurs inutilement sur votre server et encore moins sur celui de production. Si vous voulez évaluer un service additionnel assez lourd à mettre en oeuvre, vous pouvez vous prendre un serveur virtualisé de plus, juste le temps d'essayer.
Inversement il est très utile de créer des utilisateurs associés à certains services ou action. C'est la raison de la présence de nombre d'entre eux dans un linux installé fraichement (cf. cat /etc/passwd
). Il devient bien plus facile de sécuriser la machine, puisque l'on peut les restreindre à leur tâche.
adduser
est la commande habituelle pour créer un utilisateur avec son dossier/home
associéuseradd
(!) ne fait que le créer dans le système (/etc/passwd), et vous aurez à lui configurer son environnement à la main.
Les utilisateurs "non humains" ne devraient pas avoir un compte interactif, avec lequel on peut se logguer dans un shell et exécuter des commandes arbitraires. C'est le cas de www-data
par exemple: par défaut vous ne pourrez pas vous "logger" sous cet utilisateur, même si vous êtes root
!
Il y a plusieurs façons de brider un utilisateur:
- en lui spécifiant un "shell" tel que
usermod --shell /usr/sbin/nologin username
(ou plus risqué, une édition directe viavipw
!). - en limitant les commandes qu'il peut faire via ssh, voyez
rssh
illustré ici ou bien l'usage du.ssh/authorized
keys comme décrit sur cette section du wiki.
Utilisateurs "système"
Par prudence, vous pouvez commencer par désactiver un utilisateur plutôt que de le supprimer, c'est moins dangereux (voyez aussi ssh
qui peut servir à restreindre les commandes utilisables par celui-ci), par exemple:
usermod -L games
A moins de vouloir prendre du risque, il est déconseillé de toucher aux utilisateurs dont l'ID est inférieur à 1000 (ce sont des comptes système, pour les services, démons, etc). Conservez aussi
nobody
(ID 65534).
La commande awk
ci-dessous ne liste que les utilisateurs secondaires:
awk 'BEGIN { FS = ":" } { if($3 >= 1000 && $3 != 65534) print; }' /etc/passwd
Sudo, utilisateurs privilégiés et sudoers
Les utilisateurs qui font partie du groupe sudo
peuvent lancer une commande en tant que root en préfixant leur commande par sudo
(supervisor do …), qui va ensuite leur demander de saisir leur mot de passe.
Attention, cela signifie aussi qu'une commande sudo /bin/bash
leur permettra de basculer dans un shell root complet. Il faut vraiment limiter ces privilèges à quelques comptes dans lesquels on a entièrement confiance. L'intérêt est d'éviter de rester tout le temps en tant que root et donc risquer de faire une erreur fatale sur le système. Certaines distributions ne permettent d'ailleurs même pas de se logguer sous "root", et nécessitent donc au moins un utilisateur sudoer (voyez les pages sur ssh
).
Mais il existe un autre moyen intermédiaire et très utile pour autoriser l'exécution d'une commande privilégiée par un utilisateur normal. Pour cela on passe par le fichier /etc/sudoers
, à éditer avec la commande visudo
.
Par exemple, si vous souhaitez qu'un utilisateur www-uploader
puisse relancer le serveur postgresql et sans devoir saisir de mot de passe (typiquement pour un déploiement automatisé), vous pouvez créer un shell /usr/local/bin/postgre_restart.sh
qui contient ceci:
#!/bin/bash /usr/sbin/service postgresql restart
Ensuite, vous lui permettez d'éxécuter la commande en tant que root en ajoutant la ligne suivante avec `visudo`:
www-uploader ALL=(root) NOPASSWD: /usr/local/bin/postgre_restart.sh
note: Attention ! Si votre commande accepte des arguments issus de l'utilisateur, pensez à bien "blinder" le script afin d'éviter un abus de droits
Vous trouverez bien d'autres options ici.
fail2ban en défense contre les accès "brute force"
Pour SSH au moins, on recommande systématiquement l'installation de apt install fail2ban
!
Il y a une page dédiée à cet outil.
portsentry: intercepter les tentatives de scan de ports
Cet outil peut s'installer pour repérer et agir contre des outils d'intrusion qui "scannent" les ports habituels servant de vecteurs d'attaque sur un serveur. Presque systématiquement, un client qui essaye de nombreux ports consécutivement "pour voir si ça mord" n'est pas un client normal.
apt install portsentry ss -tunlp|grep portsentry # pour montrer les ports surveillés par portsentry
Par défaut cet outil ne fait que logguer des événements dans le journal /var/log/syslog
, qui pourrait être traité lui-même par failtoban
comme ci-dessus. Mais bien plus efficace, on peut directement configurer portsentry
ainsi que les ports surveillés pour bannir le client. Voyez ce tutoriel par exemple.
Note je vous conseille d'ajouter une ou plusieurs adresses IP "fiables" dans le fichier /etc/portsentry/portsentry.ignore.static
qui ne seront jamais bannies avant d'activer des réactions plus agressives envers le client.
Firewall: restreindre l'accès a des services à des IP connues
Via le standard iptables
On peut utiliser le pare-feu standard assez simplement pour limiter un accès SSH (ici sur le port standard "22") aux deux seules IP sources "11.22.33.44" et "22.33.44.55"
# installation (si besoin) which iptables >/dev/null || apt install iptables # règles pour autoriser: iptable fonctionne en "first match" (si ça matche, ça ne va pas plus loin) iptables -A INPUT -p tcp -s 11.22.33.44 --dport 22 -j ACCEPT iptables -A INPUT -p tcp -s 22.33.44.44 --dport 22 -j ACCEPT # et pour ceux qui n'auront pas matché, on ferme le service: iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP
Attention:
- L'adresse IP d'où vous vous connectez doit être fixe pour que ce soit réaliste. C'est souvent utile d'en mettre une seconde pour le cas imprévu où elle changerait (ex. crash d'un serveur qui serait le seul point d'entrée!)
- Pensez à conserver une seconde console ouverte en SSH lorsque vous modifiez le pare-feu. Cela réduit le risque de se fermer la porte soi-même accidentellement! Ceci dit, certains hébergeurs vous donneront quand même une chance de vous en sortir (ex. scaleway: accès console en ligne).
- Un
apt install iptables-persistent
permet de sauvegarder vos règles de pare-feu entre deux relances du serveur (en général c'est ce que l'on veut, sauf peut être en phase de mise au point!)
Via le nouveau ufw
Il s'agit d'un système de configuration plus récent que iptables. Il est un peu moins répandu mais il est réputé un peu plus facile à l'usage si l'on ne connait pas déjà iptables. Probablement un bon investissement.
Exemple pour autoriser les clients 10.34.0.* à accéder au service web local:
ufw allow from 10.34.0.0/8 to 10.34.0.1 port 80
Pour lister les règles ufw status numbered
(ce qui permet de retirer une règle avec ufw delete N
).
Via un serveur filtrant amont
Si l'on a un serveur amont, tel qu'un système DMZ, il sera là aussi peut être plus pertinent de filtrer le plus haut possible. C'est généralement le cas si l'on est hébergé sous une forme virtualisée comme chez Scaleway et qu'il s'agit de bloquer des accès. Dans ce cas il sera plus facile encore d'utiliser les "stateful cloud firewall".
Le filtrage opère en effet en amont du serveur: non seulement l'interface web rend la chose plus ergonomique à configurer, mais surtout il est possible de s'en "sortir" si jamais vous avez fait une fausse manipulation et que vous vous êtes fermés la porte vous même ;)
A titre d'exemple, ci-dessous un filtre qui ne permet l'accès à SSH (port 22 standard) qu'en provenance des IP de la gamme 46.208.*.*
. Les autres seront reboutés par Scaleway avant même que votre serveur ne soit informé de la tentative d'accès. On pourrait même complètement fermer l'accès sauf pour les occasions où l'on veut administrer le serveur.
Cette interface reste cependant très limitée par rapport aux capacités de iptables
.
Autres éléments de sécurité
Pare-feu "proxy"
C'est un serveur B supplémentaire, situé entre votre serveur A et l'internet, et qui permet de filtrer tous les accès entrant et sortant du serveur A. Ainsi même le root
du serveur A ne pourra rien y faire: cela réduit la chance qu'un système compromis, souvent via le serveur web, ne puisse mettre en place des ouvertures imprévues pour poursuivre et étendre une attaque partielle (ex. un accès telnet).
Là aussi, les "Stateful Cloud Firewall" de Scaleway simplifient la tache complètement, et évitent de devoir installer un serveur supplémentaire.
Pour le web, notons le classique Squid, un serveur mandataire transparent qui sert aussi de cache, et Privoxy, un système avancé de filtrage et de réécriture de requètes.
apparmor
C'est un système de protection qui permet de brider certains exécutables à certains dossiers (ex. interdire à Mysql d'aller ailleurs que dans /var/lib/mysql
).
Pour savoir s'il est installé et actif:
service apparmor status
En général, on se rend compte de son impact lorsque l'on change des dossiers par défaut.
Par exemple, si on change l'entrée datadir
dans /etc/mysql/mariadb.conf.d/50-server.cnf
pour placer les données dans /home/mysql
plutôt que par défaut dans /var/lib/mysql
… et que "ça ne marche plus", il faudra penser à indiquer le changement de dossier à apparmor
dans le fichier de configuration associé, par exemple via /etc/apparmor.d/tunables/alias
(comme indiqué dans le fichier). Sans cela, apparmor
bloquera mysql
dans sa tentative d'accéder en dehors du dossier prévu!
rkhunter
Cet outil vérifie la présence (enfin, l'absence!) de "rootkits", typiquement des chevaux de Troie, vers et autres malware qui sont des moyens techniques pour les pirates de véroler et de profiter de votre serveur une fois rentrés. On peut aussi citer Tripwire dans la même veine.
rkhunter
est un moyen de vérifier l'intégrité de votre serveur mais pas un remède. S'il comporte effectivement un rootkit il est compromis et il faudra réinstaller le serveur (la "dépollution" est difficile et extrêmement risquée). Si vous devez réinstaller un serveur compris, faites très attention aux données que vous migrez, et évitez tout exécutable ou script qui pourraient avoir été corrompus ou cachés dans vos données et projets (et donc re-véroler votre nouveau serveur).
apt install rkhunter
Mettez à jour sa base de signatures avec:
rkhunter --propupd
Dans /etc/rkhunter.conf.local
ajoutez la ligne PKGMGR=DPKG
, ainsi que ALLOW_SSH_ROOT_USER=without-password
si vous avez autorisé un accès SSH en root via clé ssl sur votre machine, afin d'éviter deux alertes par défaut.
Enfin, lancez une analyse de votre système. C'est une chose à faire régulièrement:
rkhunter --checkall
Note: je vous conseille de reconfigurer la ligne APT_AUTOGEN="yes"
dans /etc/default/rkhunter
. Cela provoque une prise en compte (via une mise à jour automatique) des installations et mises à jour que vous feriez par la suite avec apt
. Inversement, ne mettez pas APT_AUTOGEN
à yes
si vous êtes paranoïaques, pour détecter des mises à jour dans votre dos par exemple. Vous aurez alors à exécuter la commande rkhunter --propupd
précédente à chaque mise à jour logicielle de votre serveur.
Consultez internet s'il y a la moindre alerte, même s'il se peut que ce soit un "faux positif".
Le journal détaillé du --checkall
se retrouve dans le fichier /var/log/rkhunter.log
.
Outils et pratiques à tendance paranoiaques
La sécurité est sans fin. Si vous avez des serveurs particulièrement sensibles (données bancaires, etc) vous pouvez regarder ces outils et techniques:
Lynis
Comme rkhunter
ci dessus, lynis est un autre outil de vérification d'intégrité plus avancé. Il utilise les outils existant sans demander des installations supplémentaires: plus il en trouve et plus il fait de tests (une approche non invasive intéressante, puisqu'il n'implique pas d'autres outils):
cd git clone https://github.com/CISOfy/lynis # version plus récente qu'avec "apt install lynis" cd lynis; ./lynis audit system
il teste bien davantage de choses que
rkhunter
et requiert une compréhension plus complète des systèmes linux pour être réellement exploitable, jusqu'au renforcement du kernel Linux (avis aux curieux!).
Inversement, il fait des suggestions directes pour les éléments qui lui semblent à renforcer (attention à ne pas le faire à l'aveugle, certaines d'entre elles ne sont pas du tout anodines!)
Autres outils de scan
Il existe de nombreux autres optils, ce deux-là sont assez classiques, et disponibles en paquets apt
sous Debian/Ubuntu:
nmap
est un petit outil très performant:nmap -sT 192.168.0.0/24
scanne les ports ouverts sur les appareils du réseau 192.168.0.*nmap –script vuln <IP>
teste les vulnérabilités connues sur une adresse IP à distance.
- ''nikto'' est spécifiquement fait pour scanner les vulnérabilités des serveurs web.
Attention Ces outils peuvent se retourner contre vous.
Ils font des opérations fondamentalement suspicieuses du point de vue d'un administrateur, et un simple scan des ports ouverts sur un serveur activement protégé peut déclencher une procédure automatique qui vous mettra en liste noire sur le firewall. De même, utiliser ces outils dans un réseau local peut vous valoir un appel téléphonique désagréable du responsable réseau si vous ne l'avez pas prévenu avant (et si ce n'est pas vous). Utilisez ces outils ouvertement, au risque de passer sinon pour un pirate auprès du site que vous "attaquez". En règle générale, ne les utilisez pas sur un serveur tiers afin de ne pas enfreindre la loi.
Port knocking
Sans avoir une bonne raison de le faire, c'est souvent contestable. Mais cela reste parfois pratique et de toute façon intéressant à connaître: il s'agit généralement depuis l'extérieur du serveur de "toquer" sur un port ou à une URL particulière afin d'ouvrir un service pour l'appelant, souvent temporairement.
C'est assez facile à mettre en place avec le pare-feu et comme d'habitude, assez facile de se bouter soi-même en dehors du serveur !
Cacher un service SSH
Un exemple classique est d'utiliser le pare-feu pour bloquer sshd
par défaut à l'extérieur, et de ne l'ouvrir qu'aux IP qui ont fait un nc
sur le port dédié au port knocking dans la seconde qui précède. C'est faisable avec quelques règles iptables
et c'est rapide, efficace et sûr.
Votre sshd
reste ainsi la plupart du temps totalement invisible, comme si le service n'était pas installé sur le serveur. Vous échappez donc évidemment à nombre d'attaques polluantes, bêtes et méchantes.
Exemple web pour le web
Plutôt que d'utiliser nc
on peut aussi profiter du service web et apsser par un script CGI. Par exemple:
- vous voulez accéder à https://private.tecrd.com qui refuse toutes les adresses IP clients par défaut (service fermé, mais visible)
- en tant que client, vous faites d'abord un accès à
https://privatekn.tecrd.com/allowme.php?key=17&ck=32
où 17 est l'heure du jour etck
la somme de l'heure et du jour si on est le 15 du mois. C'est un petit ajout pour que l'URL ne soit pas trop "recyclable" si jamais quelqu'un la laisse fuiter. - Le script
allowme.php
va vérifier ces deux données.- Il ne fait rien ou retourne une erreur
404 Page not found
s'ils ne sont pas bons (l'avantage du 404 est de faire croire à une page réellement absente) - Si par contre les données sont valides, il ajoute votre IP client dans la liste des adresses explicitement autorisées pour https://private.tecrd.com (là encore le test peut se faire avec PHP coté serveur en début de site, qui peut retirer l'IP après une-demi heure et refermer l'accès à la zone.
Exemple complet en bash CGI et page web
Imaginons que vous avez configuré SSH sur le port 22 mais qu'i lrefuse les accès externes (il n'écoute qu'en localhost
). Voici un second exemple de "port knocking" qui vous permettra quand même d'y accéder à distance.
Nous utilisons d'abord une page web minimaliste, à qui l'on passe l'heure du jour de cette façon: https://tecrd.com/cgi-bin/toctoc.sh?12
. L'appel est traité par le CGI bash
suivant:
#!/bin/bash LOCAL_PORT=22 PUBLIC_PORT=22123 DURATION=3600 if [[ "${QUERY_STRING}" = $(/bin/date +%H) ]]; then printf "Status: 200 OK\r\nContent-Type: text/html\r\n\r\n" echo '<html><head><title>☠</title><meta http-equiv="Content-type" content="text/html"></head><body><pre>' /usr/local/bin/openport.sh ${LOCAL_PORT} ${REMOTE_ADDR} ${PUBLIC_PORT} ${DURATION} echo '</pre></body></html>' else printf "Status: 400 Bad Request\r\nContent-Type: text/html\r\n\r\n" echo "<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>404 Not Found</h1></center><hr><center>nginx/1.14.2</center></body></html>" fi
Si l'heure passée correspond bien à l'heure en cours sur le serveur, le CGI fera appel à un second script /usr/local/bin/openport.sh
. Ce dernier utilise socat
afin d'ouvrir et de rediriger pendant une heure le port externe accessible sur 22123 vers le port interne 22. On contourne donc bien la restriction de SSH qui n'écoute que localement!
#!/bin/bash -feu set -o pipefail # Opens a local port to the outside IP, for a given amount of time # openport.sh LOCAL_PORT IP DPORT TIMEOUT # Example: # openport.sh 20 82.64.183.141 2020 240 LOCAL_PORT=${1} REMOTE_IP=${2} PUBLIC_PORT=${3} TIMEOUT=${4-600} fail() { echo "$@"; exit 1; } # Avoid shell injection [[ ! ${LOCAL_PORT} =~ ^[0-9]+$ ]] && fail "Illegal local port" [[ ! ${REMOTE_IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && fail "Illegal IP" [[ ! ${PUBLIC_PORT} =~ ^[0-9]+$ ]] && fail "Illegal remote port" # Kill previous if any, and spawn with timeout ps aux | grep "timeout.* socat TCP-LISTEN:$PUBLIC_PORT" | awk '{print $2}' | xargs -r kill 2>/dev/null || true nohup timeout ${TIMEOUT} socat TCP-LISTEN:${PUBLIC_PORT},fork,range=${REMOTE_IP}/32 TCP:127.0.0.1:${LOCAL_PORT} </dev/null &>/dev/null & echo "IP ${REMOTE_IP} can now access local port ${LOCAL_PORT} via public port ${PUBLIC_PORT} for ${DURATION} seconds."
si vous vouliez utiliser un port externe inférieur à 1000, ou encore si vous vouliez utiliser
iptables
pour mieux gérer la chose, il faudra que le CGI accède en root au script. Utilisez alors sudo
pour l'appel après avoir ajouté cette ligne avec visudo
:
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/openport.sh
Défenses actives
Ce sont des techniques parfois contestables, mais intéressantes, qui cherchent à riposter aux attaques sur votre serveur.
Port scan
Il s'agit ici de bannir un attaquant qui cherche à trouver tous les ports ouverts sur votre serveur afin de les exploiter ensuite, c'est un peu le pendant défensif des opérations "outils de scan" décrites ci-avant.
On peut utiliser des règles de pare feu qui observent les connexions entrantes et bannissent pour 10 minutes toute source qui essaye au moins 5 ports différents en moins de 10 secondes.
en pratique il est difficile de détecter un réel "port scan" hostile d'un usage rare mais standard. Ces protections sont davantage utile pour détecter de possibles attaques, plutôt que comme outil de contre-mesure explicite (retirez alors l'avant dernière ligne ci-dessous). A vos risques et périls!
ipset create port_scanners hash:ip family inet hashsize 32768 maxelem 65536 timeout 600 ipset create scanned_ports hash:ip,port family inet hashsize 32768 maxelem 65536 timeout 60 iptables -A INPUT -m state --state INVALID -j DROP iptables -A INPUT -m state --state NEW -m set ! --match-set scanned_ports src,dst -m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-mode srcip --hashlimit-name portscan --hashlimit-htable-expire 10000 -j SET --add-set port_scanners src --exist iptables -A INPUT -m state --state NEW -m set --match-set port_scanners src -j DROP iptables -A INPUT -m state --state NEW -j SET --add-set scanned_ports src,dst
(source)
Honeypot
A l'inverse du port knocking, le "pot de miel" est un piège rendu public qui va "capturer" les tentatives d'accès naïves. Par exemple, on peut mettre un process en écoute sur le port 22 alors même que son service SSH est sur le port 12345. Il sera aisé de détecter une tentative frauduleuse d'accès à votre serveur (… ou un oubli de votre part!)
La détection d'un accès sur le port "pot de miel" pourra déclencher deux types de réponses:
- un blocage "blacklist" immédiat du client pour une durée donnée
- ou encore répondre extrêmement lentement afin de ralentir l'attaquant. C'est généralement efficace contre une attaque brute force (qui repose sur un très grand nombre d'essais et de combinaisons), car l'attaquant se lassera vite de votre serveur qui parait abominablement lent et ira chercher ailleurs une autre victime. Mais cela mobilise aussi vos propres ressources réseau car votre serveur conserve ce canal de communication ouvert: saturé, vous risquez fort de vous provoquer vous-même un déni d'accès (DDOS) bien contreproductif. Cette défense est généralement déconseillée à cause de cela.
La encore, testez bien que vous n'allez pas vous mettre vous-mêmes dehors!
Conclusion et réflexions: attention!
On le voit, nombre ces pratiques, surtout celles qui sont "agressives" envers le client ne sont à mettre en oeuvre qu'en ayant pesé le pour et le contre. Mais elles restent selon moi recevables dans certains cas souvent critiques (ex. un serveur IOT qui n'est jamais censé être visible du public). Le port knocking notamment est très simple et statistiquement très efficace.
D'autre part, la composante "sécurité par l'obscurité" n'est recevable qu'en supplément d'une sécurité traditionnelle explicite (SSL, certificats, mot de passe, bonnes clés, etc).
Comme d'habitude, la sécurité bénéficie de plusieurs couches les unes sur les autres. Et puis il faut voir la sécurité dans son ensemble. Si vous avez un service SSH standard, sur le port 22, vous serez régulièrement attaqués en "brute force", du simple fait que les scripts-robots des pirates trouveront ce port ouvert sur l'extérieur. Même sans succès, ces attaques laissent énormément de traces dans les journaux du système et cela réduit la lisibilité. C'est pour cela que je recommande de changer le port SSH par défaut (trop visible et trop attaqué), ou bien de recourir à du port knocking dont le gros bénéfice est de masquer simplement et complètement un service la plupart du temps. Votre journal en sera grandement réduit et vous augmenterez vos chance de voir des tentatives d'accès réellement problématiques.
Notons enfin que l'adresse IP du client est souvent utilisée comme critère pour bloquer un accès.
Mais cette adresse n'est pas toujours un identifiant unique du client! Parfois, c'est l'adresse publique d'un sous-réseau local de 100 postes et donc de diverses personnes qui ne sont pas forcément toutes mal intentionnées. C'est aussi le cas de certains opérateurs téléphoniques ou fibrés, d'où "ressortent" leurs clients sur des IP partagées, changeantes et recyclées en permanence. Il est souvent plus solide d'utiliser l'adresse ethernet physique, lorsqu'elle est disponible.