[spip-dev] problème avec l'utilisation de SPIP derrière un proxy

Salut,

certains proxy (de type haproxy) permettent de gérer le https rapidement et faire du load-balancing derrière (entre autre). C’est bien pratique, mais cela pose un énorme problème pour SPIP qui ne peut pas fonctionner avec cette configuration.

Toutes les requêtes vues par SPIP sont de type http, donc les liens générés via url_de_base() seront erronés.

C’est une situation qui pose problème à d’autres outils, et la convention est de se baser sur une info qu’aura transmise le proxy dans l’entete HTTP

Le Framework Symphony se base sur “X-forward-proto” et “X-forward-port”
http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html

C’est ce qu’utilise haproxy (et d’autres)
http://linuxfr.org/news/haproxy-1-5

Je propose que SPIP fasse pareil dans le calcul réalisé par la fonction url_de_base()

Qu’en pensez-vous ?

Je propose que SPIP fasse pareil dans le calcul réalisé par la fonction
url_de_base()

Qu'en pensez-vous ?

je ne sais pas ce qui est le mieux (il faut effectivement faire gaffe à ne
pas pouvoir se faire injecter des fausses infos) ; mais ça doit être facile
à bidouiller dans mes_options.php

-- Fil

Je propose que SPIP fasse pareil dans le calcul réalisé par la fonction

url_de_base()

Qu'en pensez-vous ?

je ne sais pas ce qui est le mieux (il faut effectivement faire gaffe à ne
pas pouvoir se faire injecter des fausses infos) ; mais ça doit être facile
à bidouiller dans mes_options.php

On peut effectivement utiliser l'approche utilisée avec le IS_APACHE, et
ainsi forcer via une configuration de forcer les appels HTTPS.
Seulement, cela ne fonctionne pas, car cela suppose que toutes les urls du
site vont utiliser https, ce qui n'est pas forcément toujours le cas. J'ai
en tête l'exemple d'un site qui ne l'utilise pas mais veut l'utiliser pour
la partie admin -- ecrire/ ou zone à accès restreint.

Hello Gilles,

pour forcer https uniquement sur le privé voilà ce qu’on fait dans un _options.php

https://gist.github.com/benchti/2a89845e31f45572671c5345d275a22b

Non il ne s'agirait pas de forcer https, mais d'activer la prise en compte des headers HTTP_X_FORWARDED_PORT HTTP_X_FORWARDED_PROTO

Cette partie du code n'est pas nickel dans url_de_base(), et est à revoir.
Aujourd'hui on tourne avec un Apache en proxy pour https (on fait donc Apache:443 > Varnish > Apache:80), sans modification de SPIP, mais avec les quelques lignes suivants en prepend php. Cela peut s'appliquer à n'importe quel proxy frontal, les headers étant conventionnels :

if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])
   AND $_SERVER['HTTP_X_FORWARDED_PORT']==='443'
   AND isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
   AND $_SERVER['HTTP_X_FORWARDED_PROTO']==='https') {
         $_SERVER['HTTPS'] = 'on';
         $_SERVER['SERVER_PORT'] = '443';
         if (isset($_SERVER['REQUEST_SCHEME'])) {
                 $_SERVER['REQUEST_SCHEME'] = 'https';
         }
         if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
                 $i = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
                 $i = reset($i);
                 $_SERVER['REMOTE_ADDR'] = $i;
         }
         if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'],',')!==false){
                 $h = explode(',',$_SERVER['HTTP_X_FORWARDED_HOST']);
                 $_SERVER['HTTP_X_FORWARDED_HOST'] = trim(end($h));
         }
}

Notez au passage que je découpe les HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED_HOST pour le cas où on aurait du double proxy (j'ai eu le cas sur un site transféré d'un autre serveur que j'ai mis en proxy le temps de la propagation DNS, du coup on avait empilement des en-têtes avec 2 IP et 2 hosts dans les headers).

Le problème d'appliquer cela par défaut c'est de risquer de l'injection de headers. Il faut verifier avec precaution si cela peut empoisonner le cache d'un visiteur normal, ou peut-être il faut ajouter les 2 headers en signature du cache. Ou n'activer cela que via une configiration ou define ?

Hello,

j'ai envoyé sur la branche dev un patch qui intègre la prise en compte de ces entêtes conventionnels
http://core.spip.org/projects/spip/repository/revisions/23093

si cela va a tout le monde on peut le reporter en branche stable 3.1 voire 3.0.