HA Proxy + et multiples serveurs http sur le port 80

Aujourd’hui j’ai une IP publique et je souhaite avoir prochainement des sites webs qui tournent sur des serveurs différents.
La solution, mettre HAProxy en front est dispatcher les requêtes qui arrivent sur le port 80, vers le bon serveur en fonction du nom de domaine demandé.

Donc j’arrête mon serveur Apache (J’aurai juré l’avoir remplacé par Lighttpd !)…

apache2ctl stop

… et je le reconfigure pour qu’il écoute sur le port 8080 en modifiant le fichier « ports.conf »

Listen 8080

… puis je reconfigure mes vhosts…

<VirtualHost *:8080>

… pour finalement le redémarrer…

apache2ctl configtest
apache2ctl restart

… « restart » c’est le mal (!) … « graceful » c’est le bien !
… et vérifie qu’il tourne bien sur le port 8080.

nmap 127.0.0.1
ORT     STATE SERVICE
...
...
8080/tcp open  http-proxy
...
...

Jusqu’ici tout va bien, mais nos sites sont inaccessibles !

Donc étape 2, on installe HAProxy par un petit…

apt-get install haproxy

… puis on l’active au démarrage de la machine en éditant le fichier « /etc/default/haproxy » en y ajoutant…

ENABLED = 1

…puis on le configure au travers du fichier « /etc/haproxy/haproxy.cfg » pour rediriger toutes les requêtes du port 80 vers le port 8080

...
...
# ============
# --- HTTP ---
# ============

listen FRONTEND_HTTP 192.168.1.11:80
        mode http
        log global
        option  httplog
        stats enable
        stats auth XXXXXXXXXX:XXXXXXXXXX
        balance roundrobin
        option httpclose
        option forwardfor
        option httpchk HEAD /check.txt HTTP/1.0
        capture request header Host len 20

        default_backend BACKEND_HTTP1

# ================
# --- BACKENDS ---
# ================

backend BACKEND_HTTP1
        cookie SERVERID insert indirect nocache
        server TB_001 127.0.0.11:8080 cookie tb001 weight 100 maxconn 100 check

…on crée le fichier « check.txt », avec n’importe quel contenu, à la racine de notre serveur web et on (re)démarre…

service haproxy restart

…et comme tout s’est magnifiquement bien passé, tous nos sites sont maintenant revenus en ligne ;)

Superbe tout ça … mais on a absolument pas avancé par rapport au titre de cette article !
Donc … à suivre…

Les logs HAProxy
Si celle-ci ne sont pas disponibles, vérifiez le contenu du fichier « /etc/rsyslog.d/49-haproxy.conf »

# Create an additional socket in haproxy's chroot in order to allow logging via
# /dev/log to chroot'ed HAProxy processes
$AddUnixListenSocket /var/lib/haproxy/dev/log

# Send HAProxy messages to a dedicated logfile
if $programname startswith 'haproxy' then /var/log/haproxy.log
&~

De mon côté j’ai du faire un…

rsyslog service restart

… pour que le fichier soit créé ;)

Lighttpd: sites availables et sites enabled

Un rapide tuto pour reproduire le fonctionnement des dossiers « sites-available » et « sites-enabled » d’Apache sous Lighttpd.
Cela fait des années maintenant que j’utilise cette technique sans jamais l’avoir couchée par écrit.

On commence par créer les dossiers…

mkdir /etc/lighttpd/sites-available
mkdir /etc/lighttpd/sites-enabled 

On ajoute la ligne suivante à la fin du fichier de configuration « /etc/lighttpd/lighttpd.conf » :

Sous Debian 9:

include_shell conf_dir + "/include-sites-enabled.pl"

Sous Ubuntu 16.04:

include_shell "/usr/share/lighttpd/include-sites-enabled.pl"

On se place dans le dossier équivalent au contenu de la variable « conf_dir » sous Debian, ou dans le dossier « /usr/share/lighttpd » sous Ubuntu.
On crée le script « include-sites-enabled.pl » avec le contenu suivant…

#!/usr/bin/perl -wl

use strict;
use File::Glob ':glob';

my $confdir = shift || "/etc/lighttpd/";
my $enabled = "sites-enabled/*.conf";

chdir($confdir);
my @files = bsd_glob($enabled);

for my $file (@files)
{
        print "include \"$file\"";
}

On teste la configuration…

lighttpd -t -f /etc/lighttpd/lighttpd.conf

… qui doit donner comme résultât « Syntax Ok » avant de pouvoir redémarrer le serveur avec…

service lighttpd restart

Comment ajouter un vhost et l’activer ?

Créez dans le dossier « /etc/lighttpd/sites-available » votre fichier de vhost avec comme extension « .conf ».
Depuis le dossier « /etc/lightppd/sites-enabled » créez un alias vers votre fichier.
Exemple…

ln -s ../sites-available/mon_vhost.conf

Il ne reste plus qu’à tester la configuration avant de redémarrer le serveur…

lighttpd -t -f /etc/lighttpd/lighttpd.conf
service lighttpd restart

Magento 2 & Lighttpd configuration

Reprise des activités Magento avec sa nouvelle version 2.1.4 et sa configuration Lighttpd.
Cette configuration se base largement sur celle fournie par Anton Samuelsson avec quelques ajustements dont la suppression du message d’avertissement de sécurité du backoffice.

# ==========================
# --- Magento 2 Lighttpd ---
# ==========================
#
# Magento  : 2.1.4
# Lighttpd : 1.4.43+git20161216-1
#
# Require "mod_access" module
#
# 2017.02.02 : Init (Based on Anton Samuelsson config. https://gist.github.com/freestream/)
# 2017.02.15 : Disable access to "/app/etc/config.php" (This remove backoffice warning)

server.modules += ("mod_access")

$HTTP["host"] =~ "^(magento2)" {
    server.document-root = "/var/www/magento2/"

    setenv.add-environment = (
        # default       Disables static file caching, provides verbose logging,
        #               automatic code compilation, enhanced debugging.
        #
        # developer     Static file caching is enabled, automatic code
        #               compilation is enabled, exceptions are not displayed to
        #               the user; instead, exceptions are written to log files.
        #
        # production    Exceptions are not displayed to the user, exceptions are
        #               written to logs only, and static files are not cached.
        #
        "MAGE_MODE"         => "default",

        # Unknown result. Both are currently broken.
        #
        # firebug
        # csv
        #
        #"MAGE_PROFILER"     => "firebug"
    )

    var.asset_allowed_img_ext   = "ico|gif|jpg|JPEG|jpeg|png|css|swf|pdf|ttf|woff2|woff|xml|wsdl|svg|otf|eot"
    var.asset_allowed_oth_ext   = "|js|zip|gz|gzip|bz2|csv|xml|html|json"

    expire.url = (
        "/pub/(static|media)/.*\.(" + var.asset_allowed_img_ext + ")"   => "access plus 7 days",
    )

    $HTTP["url"] =~ "/pub/(static|media)/.*\.(" + var.asset_allowed_img_ext + ")" {
        setenv.add-response-header = (
            "Cache-control" => "public, max-age=604800",
        )
    }

    $HTTP["url"] =~ "/pub/(static|media)/.*\.(" + var.asset_allowed_oth_ext + ")" {
        setenv.add-response-header = (
            "Cache-control" => "no-store",
        )
    }

    var.asset_allowed_ext   += var.asset_allowed_img_ext
    var.asset_allowed_ext   += var.asset_allowed_oth_ext
    var.asset_file_regex    = "([-\w^&'@{}[\],$=!#().%+~\/ ])+(\.(" + var.asset_allowed_ext + "))(\?.*|)"

    url.redirect = (
        "^/pub/static/version([\d]+)/(.*)" => "/pub/static/$2"
    )

    url.rewrite-if-not-file = (
        "^/pub/static/(" + var.asset_file_regex + ")$"      => "/pub/static.php?resource=$1",
        "^/pub/media/(" + var.asset_file_regex + ")$"       => "/pub/get.php?resource=$1",
        "^/setup"                                           => "/setup/index.php$1",
        "(.*)"                                              => "/index.php$1"
    )

    $HTTP["url"] =~ "^/app/|^/pub/media/customer/|^/pub/media/downloadable/|^/pub/errors/.*\.(xml|phtml)$" {
        url.access-deny = ( "" )
    }

    $HTTP["url"] == "/app/etc/config.php" {
        url.access-deny = ( "" )
    }

    $HTTP["url"] =~ "^/pub/media/theme_customization/.*\.xml$" {
        url.access-deny = ( "" )
    }

    $HTTP["url"] == "/pub/cron.php" {
        url.access-deny = ( "" )
    }

    $HTTP["url"] =~ "(index|get|static|report|404|503)\.php$" {
        setenv.add-environment = (
            "PHP_FLAG"      => "session.auto_start=off \n suhosin.session.cryptua=off"
        )
    }

    accesslog.filename = "/var/log/lighttpd/magento2.access.log"
}