Wiki [Tuto/HowTo] [Debian/Ubuntu] Créer manuellement un Cluster Web

1
12
sept.
2018

Sommaire

Difficulté de ce tutoriel : Bidouilleur confirmé n'ayant pas peur de la ligne de commande.

Alice upload une musique sur son Nextcloud.

Introduction

Un cluster est un ensemble d'ordinateurs physique travaillant pour une tâche commune, augmentant ainsi la puissance de calcul et évitant la fin de service lorsque l'une d'elles tombe en panne.
Le désavantage est un coûts en énergie, en consommation réseau et en ressources machines. Ainsi dans le cas présent, par exemple, syncthing devra vérifier très régulièrement les modifications des fichiers du serveur web, et partager toutes modifications avec les autres membres de la grappe.
Chaque Frontend devra aussi, et de façon régulière, vérifier la présence en ligne de tout les nœuds se qui a aussi un couts.
Ainsi pour un unique utilisateur n'ayant pas besoin d'une forte puissance de calcul ni de Haut Disponibilité, le cluster gaspillera beaucoup plus d'énergie qu'un serveur fonctionnant de manière esseulé.
L'utilisation d'un Cluster n'est requise que si vous avez besoin de Haute Disponibilité (Hight Availability) et/ou de scalabilité (adapter la puissance machine en fonction de la demande).
Note : Je pars du principe que vous avez déjà un serveur de base de données installé sur une autre machine.
Note de la rédaction : L'automatisation sera traitée dans un autre article [lien_temporaire_en_attendant]

Logiciels utilisés :

Installer un Node

Les Nœuds ou Node en anglais d'un cluster web sont des serveurs web recevant des requêtes HTTP(s), exécutant des scripts et émettant des réponses.

  1. Installer les pré-requis : Note : ici on installe se qui est généralement pré-requis pour les CMS, certains paquets pourraient donc vous être inutile
( apt update ; apt-get install -y apache2 php php-fpm php-gd php-curl php-mysql openssl php-redis libapache2-mod-php php-mbstring php-zip php-dom php-ldap php-apcu libapache2-mod-rpaf php-imagick php-dev libsystemd-dev php-intl php-geoip ; a2enmod headers rewrite rpaf ssl env dir mime http2; a2dismod status )
  1. Installez et configurez syncthing en suivant le tuto : Partager le dossier /var/www/html entre vos différents serveur web apache2 (via syncthing) (src)

  2. Configurez les permissions de www-data et apache2 :

  • Ajoutez la ligne umask 0007 à la fin de /etc/apache2/envvars
echo "umask 0007" >> /etc/apache2/envvars
  • Ajoutez la ligne umask 0007 au début de /etc/init.d/apache2 juste après ### END INIT INFO
sudo nano /etc/init.d/apache2
  • Ajoutez la ligneumask 0007 à la fin du fichier /etc/profile Note : ces changements ne seront pris en compte qu'après redémarrage de la session de chaque utilisateurs (dans le cas de www-data => après reboot)
echo "umask 0007" >> /etc/profile
  1. Placez vos vhsot apache2 dans /etc/apache2/sites-available/ et activez les via
a2ensite chacun_de_vos_fichiers.conf
  1. Redémarrez la machine
( systemctl daemon-reload ; reboot )

Configurer PHP pour stocker les variables sessions dans un serveur cache Redis commun

Apache2

  1. Éditez /etc/php/*/apache2/php.ini
  2. Remplacez :
session.save_handler = files

par

session.save_handler = redis
  1. Ajoutez
session.save_path = "tcp://adresse_ip_redis:6379"
  1. Redémarrez le serveur apache2.
service apache2 restart

Sécurisation

Les serveurs peuvent fournir des informations compromettantes via divers outils de diagnostiques/maintenance incorporé. On citera entre-autre server-status d'apache2 qui ouvre un trou de sécurité. Ces informations sont utilisées par les pirates et agences malveillantes afin de dés-anonymiser des serveurs, en vue de les référencer avant d'éventuelles attaques. Il est fortement conseillé de supprimer l'accès à ses informations.

Rappel (déjà mis en place dans la commande d'installation) : Faire taire server-status d'apache2. :

sudo a2dismod status
sudo service apache2 restart
  • Entrez ensuite l'hostname de votre web service suivis de /server-status. Le serveur doit vous retourner une erreur 404 page not found.

Faire taire serverTokens :
Ajoutez dans /etc/apache2/apache2.conf

echo 'ServerTokens Prod' >> /etc/apache2/apache2.conf

Faire taire ServerSignature :
Ajoutez dans /etc/apache2/apache2.conf

echo 'ServerSignature Off' >> /etc/apache2/apache2.conf

Ajoutez encore une fois dans /etc/apache2/apache2.conf les lignes suivantes afin de forcer la prise en compte des fichiers .htaccess (nécessaire depuis ubuntu 18.04)

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Partager un dossier sur un Stockage Distant (Remote Storage)

Coté serveur

  1. Si plusieurs utilisateurs systèmes vont utiliser le dossier, adaptez le umask des utilisateurs ssh
    • Éditez /etc/ssh/sshd_config
sudo nano /etc/ssh/sshd_config
  • Cherchez (CTRL+W) Subsystem sftp /usr/lib/openssh/sftp-server et ajoutez -u 007 à la ligne comme suit (ndlr : utile?) :
Subsystem sftp /usr/lib/openssh/sftp-server -u 007
  1. Ajoutez umask 0007 dans /etc/profile ainsi que dans /home/userCommunSFTP/.profile (adaptez le dernier path au nom de votre ou vos utilisateurs)

  2. Redémarrez le serveur openssh

sudo service sshd restart
  1. Si vous (ré-)installez le serveur alors à ce stade sur tout les clients qui utilisent votre serveur, démontez puis remontez le(s) stockage(s) SSHSF.

  2. Forcez les permissions sur le dossier local (rws) :

sudo setfacl -dRm u::rwx,g::rwx /media/VOTRE_DOSSIER_LOCAL

Coté client

  1. Effectuer un montage SSHFS : [Tuto/HowTo] Configurer et monter SSHFS sécurisé via utilisateur dédié côté server (rap : lien mort, reposter le tuto)

  2. Dans la commande de montage de montage que vous indiquez dans /etc/fstab, ajoutez le paramètre umask=0007 comme suit : [A CHECKER]

userCommunSFTP@storageserver.network:/media/remote_path/   /media/mount_path/       fuse.sshfs              port=22,noatime,_netdev,allow_other,umask=0007,reconnect     0 0
  1. Ajouter umask 0007 dans les fichiers ~/.bashrc et ~/.profile (de l'utilisateur effectuant le montage :
sudo echo 'umask 0007' >> ~/.profile
sudo echo 'umask 0007' >> ~/.bashrc
  1. Une fois monté, accorder les permissions sur le dossier.
chmod 2760 -R /media/mon_storage

Installer un Frontend

Les frontends sont chargé de recevoir les requêtes des clients et de les transmettre aux serveurs web (dit Backends) le moins occupé. Ce sont des proxys (intermédiaires) qui servent de porte d'accès entre "Internet" et votre cluster.

  1. Mettez en place HaProxy : [Tuto/HowTo] Load Balancing - redirection vers plusieurs vhost avec HaProxy

  2. Insérez chacun de vos Nodes dans votre ou vos sections Backends de HaProxy. Voici un exemple de config simplifiée ( /etc/haproxy/haproxy.cfg ) avec 2 Frontends et un Backend :

global
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    max-spread-checks 100   # delais du premier health check (si non attends le delais pour chaque)

    # Default SSL material locations
#   ca-base /etc/ssl/certs
#   crt-base /etc/ssl/private

    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3
    tune.ssl.default-dh-param 2048

defaults
    log global
    option  httplog
    option  dontlognull
        timeout connect 15000
        timeout client  50000
        timeout server  50000
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http


listen stats
    bind *:1936
    mode http
    stats enable
    stats uri /
    stats hide-version
    stats auth your_user:your_password

frontend Frontend_Tor_HTTP
        bind 127.0.0.1:81
        tcp-request inspect-delay 5s
        mode http
        option httpclose
        option forwardfor
        reqadd X-Forwarded-Proto:\ http
        http-request deny if { hdr_cnt(user-agent) eq 0 } # ban user agent vide
        http-response set-header Referrer-Policy same-origin # check https://www.w3.org/TR/referrer-policy/#referrer-policy-strict-origin
        # block page - Les deux lignes suivantes sont OBLIGATOIRE pour interdire l'accès aux fichiers conflit de syncthing. Ne les supprimez pas !
        acl protect_syncthing path_reg .*\.sync-conflict-.*
        http-request deny if protect_syncthing

#        default_backend grappe_cluster_web

                # www.mon_premier_domaine.com via tor
        acl host_tor_www.mon_premier_domaine.com hdr(host) -i blablablablabla.onion
        use_backend grappe_cluster_web if host_tor_www.mon_premier_domaine.com

frontend Frontend_HTTP
    bind *:80 v4v6
    bind *:443 v4v6 ssl crt /etc/haproxy/certs/www.mon_premier_domaine.com.pem crt /etc/haproxy/certs/www.mon_second_domaine.com.pem crt /etc/haproxy/certs/www.mon_troisieme_domaine.com.pem
        tcp-request inspect-delay 2s
    mode http
    option httpclose
    option forwardfor
    reqadd X-Forwarded-Proto:\ https
        http-request deny if { hdr_cnt(user-agent) eq 0 } # ban user agent vide
        http-response set-header Referrer-Policy same-origin # check https://www.w3.org/TR/referrer-policy/#referrer-policy-strict-origin
        # block page
        acl protect_syncthing path_reg .*\.sync-conflict-.*
        http-request deny if protect_syncthing

        # gestion des logs
#   log /dev/log local0 info
#   http-request add-header X-CLIENT-IP %[src]
        # Décommentez la ligne suivante si vous souhaitez renvoyer vers un backend quand un client joint un domaine inexistant.
#   default_backend grappe_cluster_web
        # Define hosts
    acl host_www.mon_premier_domaine.com hdr(host) -i www.mon_premier_domaine.com
        use_backend grappe_cluster_web if host_www.mon_premier_domaine.com



backend grappe_cluster_web
        mode http
        balance leastconn
    option allbackups
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
        option forwardfor
    http-check expect ! rstatus ^5
        option httpchk GET http://www.mon_premier_domaine.com/haproxytest.php HTTP/1.0
        cookie SERVERID insert indirect nocache
    default-server inter 10s fastinter 500 fall 2 rise 2
                #on force https
    acl http      ssl_fc,not
    http-request redirect scheme https if http


                # une machine qu'on joint en http (conseillé sur réseau deja chiffre)
    server Machine1.http Machine1.VPN:80 weight 1 check cookie Machine1.VPN

                # une machine qu'on joint en https SANS vérification du certificats TLS (désonseillé)
    server Machine1.https.SANS.verif Machine1.COM:443 weight 1 check cookie Machine1 ssl verify none

                # une machine qu'on joint en https AVEC vérification du certificats TLS (conseillé)
        server Machine1.https.AVEC.verif Machine1.COM:443 weight 2 check cookie Machine1 ssl verify required ca-file /etc/haproxy/certs_ssl_backend/ssl-cert-Machine1.pem

                # une seconde machine type
    server Machine2 Machine2:443 weight 2 check cookie Machine2 ssl verify required ca-file /etc/haproxy/certs_ssl_backend/ssl-cert-Machine2.pem
    server Machine2.VPN Machine2.VPN:80 weight 1 check cookie Machine2.VPN backup

Lancez la commande pour vérifier la version d'HaProxy sur votre serveur :

haproxy -v

Si la version est supérieur à 1.9, alors vous pouvez ajouter la ligne suivante tout à la fin de bind *:443 v4v6 ssl

 alpn h2,http/1.1

Screenshots

Photos

  • # LvL Up

    Posté par  . Évalué à 1 (+0/-0).

    Tout avis, retour et amélioration sont les bienvenus 😉

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.