Sécuriser un serveur Web sous Linux

Bonjour, Habr!

Nous n'avons pas publié de nouveaux livres sur Linux pour les débutants depuis longtemps - et maintenant nous entreprenons la traduction de nouveaux produits d'un tel plan. Le livre de Clinton, Linux in Action , publié par Manning, raconte non seulement la structure interne de Linux , mais aussi les problèmes les plus courants et comment les résoudre.


L'auteur a publié un extrait du 9ème chapitre sur le site Hackernoon, que nous vous suggérons d'évaluer.

Assembler un serveur LAMP, comment le configurer, assurer un traitement fiable des données, configurer le domaine et prendre soin d'un certificat TLS n'est que la moitié du chemin vers la victoire. Vous devez également vous assurer que votre infrastructure est protégée contre les nombreuses menaces redoutables d'Internet.

Dans cet article, nous examinons la sécurité d'un site Web en apprenant à travailler correctement avec les groupes de systèmes, à garantir l'isolation des processus et à auditer régulièrement les ressources système. Bien sûr, cette histoire n'est pas complète (le livre Linux en action a également couvert d'autres sujets, par exemple, installer des certificats TLS et travailler avec SELinux), mais cela suffira pour commencer.

Groupes de systèmes et principe des privilèges minimaux


Les développeurs que vous soutenez (enfin) commencent à se rendre compte qu'il est nécessaire de limiter l'accès général aux données et aux fichiers de configuration situés sur le serveur d'applications, mais en même temps, de laisser cet accès ouvert à divers programmeurs et autres équipes informatiques.

La première partie de la solution concerne les groupes . Un groupe est un objet du système (un peu comme un utilisateur) avec la mise en garde qu'aucun utilisateur ne se connectera jamais au système en tant que groupe. La force des groupes réside dans le fait qu’ils, comme les utilisateurs, peuvent être «assignés» à des fichiers ou des répertoires, permettant à chaque membre du groupe d’utiliser les privilèges qui lui sont accordés. Ceci est illustré ci-dessous.

Les développeurs du groupe Développeurs peuvent accéder à un répertoire spécifique, et pour les utilisateurs qui ne sont pas membres de ce groupe, le répertoire sera fermé
Essayez-le vous-même: créez un nouveau fichier dans un éditeur de texte. Écrivez-y du texte brut, par exemple, «Bonjour tout le monde», afin que vous puissiez voir immédiatement quand le fichier a été correctement accédé. Modifiez ensuite les autorisations à l'aide de chmod 770 afin que le propriétaire du fichier et les membres du groupe auquel il appartient aient tous les droits pour travailler avec le fichier, tandis que d'autres ne peuvent pas le lire.

 $ nano datafile.txt $ chmod 770 datafile.txt 

Si votre système n'a pas encore d'autres comptes utilisateur que le vôtre, créez un tel compte soit en utilisant adduser - cela se fait dans Debian / Ubuntu - soit en utilisant useradd , comme c'est la coutume dans CentOS. La commande useradd fonctionnera également sur Ubuntu.

useradd à l' adduser Debian, la commande useradd requiert que le mot de passe utilisateur soit généré séparément:

 # useradd otheruser # passwd otheruser Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully 

En utilisant la commande su , nous basculons vers le nouvel utilisateur. Après avoir entré son mot de passe, toutes les commandes suivantes seront exécutées au nom de cet utilisateur. Vous travaillerez au nom de cet utilisateur particulier; ni plus ni moins. Si vous essayez de lire le fichier de datafile.txt (en utilisant cat ), alors rien ne fonctionnera plus pour vous; comme vous vous en souvenez, seuls les membres du groupe ont des droits de lecture. Une fois terminé, tapez exit pour quitter le nouveau shell utilisateur et revenir à votre shell d'origine.

 $ su otheruser Password: $ cat /home/ubuntu/datafile.txt cat: /home/ubuntu/datafile.txt: Permission denied $ exit 

Tout cela est attendu et tout à fait compréhensible. Comme vous pouvez le voir, lorsque vous ne pouvez pas lire un fichier appartenant à un autre utilisateur, c'est parfois un problème. Voyons ce que vous pouvez faire en associant le fichier au groupe, puis en configurant correctement les autorisations de fichier.

Nous allons créer un nouveau groupe avec lequel nous pouvons gérer les données de notre application, puis éditer les propriétés de notre fichier de données à l'aide de la chown . L'argument ubuntu: app-data-group laisse la propriété du fichier à l'utilisateur Ubuntu, mais son groupe change pour un nouveau: app-data-group.

 # groupadd app-data-group # chown ubuntu:app-data-group datafile.txt 

Exécutez ls pour obtenir la sortie «étendue» de ce fichier et afficher ses nouvelles autorisations et son statut. Veuillez noter: comme prévu, le fichier appartient à l'utilisateur ubuntu appartenant au groupe app-data-group .

 $ ls -l | grep datafile.txt -rwxrwx — — 1 ubuntu app-data-group 6 Aug 9 22:43 datafile.txt 

Vous pouvez utiliser usermod pour ajouter votre utilisateur au app-data-group d' app-data-group , puis utiliser la commande su pour basculer vers le shell dans lequel le compte d'un autre utilisateur est déployé. Maintenant, même si les droits d'accès au fichier le bloquent de tous les «autres» - et vous êtes certainement un utilisateur «différent» pour le moment - vous devez lire ce fichier librement, car vous appartenez au groupe nécessaire.

 # usermod -aG app-data-group otheruser $ su otheruser $ cat datafile.txt Hello World 

En utilisant la commande su , nous basculons entre les comptes d'utilisateurs. Ils sont enregistrés dans mon datafile.txt . Une telle organisation est le moyen juste et efficace d'éliminer une variété de problèmes complexes avec les droits d'accès qui peuvent survenir dans un système multi-utilisateur.

En fait, il est utilisé non seulement pour fournir les droits d'accès nécessaires aux utilisateurs individuels - de nombreux processus système ne seraient pas non plus en mesure de mener à bien leurs tâches s'ils n'étaient pas prescrits d'appartenir aux groupes nécessaires. Vous pouvez afficher le fichier / etc / group en diagonale - notez combien de processus système appartiennent à vos propres groupes ...

Liste abrégée du contenu du fichier / etc / group:

 $ cat /etc/group root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4:syslog tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: […] 

Isolement du processus de conteneur


Vous craignez peut-être que de nombreux services exécutés sur votre même serveur soient menacés si au moins l'un de ces services est compromis? Une option pour atténuer les dommages que des utilisateurs imprudents ou malveillants peuvent causer consiste à isoler les ressources et les processus du système. Ainsi, même si quelqu'un souhaite étendre son autorité au-delà des limites établies, il n'aura pas accès physiquement aux données.

Auparavant, il était décidé de résoudre ce problème comme suit: chaque service se voyait allouer sa propre machine physique. Cependant, la virtualisation rend la construction d'une architecture "maillée" beaucoup plus simple et moins coûteuse. Aujourd'hui, cette architecture est souvent appelée microservice et vous permet d'exécuter de nombreux conteneurs à la fois, dans l'un, par exemple, une base de données peut fonctionner, dans l'autre - Apache, et dans le troisième - des fichiers multimédias qui peuvent être incorporés dans vos pages Web. L'architecture de microservice permet non seulement d'augmenter considérablement la productivité et l'efficacité, mais également de réduire considérablement le risque de piratage de chaque composant individuel.

Les «conteneurs» dont je parle n'ont pas à convaincre avec LXC. D'autres technologies de conteneurs telles que Docker deviennent de plus en plus populaires aujourd'hui.

Vérification des valeurs d'ID utilisateur dangereuses


Bien sûr, tout utilisateur disposant de droits d'administrateur peut temporairement fournir un accès root avec la sudo , mais seul l'administrateur est le véritable administrateur. Comme vous le savez déjà, il n'est pas sûr d'exécuter des fonctions régulières sous un accès root. Cependant, cela peut arriver - purement par accident ou en raison d'une fraude de données malveillantes - qu'un utilisateur ordinaire aura des droits administratifs sans interruption.

Dans ce cas, il est bon qu'il ne soit pas difficile d'identifier de tels imposteurs: leur identifiant d'utilisateur et / ou de groupe, comme celui de l'administrateur, sera «0». Jetez un œil au fichier passwd dans le répertoire / etc /. Ce fichier contient un enregistrement pour chaque compte d'utilisateur normal et système qui existe déjà dans le système. Le premier champ contient le nom du compte (dans ce cas, root et ubuntu), et le second champ contient x au lieu du mot de passe (si le mot de passe existe, il sera crypté dans le fichier / etc / shadow). Mais les deux champs suivants contiennent l'ID utilisateur et groupe. Dans le cas d' ubuntu dans cet exemple, les deux ID sont 1000. Et l'administrateur, comme vous pouvez le voir, a des zéros ici.

 $ cat /etc/passwd root:x:0:0:root:/root:/bin/bash […] ubuntu:x:1000:1000::/home/ubuntu:/bin/bash 

Si vous rencontrez un utilisateur régulier avec un ID utilisateur ou groupe = 0, vous pouvez être assuré que le problème n'est pas net et que la situation doit être corrigée. Un moyen rapide et facile d'identifier un tel problème est de vérifier le passwd avec la commande awk , qui affichera toutes les lignes dans le troisième champ dont il n'y a que 0. Dans mon cas (vous pouvez expirer), il n'y avait qu'une seule ligne de ce type - la racine. Vous pouvez l'exécuter à nouveau en remplaçant $ 4 par $ 3 - cela vérifiera le champ ID de groupe.

 $ awk -F: '($3 == “0”) {print}' /etc/passwd root:x:0:0:root:/root:/bin/bash 

Audit des ressources système


Plus il y a de choses dans votre système, plus il y a de chances que quelque chose se casse. Par conséquent, il est sage de suivre ce qui fonctionne et comment. Dans ce cas, nous parlons de ports réseau (si le port est «ouvert», alors par définition il devrait être une entrée), de services (si le service est actif, alors il devrait être possible de l'utiliser) et de programmes installés (si le programme est installé, il devrait être la capacité de l'exécuter).

Pour qu'un audit soit bénéfique, il doit être plus ou moins régulier. Comme nous sommes tous oublieux, il est préférable d'écrire des outils d'audit dans un script spécial qui sera non seulement exécuté régulièrement, mais idéalement analyser les résultats pour les rendre plus lisibles.

Ici, cependant, je vous présente trois outils d'audit clés qui vous aideront à afficher les ports ouverts, les services actifs et les packages logiciels inutiles. Votre tâche consiste à automatiser tout cela.

Balayage de port


Un port est considéré comme «ouvert» si un hôte exécute un processus qui écoute les demandes sur ce port. En gardant un œil sur vos ports ouverts, vous comprendrez mieux ce qui se passe exactement sur votre serveur.

Vous savez déjà que les ports HTTP (80) et SSH (22) devraient probablement être ouverts sur un serveur Web normal, ils ne vous surprendront donc pas. Mais il est beaucoup plus important de prêter attention aux autres résultats inattendus. La commande netstat affiche tous les ports ouverts, ainsi qu'une tonne d'informations sur leur utilisation.

Dans cet exemple, nous testons un serveur polyvalent très typique, et la commande -n indique à netstat d'activer tous les ports et adresses numériques. -l inclut uniquement les sockets d'écoute et -p ajoute l'ID de processus du programme d'écoute. Naturellement, si vous voyez quelque chose - agissez.

 # netstat -npl Active Internet connections (only servers) Proto Local Address Foreign Address State PID/Program name tcp 127.0.0.1:3306 0.0.0.0:* LISTEN 403/mysqld tcp 0.0.0.0:139 0.0.0.0:* LISTEN 270/smbd tcp 0.0.0.0:22 0.0.0.0:* LISTEN 333/sshd tcp 0.0.0.0:445 0.0.0.0:* LISTEN 270/smbd tcp6 :::80 :::* LISTEN 417/apache2 […] 

Ces dernières années, ss plus en plus utilisé au lieu de netstat . Juste au cas où: si un soir vous vous trouvez dans une entreprise et que quelqu'un vous pose des questions sur SS, cet exemple (qui répertorie toutes les connexions SSH installées) devrait être suffisamment informatif pour que vous ne puissiez pas faire face à la saleté:

 $ ss -o state established '( dport = :ssh or sport = :ssh )' Netid Recv-Q Send-Q Local Address:Port Peer Address:Port tcp 0 0 10.0.3.1:39874 10.0.3.96:ssh timer:(keepalive,18min,0) 

Vérification des services actifs


Si vous prenez un instantané des services gérés par le system et actuellement actifs sur votre ordinateur, la machine vous aidera à identifier toute activité indésirable. La commande systemctl peut répertorier tous les services existants, puis leur liste peut être réduite à ceux dont la description contient enabled . Ainsi, seuls les services actifs seront retournés.

 # systemctl list-unit-files — type=service — state=enabled autovt@.service enabled bind9.service enabled cron.service enabled dbus-org.freedesktop.thermald.service enabled docker.service enabled getty@.service enabled haveged.service enabled mysql.service enabled networking.service enabled resolvconf.service enabled rsyslog.service enabled ssh.service enabled sshd.service enabled syslog.service enabled systemd-timesyncd.service enabled thermald.service enabled unattended-upgrades.service enabled ureadahead.service enabled 

Si vous trouvez quelque chose qui ne rentre évidemment pas systemctl , vous pouvez utiliser la commande systemctl pour arrêter le service et vous assurer qu'il ne redémarre pas au prochain démarrage.

 # systemctl stop haveged # systemctl disable haveged 

En fait, il n'y a rien de sombre et sombre dans le service haveged que j'arrête dans cet exemple: c'est un tel outil que je lance souvent pour créer une activité de système d'arrière-plan aléatoire lorsque je crée des clés de chiffrement.
Rechercher les programmes installés

Quelqu'un pourrait-il installer des programmes dans le système à votre insu? Eh bien, pour le découvrir, vous devez regarder. La commande yum list installed ou, dans le cas de Debian / Ubuntu, dpkg — list vous donnera un résumé détaillé, et la commande remove devrait supprimer tous les paquets dont nous n'avons pas besoin.

 # yum list installed # yum remove packageName 

Voici comment la même chose se fait dans Ubuntu:

 # dpkg --list # apt-get remove packageName 

Il est également utile de garder une trace des modifications apportées à vos fichiers de configuration système - nous en parlerons au chapitre 11.

Source: https://habr.com/ru/post/fr425571/


All Articles