Nicolas Steinmetz / @nsteinmetz
Paris Web 2014
Mais de quoi tu me parles ?
Intermédiaire entre des clients (PC/Serveurs) et d'autres ressources
Usage : interne vers externe
Attention au SPOF
Outil déployé dans les grands groupes pour accroître la productivité de leurs employés et de leurs coûteux prestataires
ou pas...
ben un proxy, mais à l'envers !
Externe vers interne
Attention au SPOF (aussi)
Changement de paradigme
Les reverse-proxys sont partout ; vous ne pouvez les ignorer !
1 seul et unique serveur
2 serveurs
Rappel/info : par défaut, le traffic MySQL est en clair ; à sécuriser ?!
Avec Apache + mod_proxy
<VirtualHost *>
ServerName www.exemple.com
ProxyPreserveHost On
ProxyPass / http://0.0.0.0:8080/
ProxyPassReverse / http://0.0.0.0:8080/
</VirtualHost>
Tout http://exemple.com/* sera rerouté vers votre application
<VirtualHost *>
ServerName www.exemple.com
ProxyPreserveHost On
ProxyPass /docs http://docs.exemple.com/
ProxyPass /backend http://backend.exemple.com/
ProxyPass /static http://media.exemple.com/static/
ProxyPass / http://main.exemple.com/
</VirtualHost>
Suivant le chemin, votre RP va attaquer tel ou tel serveur pour le restituer au client
Pré-requis :
Attention aux choix/impacts infrastructuraux !!
Avec apache + mod_proxy + mod_proxy_balancer
<VirtualHost *>
ServerName www.exemple.com
ProxyPass / balancer://monApplication/
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080
BalancerMember http://1.2.3.5:8080
</Proxy>
</VirtualHost>
<VirtualHost *>
ServerName www.exemple.com
ProxyPass / balancer://monApplication/
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember http://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember http://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
Pensez à personnaliser les pages d'erreurs 5xx !
<VirtualHost *>
ServerName www.exemple.com
<Location /misc/>
ProxyPass http://localhost:8888/
ProxyPassReverse http://localhost:8888/
</Location>
ErrorDocument 500 /misc/indisponible.html
ErrorDocument 502 /misc/indisponible.html
ErrorDocument 503 /misc/indisponible.html
ProxyPass / balancer://monApplication/
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember http://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember http://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
Là, c'est tout de suite la classe :-)
Ou l'effet : "l'Apple Store est fermé !!"
<VirtualHost *>
ServerName www.exemple.com
RewriteEngine On
# Tout ce qui ne provient pas de mon IP publique
RewriteCond %{REMOTE_ADDR} !^111\.222\.111\.222
# Et la même via un CDN
RewriteCond %{HTTP:True-Client-IP} !^111\.222\.111\.222
# Est redirigé vers une page de maintenance
RewriteRule ^/(.*) http://www.domaine.tld/divers/maintenance.html [NE]
# Donc moi, je passe :)
ProxyPass / balancer://monApplication/
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember http://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember http://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
Principe
Avantages
!! Le traffic en clair ne peut se faire qu'au sein d'un LAN - jamais entre des machines sur un réseau public !
<VirtualHost *>
ServerName www.exemple.com
# Redirection de /inscription/* et /moncompte/* vers l'url en https
RewriteRule ^/(inscription/.*) https://ssl.domaine.tld/$1 [NE]
RewriteRule ^/(moncompte/.*) https://ssl.domaine.tld/$1 [NE]
# Pour le reste, rester en http simple
RewriteRule ^/(.*)$ balancer://monApplication%{REQUEST_URI} [NE,P,L]
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember http://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember http://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
<VirtualHost *:443>
ServerName www.exemple.com
# Maintient de /inscription/* et /moncompte/* vers mon cluster de frontaux
RewriteRule ^/(inscription/.*) balancer://monApplication%{REQUEST_URI} [NE,P,L]
RewriteRule ^/(moncompte/.*) balancer://monApplication%{REQUEST_URI} [NE,P,L]
# Pour le reste, revenir en http simple
RewriteRule ^/(.*)$ http://www.domaine.tld/$1 [NE]
<Proxy balancer://monApplication>
BalancerMember http://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember http://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember http://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
<VirtualHost *:443>
ServerName www.exemple.com
SSLProxyEngine on # Enable SSL Proxy
SSLProxyCheckPeerCN on # Check if remote certificate is valid
SSLProxyCheckPeerExpire on # Check if remote certificate is expired
ProxyPass / balancer://monApplication/
<Proxy balancer://monApplication>
BalancerMember https://1.2.3.4:8080 loadfactor=1 timeout=10 retry=600
BalancerMember https://1.2.3.5:8080 loadfactor=2 timeout=20 retry=600
# La ligne suivante configure le serveur cible de réserve
BalancerMember https://1.2.3.6:8080 status=+H
</Proxy>
</VirtualHost>
Le certificat du frontal n'a pas besoin d'être signé publiquement ; il faut juste que le RP puisse le valider
Quand CORS et CSP ne peuvent pas être utilisés
location /ressource_externe {
proxy_pass http://www.partenaire.com/contenu/a/recuperer;
}
À utiliser en dernier recours
(mais parfois suffisant)
<VirtualHost *>
ServerName www.exemple.com
ProxyPreserveHost On
ProxyPass /app/ http://app.exemple.com/
ProxyPass /backend http://backend.exemple.com/
ProxyPass /static http://media.exemple.com/static/
</VirtualHost>
Dans ce cas /admin/ n'est pas accessible via votre RP mais peut l'être depuis votre LAN par exemple.
Ton serveur applicatif point trop tu ne solliciteras
Cache sur disque/RAM
Attention aux stratégites d'invalidation du cache et leurs effets en terme de (contre-)performance
<VirtualHost 1.2.3.4:80>
ServerName blog-uk.fr.macompagnie.lan
ProxyPreserveHost On
RequestHeader set Host: myblog.uk.myfirm.lan
ProxyPass / http://1.1.1.1/
ProxyPassReverse / http://1.1.1.1/
</VirtualHost>
Sauf que les liens du site sont absolus ! #paf
<VirtualHost 1.2.3.4:80>
ServerName blog-uk.fr.macompagnie.lan
ProxyPreserveHost On
RequestHeader set Host: myblog.uk.myfirm.lan
ProxyPass / http://1.1.1.1/
ProxyPassReverse / http://1.1.1.1/
<IfModule mod_substitude.so>
AddOutputFilterByType SUBSTITUTE text/html
Substitute s/myblog.uk.myfirm.lan/blog-uk.fr.macompagnie.lan/iq
SetOutputFilter INFLATE;SUBSTITUTE;DEFLATE
</IfModule>
</VirtualHost>
#MasterOfUniverse
Pour Apache 2.4, il y a aussi mod_proxy_html
Ta résilience tu travailleras
En mode mono-serveur :
En mode multi-serveurs :
Mais commencez *simple* !
L'année prochaine, *tu* présentes quoi à Paris-Web ?
Parce que moi aussi l'année dernière, j'étais à ta place...