Sécuriser son serveur

La plupart des attaques que va subir votre serveur seront réalisées par des robots. Ce sont des petits programmes qui vont scanner le système afin de déceler une faille de sécurité et l’exploiter.

Il est aussi possible qu’un pirate mène l’attaque. Ce dernier plus intelligent sera le plus dangereux.

Voici plusieurs types d’attaques que peut subir votre serveur, et comment s’en protéger :

  • Un service (http, mail, ssh) est directement attaqué afin d’en exploiter une faille de sécurité connue. Les mises à jour de sécurité veillent à garder les services fiables (voir Mises à jour de sécurite).
  • Un attaquant peut effectuer de nombreuses requêtes afin de déceler sur quels ports il peut trouver une faille. Un parefeu (voir Parefeu) va limiter le nombre de ports à l’écoute et portsentry (voir Portsentry) va empêcher que l’on scanne les ports ouverts sur votre serveur.
  • Si un service est disponible (http ou ssh par exemple), un attaquant peut essayer des milliers de combinaisons d’identifiants et mots de passe. Cela a deux effets. Tout d’abord, votre serveur est surchargé et ralenti. De plus, un essai de connexion peut malheureusement réussir à un moment donné après des milliers d’essais. Fail2ban (voir Fail2ban) va bannir ceux qui tenteraient ce passage en force.

Imaginez votre serveur un peu comme votre maison.

En général, vous fermez les portes à clé, comme le parefeu ferme certains ports.

Un cambrioleur va d'abord repérer si des portes sont ouvertes. C'est équivalent à scanner les ports de votre serveur (voir Portsentry).

Vous pouvez aussi rajouter une alarme à vote maison, avec un mot de passe pour la désactiver. Fail2ban tient ce rôle en quelque sorte, sauf que lui il jette les cambrioleurs à coups de pieds au fesses s'ils échouent à s'identifier.

Cette liste n’est bien sûr pas exhaustive. Bien qu’un serveur auto-hébergé présente moins d’intérêt pour un pirate que ceux de google et risque donc moins d’être attaqué, veillez à vous renseigner un minimum sur la façon de sécuriser votre serveur. L’utilisation de fail2ban et de “phrases de passe” longues vous permettront d’esquiver une grande partie des assauts.

Mises à jour de sécurité

Une des choses les plus importantes pour prendre soin de son serveur, c’est de le mettre à jour et ainsi profiter des patchs que debian propose.

Petite piqûre de rappel pour mettre votre système debian à jour :

# apt-get update
# apt-get upgrade
# apt-get dist-update

Unattended-upgrades

Afin d’effectuer les mises à jours de sécurité, il est possible de configurer votre serveur pour qu’il vous envoie un mail lorsque ces mises à jours sont disponibles.

Tout d’abord, installez les paquets suivants :

# apt-get install unattended-upgrades apt-listchanges

Il faut ensuite configurer unattended-upgrades en éditant le fichier /etc/apt/apt.conf.d/50unattended-upgrades.

Dans la partie contenant Unattended-Upgrade::Origins-Pattern {, vous pouvez décommenter (en retirant les // au début de ligne) les sections de debian à mettre à jour automatiquement. Je vous le déconseille, le mieux étant toujours de faire la mise à jour directement “à la main”.

Par contre, pour être averti par mail, il est nécessaire de décommenter la ligne suivante :

//Unattended-Upgrade::Mail "root";

Enfin, pour activer unattended-upgrades, lancez la commande suivante :

dpkg-reconfigure -plow unattended-upgrades

Il y a alors un fichier /etc/apt/apt.conf.d/20auto-upgrades de créé, qui contient :

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Pour éviter que les mises à jour soient automatiques, changez la deuxième ligne pour avoir :

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "0";

Parefeu

Un parefeu, c'est un programme qui va faire la douane à l'entrée de votre serveur. Selon les règles que vous lui avez donné, il ne laissera passer les visiteurs que par les ports que vous avez ouvert.

Un parefeu bien configuré est essentiel pour la sécurité de votre serveur. C’est un premier rempart contre les attaques des pirates ou robots.

Le paquet arno-iptables-firewall est parfait pour faciliter cette opération. Lors de l’installation, il vous posera quelques questions pour configurer le parefeu. En cas de modifications ultérieures, modifiez le fichier

/etc/etc/arno-iptables-firewall/conf.d/00debconf.conf

Ce fichier ressemble à ceci :

EXT_IF="eth0"
EXT_IF_DHCP_IP=1
OPEN_TCP="22 443 587 80 25 143 993"
OPEN_UDP=""
INT_IF="192.168.1.66"
NAT=0
INTERNAL_NET=""
NAT_INTERNAL_NET=""
OPEN_ICMP=0

La partie qui nous intéresse principalement, c’est les variables OPEN_TCP et OPEN_UDP, dans lesquelles on peut rajouter des numéros de ports.

Pensez juste à relancer le parefeu une fois vos modifications terminées :

# service arno-iptables-firewall restart

Certains préféreront utiliser ufw pour gérer leur parefeu, qui est tout aussi valable. Voici quelques commandes utiles :

  • ufw default deny : refuse tout en entrée. Il faut entrer cette commande en premier, puis seulement ensuite ouvrir les ports au cas par cas.
  • ufw allow 22/tcp : autorise le port 22 en TCP.
  • ufw enable : Active ufw après les modifications

Par défaut, iptables, le parefeu de linux (enfin la surcouche à netfilter pour les puristes) laisse tout passer. C'est pourquoi il est important de tout fermer en entrée du serveur, puis ouvrir uniquement ce que vous voulez rendre disponible au monde.

Il existe 2 types de protocole : TCP et UDP. Chaque port peut être ouvert seulement pour ne laisser passer qu'un seul de ces deux protocoles. Il n'est pas nécessaire de bien comprendre la différence entre les 2. Il s'agit très grossièrement de la façon dont le serveur et le visiteur vont se parler.

Fail2ban

Fail2ban est sans doute le logiciel le plus important à avoir pour protéger votre serveur. C’est une sorte de gardien intelligent. Il va surveiller qui tente d’accéder à votre serveur, et si cette personne échoue plusieurs fois (par exemple à cause d’un mauvais mot de passe), alors elle est bannie et on ne l’écoute plus.

Fail2ban fonctionne avec ssh, mais aussi le serveur mail postfix et dovecot, ainsi que d’autres services comme le ftp.

Pour l’installer, c’est toujours aussi simple :

# apt-get install fail2ban

Mieux comprendre la configuration

La configuration de fail2ban se déroule dans le fichier /etc/fail2ban/jail.local.

Ce fichier est découpé en plusieurs sections que l’on repère facilement puisqu’elles sont entre crochets : [section].

La première section est [DEFAULT] et permet de définir des valeurs qui seront utilisée par la suite, sauf si vous les modifiez dans les sections.

Voyons ce que signifient certaines options :

  • port : permet de préciser sur quel port le service écoute. Par exemple, pour nginx, c’est le 80 ou http.
  • bantime : C’est le nombre de secondes pendant lequel les éventuels attaquants seront bannis. Évitez les chiffres ronds, puisque ce sont souvent des robots qui réalisent les attaques.
  • maxretry : Nombre d’essais autorisés pendant le temps findtime
  • findtime : Nombre de secondes pendant lequel on regarde si l’attaquant tente un nouvel assaut.
  • logpath : l’emplacement du fichier de log (fichier qui enregistre l’activité du service)

Vous avez bien sûr la possibilité de créer vos propres filtres, mais cela relève d’une documentation propre à fail2ban. Vous pouvez toutefois visiter le site de fail2ban si le sujet vous intéresse.

Dans tous les cas, je vous conseille de jeter un œil au fichier /etc/fail2ban/jail.conf pour d’autres exemples.

Configuration rapide

Je vous propose ci-dessous une configuration déjà toute prête. Pour le fichier /etc/fail2ban/jail.local :

[DEFAULT]
ignoreip = 127.0.0.1/8
ignorecommand =
bantime  = 610
findtime = 600
maxretry = 3
backend = auto
usedns = warn
destemail = root@localhost
sendername = Fail2Ban
sender = fail2ban@localhost
banaction = iptables-multiport
mta = sendmail
protocol = tcp
action = %(action_mwl)s

[ssh]
enabled  = true
port  = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3

[pam-generic]
enabled  = true
filter   = pam-generic
port     = all
banaction = iptables-allports
logpath  = /var/log/auth.log
maxretry = 3

[xinetd-fail]
enabled   = true
filter    = xinetd-fail
port      = all
banaction = iptables-multiport-log
logpath   = /var/log/daemon.log
maxretry  = 2

[ssh-ddos]
enabled  = true
port  = ssh
filter   = sshd-ddos
logpath  = /var/log/auth.log
maxretry = 3

[ssh-route]
enabled = false
filter = sshd
action = route
logpath = /var/log/sshd.log
maxretry = 6

[ssh-iptables-ipset4]
enabled  = false
port  = ssh
filter   = sshd
banaction = iptables-ipset-proto4
logpath  = /var/log/sshd.log
maxretry = 6

[ssh-iptables-ipset6]
enabled  = false
port  = ssh
filter   = sshd
banaction = iptables-ipset-proto6
logpath  = /var/log/sshd.log
maxretry = 6

[php-url-fopen]
enabled = false
port    = http,https
filter  = php-url-fopen
logpath = /var/www/*/logs/access_log

[nginx-http-auth]
enabled = true
filter  = nginx-http-auth
port    = http,https
logpath = /var/log/nginx/error.log

[vsftpd]
enabled  = false
port     = ftp,ftp-data,ftps,ftps-data
filter   = vsftpd
logpath  = /var/log/vsftpd.log
maxretry = 6

[postfix]
enabled  = true
port     = smtp,ssmtp,submission
filter   = postfix
logpath  = /var/log/mail.log

[sasl]
enabled  = true
port     = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
filter   = postfix-sasl
logpath  = /var/log/mail.log

[dovecot]
enabled = true
port    = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
filter  = dovecot
logpath = /var/log/mail.log

[ssh-blocklist]
enabled  = false
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
           sendmail-whois[name=SSH, dest="%(destemail)s",\
           sender="%(sender)s", sendername="%(sendername)s"]
           blocklist_de[email="%(sender)s", apikey="xxxxxx",\
           service="%(filter)s"]
logpath  = /var/log/sshd.log
maxretry = 20

[nginx-404]
enabled  = true
filter   = nginx-404
action   = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp]
logpath = /var/log/nginx*/*error*.log
maxretry = 2
findtime  = 6
bantime  = 1200

[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/nginx*/*error*.log
bantime = 630
maxretry = 3

[nginx-login]
enabled = true
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port="http,https"]
logpath = /var/log/nginx*/*error*.log
bantime = 630
maxretry = 3

[nginx-badbots]
enabled  = true
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
logpath = /var/log/nginx*/*error*.log
bantime  = 87000
maxretry = 1

[nginx-noscript]
enabled = true
action = iptables-multiport[name=NoScript, port="http,https"]
filter = nginx-noscript
logpath = /var/log/nginx*/*error*.log
maxretry = 6
bantime  = 87000

[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"]
filter = nginx-proxy
logpath = /var/log/nginx*/*error*.log
maxretry = 0
bantime  = 87000

La fin de cette configuration nécessite des filtres pour nginx qu’il faut ajouter dans /etc/fail2ban/filter.d.

  • Fichier nginx-404.conf

    [Definition]
    failregex = <HOST> - - [.*?] ".*?" 4(0[0-9]|1[0-5])
    ignoreregex =
    
  • Fichier nginx-proxy.conf

    # Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
    #
    # Block IPs trying to use server as proxy.
    #
    # Matches e.g.
    # 192.168.1.1 - - "GET http://www.something.com/
    #
    [Definition]
    failregex = ^<HOST> -.*GET http.*
    ignoreregex =
    
  • Fichier nginx-noscript.conf

    # Noscript filter /etc/fail2ban/filter.d/nginx-noscript.conf:
    #
    # Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
    #
    # Matches e.g.
    # 192.168.1.1 - - "GET /something.php
    #
    [Definition]
    failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\scgi)
    ignoreregex =
    
  • Fichier nginx-auth.conf

    # Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
    #
    # Blocks IPs that fail to authenticate using basic authentication
    #
    [Definition]
    failregex = no user/password was provided for basic \
    authentication.*client: <HOST>
                user .* was not found in.*client: <HOST>
                user .* password mismatch.*client: <HOST>
    ignoreregex =
    
  • Fichier nginx-login.conf

    # Login filter /etc/fail2ban/filter.d/nginx-login.conf:
    #
    # Blocks IPs that fail to authenticate
    # using web application's log in page
    #
    # Scan access log for HTTP 200 + POST /sessions => failed log in
    [Definition]
    failregex = ^<HOST> -.*POST /sessions HTTP/1\.." 200
    ignoreregex =
    

À la fin de la configuration, il faut recharger fail2ban :

# service fail2ban restart

Portsentry

Portsentry permet de se munir contre le scan des ports vulnérables sur votre serveur.

Installez le paquet portsentry.

Ensuite, on va procéder à la configuration. Au lieu de coller ci-dessous une grande quantité de texte, vérifier simplement que le contenu écrit est bien présent dans les fichiers donnés :

  • Fichier /etc/portsentry/portsentry.conf

    TCP_PORTS="1,11,15,79,111,119,143,540,635,1080,1524,2000,5742,6667,\
      12345,12346,20034,27665,31337,32771,\
      32772,32773,32774,40421,49724,54320"
    UDP_PORTS="1,7,9,69,161,162,513,635,640,641,700,37444,34555,\
      31335,32770,32771,32772,32773,32774,31337,54321"
    ADVANCED_PORTS_TCP="1024"
    ADVANCED_PORTS_UDP="1024"
    ADVANCED_EXCLUDE_TCP="113,139"
    ADVANCED_EXCLUDE_UDP="520,138,137,67"
    IGNORE_FILE="/etc/portsentry/portsentry.ignore"
    HISTORY_FILE="/var/lib/portsentry/portsentry.history"
    BLOCKED_FILE="/var/lib/portsentry/portsentry.blocked"
    RESOLVE_HOST = "0"
    BLOCK_UDP="1"
    BLOCK_TCP="1"
    KILL_ROUTE="/sbin/route add -host $TARGET$ reject"
    KILL_HOSTS_DENY="ALL: $TARGET$ : DENY"
    KILL_RUN_CMD="/sbin/iptables -I INPUT -s $TARGET$ -j DROP && \
        /sbin/iptables -I INPUT -s $TARGET$ -m limit \
        --limit 3/minute --limit-burst 5 -j LOG \
        --log-level debub --log-prefix 'Portsentry: dropping: '"
    SCAN_TRIGGER="0"
    
  • Fichier /etc/default/portsentry :

    TCP_MODE="atcp"
    UDP_MODE="audp"
    

Et pour finir, on recharge portsentry :

# service portsentry restart

Redémarrages nécessaires

Il est parfois nécessaire de redémarrer certains services, voire le serveur après des mises à jours.

Si vous ne savez pas trop ce qui doit être redémarré, sachez qu’il existe le paquet needrestart.

Il ne vous restera plus qu’à lancer la commande needrestart -kl, pour voir apparaître des messages indiquant ce qui doit être relancé.

Ce qui est génial, c’est que vous verrez ce message après une mise à jour, car needrestart sera automatiquement lancé.

De façon générale, vous pouvez relancer un service avec la commande suivante :

# /etc/init.d/nom_du_service restart

Chasseur de rootkit

Un rootkit est un petit programme qui peut permettre à un attaquant d’obtenir les droits super-utilisateur sur votre serveur.

Il existe heureusement quelques outils pour vérifier si votre système contient un rootkit, comme par exemple rkhunter

Pour l’installer, il faut juste ajouter le paquet du même nom :

# apt-get install rkhunter

Son fichier de configuration est /etc/rkhunter.conf. Pour qu’il fonctionne bien, je vous propose de décommenter, modifier ou ajouter les lignes suivantes :

ALLOWHIDDENDIR="/dev/.udev";
ALLOWHIDDENDIR="/dev/.static";
MAIL-ON-WARNING="root@localhost"
SCRIPTWHITELIST=/usr/bin/unhide

De cette façon vous serez averti par mail si un rootkit est détecté.

Lancez ensuite ces commandes pour préparer rkhunter

rkhunter --update
rkhunter --propupdate

Pour tester votre système, il faut lancer la commande :

rkhunter --check

Notez que le système est vérifié une fois par jour grâce à une tâche cron par défaut.

Pour que les informations pour rkhunter soient mises à jour après chaque exécution de apt, vous pouvez créer le fichier /etc/apt/apt.conf/98-rkhunter et mettre dedans :

DPkg::Post-Invoke {
    "rkhunter --update;"
    "rkhunter --propupdate";
};

Sécurisation minimale de MySQL

Si vous avez choisi d’installer la base de données MySQL, il est conseillé de lancer la commande mysql_secure_installation. Il vous sera posé une série de questions afin de sécuriser la base de données.1

Cela ressemblera à ça :

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist
 ... Failed!  Not critical, keep moving...
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...



All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

Suggestions d’améliorations avec lynis

Lynis est un petit programme qui peut scanner votre serveur et vous suggérer des améliorations. Il vous suffit d’installer le paquet lynis (eh oui quelle surprise!)

Ensuite, lancez simplement la commande

lynis -c

Vous verrez alors plusieurs scans et conseils à l’écran. L’ensemble peut être retrouvé dans /var/log/lynis.log. Cherchez les lignes contenant Suggestion pour voir des propositions afin d’améliorer la sécurité de votre serveur.

1. Merci PengouinPdt pour l’info

results matching ""

    No results matching ""