Changelog :
- modification anti-w00tw00t dans Fail2ban (nginx-badbots.conf) le 17/04
- rédaction initial du tuto le 28/02

Note:
- Logwatch fonctionne maintenant avec nginx le 05/03
Si vous avez déjà suivi le tuto sécurité avant cette date, La manip' est expliqué en détail ici
Tuto sur la sécurisation de base

Adaptation à Nginx de l'ancien tuto pour les parties Logwatch, Fail2ban et Logs

Serveur Mail

On va commencer par mettre en place un serveur mail léger pour avoir un retour sur ce qui se passe sur notre serveur.

Installation de Postfix :
apt-get install -f postfix mailutils
Lors de l'installation, laisser la configuration par défaut et dans "Nom de courrier" mettre le nom de votre serveur.

On teste :
echo 'Salut, je suis un email.' | mail -s 'Hello world' votre_mail@gmail.com
Redirection des mails root :
nano /etc/aliases
Et rajouter à la fin :
root: votre_mail@gmail.com
Pour valider les changements :
newaliases
Nouveau test :
echo 'Salut, je suis un email.' | mail -s 'Hello world' root
Mail lors d'une connexion root :

On va mettre en place un mail lors des connexions ssh root, vous recevrez ainsi un mail à chaque connexion sur le compte.
nano /root/.bashrc
Ajouter à la fin :
echo 'Acces Shell Root le ' `date` `who` | mail -s 'Connexion serveur via root' root
Pour envoyer des mails via le système, on n'a pas besoin d'avoir Postfix qui écoute sur le port 25 :
nano /etc/postfix/master.cf
Commenter la ligne suivante (avec #) :
#smtp inet n - - - - smtpd
On relance Postfix :
/etc/init.d/postfix restart
Si les mails coincent avec Gmail/Hotmail sur les nouveaux Kimsufi, c'est parce que par défaut l'IPV6 n'a pas de reverse configuré.

Pour éviter le souci on va forcer l'IPV4 :
nano /etc/postfix/main.cf
Et ajouter à la fin :
inet_protocols=ipv4
Relancer Postfix :
/etc/init.d/postfix restart
On a fini de configurer le serveur pour qu'il nous envoie des mails en cas de problèmes.

Logwatch

Logwatch est un programme qui vous envoie un récapitulatif de ce qui se passe sur votre serveur tout les jours.

Installation :
apt-get install -f logwatch
Configuration basique :
nano /usr/share/logwatch/default.conf/logwatch.conf
Modifier les valeurs suivantes :
Output = mail
MailTo = root
On enregistre et on sort.

Configuration pour Nginx

On va créer un premier fichier :
nano /usr/share/logwatch/default.conf/logfiles/nginx.conf
Et copier coller :
########################################################
# Define log file group for nginx
########################################################

# What actual file? Defaults to LogPath if not absolute path….
LogFile = nginx/*access.log
LogFile = nginx/*access.log.1
LogFile = nginx/*error.log
LogFile = nginx/*error.log.1

# If the archives are searched, here is one or more line
# (optionally containing wildcards) that tell where they are…
#If you use a “-” in naming add that as well -mgt
Archive = nginx/*access.log*
Archive = nginx/*error.log*

# Expand the repeats (actually just removes them now)
*ExpandRepeats

# Keep only the lines in the proper date range…
*ApplyhttpDate

# vi: shiftwidth=3 tabstop=3
Et on passe au deuxième fichier :
cp /usr/share/logwatch/default.conf/services/http.conf /usr/share/logwatch/default.conf/services/nginx.conf
mv /usr/share/logwatch/default.conf/services/http.conf /usr/share/logwatch/default.conf/services/http.conf.bak
On édite :
nano /usr/share/logwatch/default.conf/services/nginx.conf
Et on modifie en début de fichier :
Title = “nginx”
LogFile = nginx
Et enfin le dernier fichier (rien à modifier là) :
cp /usr/share/logwatch/scripts/services/http /usr/share/logwatch/scripts/services/nginx
On relance :
logwatch restart
Et vous devriez recevoir un mail avec le récapitulatif et ensuite un mail journalier.

Pour jeter un œil sur les logs du jour :
logwatch --range today

Sécurisation SSH

Les principales attaques sur internet se font sur les ports 21/22 et 80
On va donc changer le port SSH et interdire la connexion en root, on commence par créer un utilisateur qui servira à se connecter en console, ça ne doit pas être un utilisateur de la seedbox, pour vivre heureux vivons cachés :
mkdir /home/votre_user
useradd -s /bin/bash votre_user
passwd votre_user
chown -R votre_user:votre_user /home/votre_user
On édite :
nano /etc/ssh/sshd_config
Modifier les valeurs suivantes :
Port 22025 # Choisissez un n° de port perso et non utilisé , pas celui là...
PermitRootLogin no

# Choix des utilisateurs autorisés à se connecter,
# ajouter l'user qu'on a créé plus haut, plus les utilisateurs de ruTorrent pour qu'ils conservent l'accès en SFTP.
AllowUsers votre_user userbox1 userbox2
Sans virgule, juste un espace entre chaque users.

On sauvegarde avec Ctrl+x et on relance le daemon :
/etc/init.d/ssh restart
On teste sa configuration maintenant sans fermer la fenêtre actuelle, en cas de problème remettre le port 22 ou essayer avec un autre. Vous ne pourrez plus vous connecter en root ! Il va falloir vous connecter avec l'utilisateur créé au début.

Une fois loggé, la commande : su vous permettra de passer root
    Fail2Ban

    Qu'on ne présente plus, va nous permettre de bannir les tentatives d’accès non autorisées.
    Si vous avez utilisé le script d'installation automatique ruTorrent, Fail2ban est déjà installé et configuré.
    Ne pas créer le fichier jail.local, il est déjà présent ! Il vous reste à modifier le port ssh et la partie mail dans le fichier.
    Tout le reste est déjà fait !
    Installation de Fail2ban :
    apt-get install -f fail2ban
    Créer le fichier jail.local en faisant une copie de jail.conf :
    cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
    Configuration du fichier jail.local :
    nano /etc/fail2ban/jail.local
    Modifier les valeurs suivantes :
    Note: J'ai laissé le conf de vsftpd sur "true", si vous ne l'avait pas installé vous laissez sur "false",
    on adaptera en fonction du tuto Nginx plus tard.

    destemail = root
    
    # "ignoreip" can be an IP address, a CIDR mask or a DNS host
    ignoreip = 127.0.0.1/8 XXX.XXX.XXX.XXX  #<= Votre IP "maison" habituelle si fixe
    bantime  = 600
    maxretry = 5
    
    # Activation de fail2ban sur le ssh
    [ssh]
    enable = true
    port = 22025 # Votre n° de port perso
    
    # Il faut ensuite mettre des "true" sur les services que vous voulez
    # surveillez, et ajouter au besoin les services absents :
    
    # Ajouter pour nginx
    [nginx-auth]
    
    enabled  = true
    port  = http,https
    filter   = nginx-auth
    logpath  = /var/log/nginx/*error.log
    banaction = iptables-multiport
    maxretry = 15
    
    [nginx-badbots]
    
    enabled  = true
    port  = http,https
    filter = nginx-badbots
    logpath = /var/log/nginx/*access.log
    banaction = iptables-multiport
    maxretry = 5
    
    # Pour vsftpd, il est dans le fichier donc vous modifiez juste false en true si besoin
    [vsftpd]
    
    enabled  = true
    port     = ftp,ftp-data,ftps,ftps-data
    filter   = vsftpd
    logpath  = /var/log/vsftpd.log
    banaction = iptables-multiport
    # or overwrite it in jails.local to be
    # logpath = /var/log/auth.log
    # if you want to rely on PAM failed login attempts
    # vsftpd's failregex should match both of those formats
    maxretry = 5
    On va créer nos filtres pour Nginx :

    1)
    nano /etc/fail2ban/filter.d/nginx-auth.conf
    Et on colle (sans modifier) :
    ## FICHIER /etc/fail2ban/filter.d/nginx-auth.conf ##
    [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 =
    2)
    nano /etc/fail2ban/filter.d/nginx-badbots.conf
    Et coller :
    # Fail2Ban configuration file
    # Author: Patrik 'Sikevux' Greco <sikevux@sikevux.se>
    
    [Definition]
    
    # Option: failregex
    # Notes.: regex to match access attempts to setup.php
    # Values: TEXT
    
    failregex = ^<HOST> .*?"GET.*?\/setup\.php.*?" .*?
    
    # Anti w00tw00t
                ^<HOST> .*?"GET .*w00tw00t.* 400
    
    # try to access to directory
                ^<HOST> .*?"GET .*admin.* 403
                ^<HOST> .*?"GET .*admin.* 404
                ^<HOST> .*?"GET .*install.* 404
                ^<HOST> .*?"GET .*dbadmin.* 404
                ^<HOST> .*?"GET .*myadmin.* 404
                ^<HOST> .*?"GET .*MyAdmin.* 404
                ^<HOST> .*?"GET .*mysql.* 404
                ^<HOST> .*?"GET .*websql.* 404
                ^<HOST> .*?"GET .*webdb.* 404
                ^<HOST> .*?"GET .*webadmin.* 404
                ^<HOST> .*?"GET \/pma\/.* 404
                ^<HOST> .*?"GET .*phppath.* 404
                ^<HOST> .*?"GET .*admm.* 404
                ^<HOST> .*?"GET .*databaseadmin.* 404
                ^<HOST> .*?"GET .*mysqlmanager.* 404
                ^<HOST> .*?"GET .*phpMyAdmin.* 404
                ^<HOST> .*?"GET .*xampp.* 404
                ^<HOST> .*?"GET .*sqlmanager.* 404
                ^<HOST> .*?"GET .*wp-content.* 404
                ^<HOST> .*?"GET .*wp-login.* 404
                ^<HOST> .*?"GET .*typo3.* 404
                ^<HOST> .*?"HEAD .*manager.* 404
                ^<HOST> .*?"GET .*manager.* 404
                ^<HOST> .*?"HEAD .*blackcat.* 404
                ^<HOST> .*?"HEAD .*sprawdza.php.* 404
                ^<HOST> .*?"GET .*HNAP1.* 404
                ^<HOST> .*?"GET .*vtigercrm.* 404
                ^<HOST> .*?"GET .*cgi-bin.* 404
                ^<HOST> .*?"GET .*webdav.* 404
                ^<HOST> .*?"GET .*web-console.* 404
                ^<HOST> .*?"GET .*manager.* 404
    # Option: ignoreregex
    # Notes.: regex to ignore. If this regex matches, the line is ignored.
    # Values: TEXT
    #
    ignoreregex =
    Et on redémarre fail2ban pour finir :
    /etc/init.d/fail2ban restart
    Pour recevoir un email détaillé à chaque blocage.

    Toujours dans le fichier jail.local :
    nano /etc/fail2ban/jail.local
    Chercher les lignes :
    # Choose default action.  To change, just override value of 'action' with the
    # interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
    # globally (section [DEFAULT]) or per specific section
    action = %(action_)s
    Et modifier :
    action = %(action_)s
    En :
    action = %(action_mwl)s
    Et on redémarre Fail2ban :
    /etc/init.d/fail2ban restart
    Vous recevrez un mail à chaque ban.

    Facultatif

    Pour personnaliser vos messages d'alerte (Nom de serveur en "Objet" etc...)

    Ça se passe dans /etc/fail2ban/action.d/

    Éditer et adapter :
    nano /etc/fail2ban/action.d/sendmail.conf
    
    nano /etc/fail2ban/action.d/sendmail-whois.conf
    
    nano /etc/fail2ban/action.d/sendmail-whois-lines.conf
    Et on redémarre après modif' :
    /etc/init.d/fail2ban restart
    Pas de panique avec la rafale de 6 ou 7 mails au démarrage... C'est bien plus calme après !

    Portsentry

    Détection et blocage de “scan de ports”, ça va nous permettre de masquer notre nouveau port SSH entre autre.

    Note: Portsentry ne bloque rien par défaut il se contente de logger les scans de votre serveur.
    Il faut le configurer, ce que l’on va tout de suite faire en commençant par white-lister certaines IP.

    Installation :

    apt-get install portsentry

    Configuration :

    nano /etc/portsentry/portsentry.ignore.static

    Dans cet exemple nous allons ajouter le range d’IP de Google & les nôtres :

    # IP du serveur
    x.x.x.x
    # Votre IP maison si fixe par sécurité
    x.x.x.x
    # Plage d'IP Google
    66.249.64.0/19

    Une fois que cela est fait, il faut modifier la configuration :

    nano /etc/portsentry/portsentry.conf

    Comme expliqué auparavant Portsentry ne bloque aucune ip par défaut, il faut modifier cette configuration en passant à " 1 " les variables suivantes :

    ##################
    # Ignore Options #
    ##################
    ...
    # 0 = Do not block UDP/TCP scans.
    # 1 = Block UDP/TCP scans.
    # 2 = Run external command only (KILL_RUN_CMD)
     
    BLOCK_UDP="1"
    BLOCK_TCP="1"
    ...

    La section "Dropping Routes"
    Chercher et vérifier que la lignes suivante est bien décommentée:

    # Newer versions of Linux support the reject flag now. This
    # is cleaner than the above option.
    KILL_ROUTE="/sbin/route add -host $TARGET$ reject"

    La section TCP Wrappers
    On continue, Chercher et vérifier que les lignes suivantes sont bien décommentées:

    ###############
    # TCP Wrappers#
    ###############
    ...
    KILL_HOSTS_DENY="ALL: $TARGET$ : DENY"

    Et ajouter dans la partie External Command :

    ###################
    # External Command#
    ###################
    ...
    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 debug --log-prefix 'Portsentry: dropping: '"

    modifier (et décommenter)

    #KILL_RUN_CMD_FIRST = "0"

    en

    KILL_RUN_CMD_FIRST = "1"

    et modifier

    SCAN_TRIGGER="0"

    en

    SCAN_TRIGGER="1"

    Il vaut mieux utiliser le mode atcp et audp pour une détection automatique des ports utilisés, il faut donc éditer le fichier /etc/default/portsentry :

    nano /etc/default/portsentry

    On édite :

    # /etc/default/portsentry
    #
    # This file is read by /etc/init.d/portsentry. See the portsentry.8
    # manpage for details.
    #
    # The options in this file refer to commandline arguments (all in lowercase)
    # of portsentry. Use only one tcp and udp mode at a time.
    #
    TCP_MODE="atcp"
    UDP_MODE="audp"

    Maintenant vous pouvez redémarrer Portsentry :

    /etc/init.d/portsentry restart

    La commande en dessous marche aussi en cas de soucis :

    service portsentry restart

    Facultatif

    Deux heures après voir installé Portsentry, allez jeter un œil sur le log pour vérifier si des IPs ont déjà été bloquées :

    cat /etc/hosts.deny

    Surprise il y a déjà du monde...

    Pour dé-bannir un user kické par erreur, cherchez son IP dans :

    nano /etc/hosts.deny

    l'effacer et redémarrer. Ça doit suffire à régler le soucis.
    Si le blocage persiste, vous pouvez tenter:

    route del -host IP reject

    Pour avoir plus d'infos sur le port qui a déclenché le blocage + date/heure:

    cat /var/lib/portsentry/portsentry.history
    Surveillance de notre log d’accès à Rutorrent et bannissement
    Si vous avez utilisé le script d'installation automatique de ruTorrent, la création de la page de log html est déjà intégré !
    Alors voilà, n'étant pas trop fan de la console le matin j'ai trouvé un moyen ludique de garder un œil sur mes logs d'accès sans que ce ne soit trop prenant au café.

    On va utiliser un utilitaire de colorisation de log : CCZE, qui permet au passage de générer une page html Exemple ici (j'ai masqué toutes les ip pour la démo bien sur).


    1er Partie

    On crée le dossier qui va recevoir la page html :
    mkdir /var/www/rutorrent/logserver
    On change le proprio du dossier :
    chown www-data:www-data /var/www/rutorrent/logserver
    On installe maintenant CCZE :
    apt-get install ccze
    On crée un dossier pour recevoir notre script et on se déplace dedans :
    mkdir /usr/share/mes-scripts/
    cd /usr/share/mes-scripts/
    On va maintenant créer un fichier logserver.sh :
    nano /usr/share/mes-scripts/logserver.sh
    Et on colle en modifiant USER par le votre :
    #!/bin/bash
    #
    # Remplacer USER par votre conf, exemple pour un user "exrat" :
    #    sed  -i '/EXRAT\ HTTP/d' access.log
    #
    if [ -e /var/log/nginx/rutorrent-access.log.1 ]; then
        # Récupération des logs (J et J-1) et fusion
        cp /var/log/nginx/rutorrent-access.log /tmp/access.log.tmp
        cp /var/log/nginx/rutorrent-access.log.1 /tmp/access.log.1
        cd /tmp
        cat access.log.1 access.log.tmp > access.log
    else
    cd /tmp
        cp /var/log/nginx/rutorrent-access.log /tmp/access.log
    fi
    
    # Nettoyage
    sed -i '/plugins/d' access.log
    sed -i '/getsettings.php/ d' access.log
    sed -i '/setsettings.php/ d' access.log
    sed  -i '/USER\ HTTP/d' access.log
    
    # Si plusieurs colocs on ajoute leurs "USER" et on décommante les lignes ("#").
    #sed  -i '/USER\ HTTP/d' access.log
    #sed  -i '/USER\ HTTP/d' access.log
    #sed  -i '/USER\ HTTP/d' access.log
    
    # Création de la page html
    ccze -h < /tmp/access.log > /var/www/rutorrent/logserver/access.html
    On rend le script exécutable :
    chmod +x logserver.sh
    On teste le script :
    /usr/share/mes-scripts/logserver.sh
    La page html doit être créée à cette adresse :

    [url]http://ip_server/rutorrent/logserver/access.html[/url]

    Comme le monde est bien fait, tomcdj71 a adapté un plugin pour avoir l'icone et l'accès directement depuis ruTorrent :
    http://mondedie.fr/d/7430

    La page est protégé par votre pass rutorrent et vidé de toutes les lignes superflues pour n'avoir que les tentatives d'accès frauduleuses, et l'activité utile de la box.

    On ajoute un crontab pour que la page html soit rafraichie toutes les 6 heures histoire de garder à l’œil les tentatives récentes de nos amis russes et chinois :
    crontab -e
    Et on colle en bas :
    0 */6 * * * sh /usr/share/mes-scripts/logserver.sh
    On ferme et c'est fini, on aura un nouveau log à minuit, 6h, 12h et 18h, il n'y a plus qu'à bannir à tour de bras si le cœur vous en dit !

    Note: La manip' permet bien sûr de créer des pages html sur le même modèle avec n'importe quel fichier log (ou autre) que vous voudriez surveiller.

    Par exemple :
    ccze -h < /var/log/fail2ban.log > /var/www/rutorrent/logserver/fail2ban.html
    [url]http://ip_server/rutorrent/logserver/lighttpd.conf.html[/url] - Exemple d'un fichier de conf cliquable ici


    2ème Partie

    Donc maintenant qu'on a repéré un loulou ukrainien qui insiste un peu trop à la porte du serveur, et toujours dans le but de se simplifier la vie, je me suis bricolé un petit script couplé avec un alias pour bannir le fâcheux.

    Une fois fini, il n'y aura plus qu'à taper ban en console et rentrer l'ip pour le bloquer avec iptable.

    On crée (si on ne l'a pas fait plus haut) le dossier pour le script :
    mkdir /usr/share/mes-scripts/
    On se place à l’intérieur du dossier :
    cd /usr/share/mes-scripts/
    On crée un fichier :
    nano /usr/share/mes-scripts/ban.sh

    Et on colle :
    #!/bin/bash
    #
    echo -n "Entrer l'adresse IP à bannir : "
    read IP
    dig -x $IP +short
    echo -n -e "Bannir l'adresse IP\033[1;33m $IP \033[00m? y/n: "
    read ouinon
    if [ "$ouinon" = "y" ] || [ "$ouinon" = "Y" ]; then
    	iptables -I INPUT -s $IP -j DROP &
    fi
    if [ "$ouinon" = "n" ] || [ "$ouinon" = "N" ]; then
    	exit 0;
    fi
    echo "L'adresse IP $IP a été bannie définitivement"
    exit 0;
    chmod +x ban.sh
    Tant qu'à être là, on va faire la même manip' pour unban ça peut être utile.

    On crée le fichier :
    nano /usr/share/mes-scripts/unban.sh
    Et on colle :
    #!/bin/bash
    #
    echo -n "Entrer l'adresse IP à débloquer : "
    read IP
    dig -x $IP +short
    echo -n -e "Autoriser l'adresse IP\033[1;33m $IP \033[00m? y/n: "
    read ouinon
    if [ "$ouinon" = "y" ] || [ "$ouinon" = "Y" ]; then
    	iptables -D INPUT -s $IP -j DROP &
    fi
    if [ "$ouinon" = "n" ] || [ "$ouinon" = "N" ]; then
    	exit 0;
    fi
    echo "L'adresse IP $IP a été débloquée"
    exit 0;
    chmod +x unban.sh
    Fin de la première étape, maintenant on va créer deux alias :
    nano /root/.bashrc
    On repère les alias dans le fichier pour faire ça propre et on colle :
    alias ban='sh /usr/share/mes-scripts/ban.sh'
    alias unban='sh /usr/share/mes-scripts/unban.sh'
    On recharge son fichier .bashrc et c'est fini :
    . ~/.bashrc
    Pour bannir une ip : ban

    pour dé-bannir: unban

    Et on se laisse guider, pour ceux qui ont du mal à se souvenir de la commande iptable qui va bien, ça simplifie la vie .

    Les scripts donnent au passage le reverse dns de l'ip pour savoir sur qui on tape quand l'info est dispo.

    J'ai eu un peu mal à faire celui là, je débute en bash... Si vous avez un problème avec la couleur du script, vérifiez que Putty est bien en UTF-8.

    Ex.
    4 ans plus tard
    Répondre…