Outils pour utilisateurs

Outils du site


doc:formations:hebergement:serveur:proteger

< Retour à l'index

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 groupe syslog)
  • 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 possible
  • w (write) que l'écriture est possible
  • x 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 le x 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 via vipw !).
  • 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:

  • debsecan va vous lister tous les codes CVE de votre installation. Ce sont des failles de sécurités qui sont référencées officiellement au niveau mondial. Notez que j'attend encore de voir un serveur avec une liste vide !
  • 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 et ck 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.

doc/formations/hebergement/serveur/proteger.txt · Dernière modification : 2024/02/19 18:56 de jeremie