Une seule IP publique avec plusieurs machines ou services.

Il y a (déjà) un mois, je présentais mon infra perso aujourd’hui suite à des papotages sur irc, je vois qu’il peut être nécessaire de rentrer un peu plus dans les détails concernant Varnish, qui semble pouvoir aider plus de gens que prévu.

Bon dans la vraie vie, on utilise plutôt nginx ou le mod_proxy d’apache pour faire ça mais Varnish est moins gourmand qu’apache et permet plein de choses en plus.

Et puis quand on y a gouté on a du mal à s’en passer…

Pour cette présentation, on va dire que mon adresse IP publique est 127.0.0.1 parce que c’est facile à retenir.
Et coté dns va dire que tous mes trucs sont en *.bazar.4ze.win

Je ne sais pas si c’est le cas partout mais chez Gandi en tout cas, on peut faire des enregistrements DNS « wildcard » (génériques en français).
J’ai donc pour le nom de domaine 4ze.win une ligne de config dns :
*.bazar 1080 IN A 127.0.0.1
En français ça veut dire quelque chose comme « quelque soit le machin qu’on met avant .bazar.4ze.win, faut répondre 127.0.0.1 ».

L’intérêt est double : permettre de rendre accessible en quelques secondes un service via un nouveau nom (juste une modif de varnish) et aussi de pouvoir afficher un site par défaut en cas de faute de frappe par exemple.

Voici un petit schéma, avec Varnish qui reçoit tout le trafic du port 80 (http donc) et redirige ensuite vers d’autres machines suivant le nom demandé.

Un superbe?! schéma du fonctionnement de varnish
Paint rulez! ^^

Maintenant que j’ai présenté le principe, on va rentrer dans le vif du sujet avec la config de Varnish (la version 4 en l’occurrence)…
Le fichier de config par défaut (chez debian en tout cas) est /etc/varnish/default.vcl et il est commenté ce qui est plutôt gentil.

Tout d’abord on définit un « backend », c’est à dire le serveur final auquel on veut causer :
backend jeedom {
    .host = « 172.16.32.9 »;
    .port = « 80 »;
}

Ensuite, dans la partie sub vcl_recv on définit quand est-ce que les requêtes sont envoyées à ce serveur :

if ( req.http.host == « jeedom.bazar.4ze.win » ) {
set req.backend_hint = jeedom;
}

Et puis c’est tout!
Quand on ajoute un service ou une machine on a juste à créer un nouveau backend et à dire quand il doit être sollicité.

En bonus, on peut aussi ajouter des headers du genre :

sub vcl_deliver {
#on empêche iframe et XSS
set resp.http.X-Frame-Options =  « SAMEORIGIN »;
set resp.http.X-Xss-Protection =  « 1; mode=block »;
set resp.http.X-Content-Security-Policy = « sript-src ‘self' »;
set resp.http.Content-Security-Policy = « sript-src ‘self' »;
set resp.http.X-Content-Type-Options = « nosniff »;
}

On peut aussi nettoyer les « user-agent » (il y a des failles au moins pour joomla qui tourne avec ça) :

sub normalize_user_agent {
if (req.http.user-agent ~ « Android ») {
set req.http.user-agent = « Android »;
}  else if (req.http.user-agent ~ « Opera ») {
set req.http.user-agent = « Opera Mini »;
} else if (req.http.user-agent ~ « MSIE ») {
set req.http.user-agent = « MSIE »;
} else if (req.http.user-agent ~ « iPhone ») {
set req.http.user-agent = « iPhone »;
} else if (req.http.user-agent ~ « Firefox ») {
set req.http.user-agent = « firefox »;
} else if (req.http.user-agent ~ « Chrome ») {
set req.http.user-agent = « Chrome »;
} else if (req.http.user-agent ~ « Safari ») {
set req.http.user-agent = « Safari »;
} else {
set req.http.user-agent = « truc louche »;
}
}

Bref, varnish c’est le bien et la doc est bien faite Doc Varnish (en)

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *