Tu sei qui: Portale > Plone > Configurare Plone dietro Apache e Varnish
Accedi


Hai dimenticato la tua password?
« gennaio 2012 »
gennaio
lumamegivesado
1
2345678
9101112131415
16171819202122
23242526272829
3031
 

Configurare Plone dietro Apache e Varnish

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
— archiviato sotto: , , ,

Semplice howto per configurare plone 3.3.x dietro Apache 2.2 e Varnish 2.1.x

Premessa

Di seguito verrà utilizzata soltanto una macchina per la gestione del front end con apache e varnish e del back end con l'istanza di plone, ma comunque le possibili implementazioni permettono una divisione in quante macchine si vuole in modo tale da aumentare la scalabilità del sistema ed anche la sicurezza separando i layer di accesso. Ad esempio si potrà avere un'architettura basata su quattro macchine dove sulla prima si installerà apache per la gestione delle connessioni http e https e relative rewrite rule, sulla seconda si potrà installare Varnish come http accelerator, sulla terza si potranno installare le componenti ZEO client e sulla quarta macchina si potrà installare la componente ZEO Server. Di seguito i dettagli identificativi che verranno utilizzati in questo howto e che dovranno essere sostituiti con i valori corretti:

  • nome host: server01
  • ip: 1.1.1.1
  • numero porta tcp per il servizio http: 80
  • numero porta tcp per il servizio https: 443
  • numero porta tcp per il servizio http di varnish: 8080
  • numero porta tcp per i servizi di ZEO Client: 8011, 8012
  • numero porta tcp per il servizio ZEO Server: 8100
  • nome dominio: example.com

Di seguito si presume che la macchina abbia preinstallato plone con i due ZEO Client in ascolto sulle porte 8011 e 8012 e che apache sia configurato per accettare connessioni sia sulla porta 80 che sulla 443, ovvero che siano state configurate le chiavi ssl per la cifratura.

Architettura

Di seguito verrà illustrato come configurare il CMS Plone 3.3.x dietro Apache 2.2 che gestisce le connessioni di front end e Varnish 2.1.x che verrà utilizzato come HTTP accelerator. Di seguito un semplice schema architetturale:

 Varnish

Apache

Bisogna configurare apache in modo che punti verso HTTP Accelerator di Varnish

Definizione delle porte in ascolto

Per prima cosa configurare le porte in ascolto di Apache, su ubuntu il file da editare sarà ports.conf sotto /etc/apache2 ed immettere statement come:

Listen 80
NameVirtualHost 1.1.1.1:80

<IfModule mod_ssl.c>
    Listen 443
    NameVirtualHost 1.1.1.1:443
</IfModule>

Riscrittura del VirtualHost

A questo punto bisogna riscrivere i due VirtualHost, uno per la connessione non autenticata (porta 80) e l'altro per le sessioni autenticate, che verranno automaticamente redirette su http over ssl (porta 443). Su ubuntu si dovranno editare i file "default" e "default-ssl" sotto /etc/apache2/sites-available.

File default

<VirtualHost 1.1.1.1:80>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
   
    ErrorLog /var/log/apache2/error.log
   
    LogLevel warn

    CustomLog /var/log/apache2/access.log combined

    <IfModule mod_rewrite.c>
        RewriteEngine On
        #RewriteLog /var/log/apache2/rewrite-default.log
        #RewriteLogLevel 3
   
        #Redirect su https nel caso sia una sessione autenticata o si
        #stia cercando di autenticarsi
        RewriteCond %{HTTP_COOKIE} __ac=.[[:alnum:]]+.[;]? [OR]
        RewriteCond %{REQUEST_URI}  /login_.*              [OR]
        RewriteCond %{REQUEST_URI}  /logged_out$           [OR]
        RewriteCond %{REQUEST_URI)  /login_success$        [OR]
        RewriteCond %{SERVER_NAME}  ^secure\.example\.com$
        RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]

        RewriteCond %{SERVER_NAME} ^example\.com$ [OR]
        RewriteCond %{SERVER_NAME} ^www\.example\.com$
        RewriteRule ^/(.*) \
http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/example/VirtualHostRoot/$1 [P,L]

    </IfModule>

</VirtualHost>

File default-ssl:

<IfModule mod_ssl.c>
<VirtualHost 1.1.1.1:443>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com

    ErrorLog /var/log/apache2/error.log

    LogLevel warn

    CustomLog /var/log/apache2/ssl_access.log combined

    <IfModule mod_rewrite.c>
        RewriteEngine On
        #RewriteLog /var/log/apache2/rewrite.log
        #RewriteLogLevel 3

        # se si tenta di accedere alla pagina di login -> ssl
        RewriteCond %{SERVER_NAME} example\.com$
        RewriteCond %{REQUEST_URI} /login_.*               [OR]
        RewriteCond %{REQUEST_URI}  /logged_out$           [OR]
        RewriteCond %{REQUEST_URI} /logged_in
        RewriteRule ^/(.*) \
http://localhost:8080/VirtualHostBase/https/%{SERVER_NAME}:443/example/VirtualHostRoot/$1 [P,L]
                       
        # se __ac non e' settato allora redirect su http
        RewriteCond %{HTTP_COOKIE}  __ac=.deleted. [OR]
        RewriteCond %{HTTP_COOKIE}  !__ac=.*
        RewriteRule ^/(.*) http://%{SERVER_NAME}/$1 [R,L]

        # in ultimo si proxa su varnish
        #RewriteCond %{REMOTE_PORT} 443
        RewriteCond %{SERVER_NAME} ^example\.com$ [OR]
        RewriteCond %{SERVER_NAME} ^www\.example\.com$
        RewriteRule ^/(.*) \
http://localhost:8080/VirtualHostBase/https/%{SERVER_NAME}:443/example/VirtualHostRoot/$1 [P,L]
        </IfModule>

...(configurazione dell'ssl da immettere qui)
</VirtualHost>
</IfModule>

Caricamento dei moduli e restart

Una volta configurati i VirtualHost si dovrà verificare che i moduli richiesti siano caricati. Su ubuntu si potranno caricare nel seguente modo:

a2enmod ssl
a2enmod proxy_http
a2enmod rewrite
a2ensite default-ssl

Per verificare che la configurazione sia corretta eseguire il comando

apache2ctl configtest

Ora riavviare il server http

sudo /etc/init.d/apache2 restart

Varnish

Installazione

 Per prima cosa bisognerà preparare l'ambiente per poter compilare il codice sorgente creando l'utente varnish negandogli però la possibilità di effettuare login

useradd -d /home/varnish -m -s /bin/false varnish

A questo punto si potrà scaricare il codice sorgente per procedere con la sua compilazione ed installazione. Con un'utenza non privilegiata ma che possa effettuare login collegarsi in console e scaricare il sorgente:

wget http://sourceforge.net/projects/varnish/files/varnish/2.1.3/varnish-2.1.3.tar.gz/download
tar -xzvf  varnish-2.1.3.tar.gz
cd varnish*
sh autogen.sh
sh configure --prefix=/usr/local/varnish
make

Ora con un'utenza privilegiata bisognerà eseguire il comando d'installazione che su ubuntu potrà essere:

sudo make install

Configurazione

Una volta che varnish 2.1 è installato si potrà procedere alla sua configurazione. Di seguito viene presentanto il contenuto del file example.vcl

# definizione dei backend di istanze ZEO Clients
backend b1 {
    .host = "localhost";
    .port = "8011";
    .probe = {
        .request =
            "GET / HTTP/1.1"
            "Host: 127.0.0.1"
            "Connection: close";
    }
} # end b1

backend b2 {
    .host = "localhost";
    .port = "8012";
    .probe = {
        .request =
            "GET / HTTP/1.1"
            "Host: 127.0.0.1"
            "Connection: close";
    }
} # end b2

# director
director director_0 random {
    .retries = 5;
    {
        .backend    = b1;
        .weight        = 1;
    }
    {
        .backend    = b2;
        .weight        = 1;
    }
} # end director_0

acl purge {
    "localhost";
} # end acl purge


### richiamato dai client alla connessione
sub vcl_recv {
    # grace time
    set req.grace = 300s;

    # impostazione del director di default
    set req.backend = director_0;

### oggetti da immettere nella cache
   
    # javascript
    if (req.request == "GET" && req.url ~ "\.(js)") {
        return(lookup);
    }

    # immagini
    if (req.request == "GET" && req.url ~ "\.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|img|tga|wmf)$") {
        return(lookup);
    }

    # css + html
    if (req.request == "GET" && req.url ~ "\.(css|html)$") {
        return(lookup);
    }

    # multimedia
    if (req.request == "GET" && req.url ~ "\.(svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv)$") {
        return(lookup);
    }

    # xml
    if (req.request == "GET" && req.url ~ "\.(xml)$") {
        return(lookup);
    }

### da non immettere nella cache queste regole
    if (req.request != "GET" && req.request != "HEAD") {
        return(pipe);
    }
    if (req.http.Authenticate || req.http.Authorization) {
        return(pass);
    }

### sessioni autenticate
    # da verificare il cookie di plone
    if (req.http.Cookie && req.http.Cookie ~ "__ac.*") {
        return(pipe);
    }

### gestione dei purge
    if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        return(lookup);
    }

### gestione dell'encoding
    if (req.http.Accept-Encoding) {
        if (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            # unkown algorithm
            remove req.http.Accept-Encoding;
        }
    } # end encoding

} # end vcl_recv

### vcl_hit richiamato quando l'oggetto risiede nella cache
sub vcl_hit {
    if (req.request == "PURGE") {
        set obj.ttl = 0s;
        error 200 "Purged.";
    }
    if (!obj.cacheable) {
        return(pass);
    }

    return(deliver);
} # end vcl_hit

### vcl_miss richiamato quando l'oggetto non viene trovato in cache
sub vcl_miss {
    if (req.request == "PURGE") {
        error 404 "Not in cache.";
    }
} # end vcl_miss

### vcl_fetch richiamato quando l'oggetto viene prelevato dal backend
sub vcl_fetch {

    ## restart se ricevo codici di errore
    if (beresp.status != 200 && beresp.status != 403 && beresp.status 
        != 404 && beresp.status != 301 && beresp.status != 302) {
           restart;
    }

    set beresp.ttl = 300s;
    set beresp.grace = 300s;

    if (beresp.status == 404) {
        set beresp.ttl = 0s;
    }

    if (beresp.status >= 500) {
        set beresp.ttl = 0s;
    }

    if (req.request == "GET" && req.url ~ "\.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|img|tga|wmf)$") {
        set beresp.ttl = 300s;    
    }

    ## css + html
    if (req.request == "GET" && req.url ~ "\.(css|html)$") {
        set beresp.ttl = 300s;
    }
   
    ## javascript
    if (req.request == "GET" && req.url ~ "\.(js)$") {
        set beresp.ttl = 300s;
    }

    ## xml
    if (req.request == "GET" && req.url ~ "\.(xml)$") {
        set beresp.ttl = 300s;
    }

    ## multimedia
    if (req.request == "GET" && req.url ~ "\.(svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv)$") {
        set beresp.ttl = 300s;
    }

    if (!beresp.cacheable) {
        set beresp.http.X-Cacheable = "NO:Not-Cacheable";
        return(pass);
    }

    if (beresp.http.Set-Cookie) {
        return(pass);
    }

    if (req.request == "HEAD") {
        set beresp.http.head = "yes";
    }

    set beresp.http.X-Cacheable = "YES";
    return(deliver);
} # end vcl_fetch

 Nell'esempio sopra esposto è stata scelta come durata della cache un valore di 300 secondi, ma è possibile modificare questo valore con quello che si ritiene più opportuno, come ad esempio 600 secondi equivalenti a 10 minuti.

Start

Non ci resta che provare ad effettuare lo start di Varnish da riga di comando per verificare che tutto sia a posto. Eseguire con una utenza privilegiata il comando:

sudo /usr/local/varnish/sbin/varnishd -f /usr/local/varnish/etc/varnish/example.vcl -P \
    /usr/local/varnish/var/varnish/varnish.pid -a 127.0.0.1:8080 \
    -s malloc,1G -T 127.0.0.1:2500 -u varnish

dove nello specifico
- con "-f /usr/local/varnish/etc/varnish/example.vcl" si indica il file di configurazione precedentemente preparato;
- con "-P /usr/local/varnish/var/varnish/varnish.pid" si indica a varnish di creare il pid file varnish.pid, utile per effettuare lo stop dello stesso demone;
- con "-a 127.0.0.1:8080" si indica a varnish di porsi in ascolto sulla porta 8080 dell'interfaccia di loopback;
- con "-s malloc,1G" si indica a varnish di effettuare in RAM il caching per un contenuto massimo di 1G;
- con "-T 127.0.0.1:2500" si indica a varnish di porsi in ascolto sullo porta 2500 dell'interfaccia di loopback per l'eventuale gestione;
- con "-u varnish" si indica a varnish di utilizzare l'utente varnish per l'esecuzione del demone

Conclusioni

Se è stato fatto tutto bene e se le due istanze ZEO Client sono in ascolto sulle porte 8011 e 8012 il nostro plone sarà configurato come back end alle spalle di apache che gestirà lo switch tra connessioni http e http over ssl a seconda che si navighi su pagine e contenuti pubblici oppure che si effettui la login al nostro sito, dove in questo caso si passerà su connessione cifrata; il tutto sfruttando la capacità di Varnish come HTTP accelerator per effettuare il caching delle risorse senza andare a richiederle ogni volta al nostro plone.

Azioni sul documento