Co się stanie gdy wywołamy taki adres?
http://adres.pl/katalogObsługując taki adres serwer Apache spróbuję udostępnić plik o nazwie /katalog (względem DocumentRoot). Gdy się okaże, że pod tą nazwą w systemie plików znajduję się katalog serwer wykona przekierowanie (HTTP 301) na adres:
http://adres.pl/katalog/W przekierowaniu jest podany adres bezwzględny (pełny URL). Przy tworzeniu pełnego adresu Apache ustawia rodzaj protokołu (scheme). Domyślna wartość dla scheme to http. Gdy aktywny jest jakiś moduł SSL/TLS (np. mod_ssl) dla vhostów z obsługą SSL-a zwracana jest wartość https.
Na problem możemy natrafić gdy terminacja SSL/TLS obywa się w innym miejscu niż Apache (przykład terminacji na serwerze Nginx). W takiej sytuacji komunikacja serwera proxy z serwerem Apache odbywa się najczęściej po "czystym" protokole HTTP i Apache wygeneruję przekierowanie bezwzględne zawierające http://.
Najprostszym rozwiązaniem tego problemu w przypadku Nginx jest wykorzystanie dyrektywy proxy_redirect. Pozwala ona na podmianę w odpowiedzi z backendu np. http:// na https://. Wykorzystując to rozwiązanie może być trudno wykonać celowe przekierowanie z poziomu backendu (np. aplikacji php) na adres http:// - może ono zostać zamienione na https://.
Poniższy bardzo prosty moduł dla Apache (dla wersji 2.2.x) rozwiązuję ten problem. Rozwiązanie opiera się na przekazaniu przez serwer proxy nagłówka (X-Forwarded-Proto) informującego jaki protokół został użyty przy połączeniu. Poniższy moduł po wykryciu takiego nagłówka "informuję" serwer Apache o odpowiednim typie protokołu (zmienia nazwę dla scheme) dla danego requesta.
Moduł jest bardzo prosty. Posiada zaszyte informacje o nazwie nagłówka i dopuszcza tylko zmianę jeśli request został wywołany z adresu 127.0.0.1. Moduł celowo nie obsługuję żadnych parametrów konfiguracyjnych - jeśli moduł zostanie wyłączony konfiguracja serwera Apache będzie dalej prawidłowa (nie będzie nieznanych dyrektyw konfiguracyjnych).
Poniżej kod źródłowy modułu (w języku C) i pakiety RPM.
Pakiet RPM dla CentOS 6.x x86_64
Pakiet SRPMS
/*
* mod_rpsm.c (Reverse Proxy Scheme Module)
* Version: 1.0
* License: Public Domain
*
* Author: Robert Socha
* EMail: socha@socha.it
*
* Simple module to set Apache scheme (https or http) when request are coming from
* reverse proxy/ssl terminator (eg. Nginx)
* No configuration directives - pass X-Forwarded-Proto header from proxy
* (and set it to https)
*
* Compile: apxs -c mod_rpsm.c
*
*/
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
module AP_MODULE_DECLARE_DATA rpsm_module;
static const char *rpsm_http_scheme(const request_rec *r) {
const char *xfproto;
if( (strcmp(r->connection->remote_ip,"127.0.0.1")==0) &&
(xfproto = apr_table_get(r->headers_in, "X-Forwarded-Proto")) &&
(strcmp(xfproto,"https") == 0)) {
return "https";
}
return NULL;
}
static void rpsm_register_hooks(apr_pool_t *p) {
ap_hook_http_scheme(rpsm_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA rpsm_module = {
STANDARD20_MODULE_STUFF,
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server configs */
NULL, /* command apr_table_t */
rpsm_register_hooks, /* register hooks */
};
Brak komentarzy:
Prześlij komentarz