Virtual hosting su hosting scalabile per WordPress

Nella precedente serie di articoli, abbiamo utilizzato un insieme di tre macchine per realizzare un hosting altamente ottimizzato per ospitare blog in WordPress.
In questo articolo modificheremo la configurazione per poter ospitare più blog all’interno di un’unico insieme di VM.

1) Creazione di utenti distinti per gli script php
Sia sul Load Balancer, sia sull’application server, andremo a creare un utente specifico per far girare gli script php di ogni sito. QUesta impostazione ci consente di mantenere un sistema sicuro in quanto uno script del “sito1” non avrà accesso ai file del “sito2”.
Lanciamo quindi i seguenti comandi su entrami i server:

useradd sito1
useradd sito2

2) Modifica della path del sito web e settaggio dei permessi
Innanzi tutto, abbiamo tutti i file del nostro sito wordpress all’interno della directory /var/www e la cosa non va certo bene per l’impostazione che stiamo per realizzare.
Sul Load Balancer, lanciamo i seguenti comandi:

cd /var/www
mkdir sito1
mv * sito1
chown -R sito1:www-data sito1
chmod 750 sito1
mkdir sito2
chown -R sito2:www-data sito2
chmod 750 sito2
mkdir default
chown -R root:www-data default
chmod 750 default
touch default/index.hrml

Con questa impostazione, abbiamo creato due directory per i nostri Virtual Hosting, bloccando l’accesso in lettura/scrittura al solo proprietario della directory.

3) Configurazione di nginx sul load balancer
E’ necessario modificare la configurazione di nginx sul Load Balancer in modo da abilitare il Virtual Hosting. Con l’occasione aggiungeremo qualche limite per amentare ulteriormente la sicurezza del sistema.

<strong>/etc/nginx/nginx.conf</strong>
user www-data;
worker_processes  2;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log /var/log/nginx/access.log;
    server_names_hash_bucket_size 64;
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay        on;
    gzip              on;
    gzip_comp_level   5;
    gzip_http_version 1.0;
    gzip_min_length   0;
    gzip_vary         on;

    ## Start: Size Limits & Buffer Overflows ##
    client_body_buffer_size  1k;
    client_header_buffer_size 2k;
    client_max_body_size 1k;
    large_client_header_buffers 2 2k;
    ## END: Size Limits & Buffer Overflows ##

    ## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     5 5;
    send_timeout          10;
    ## End: Timeouts ##

    ### Directive describes the zone, in which the session states are stored i.e. store in slimits. ###
    ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ###
    limit_zone slimits $binary_remote_addr 5m;

    ### Control maximum number of simultaneous connections for one session i.e. ###
    ### restricts the amount of connections from a single ip address ###
    limit_conn slimits 5;

    upstream appservers {
        fair weight_mode=idle no_rr;
        server php-appserver1 weight=10;
    }
    server {
        listen       80;
        server_name  _;
        index index.htm
        access_log /var/log/nginx/default.access.log;

       location / {
            root /usr/share/nginx/www/default;
        }
    }

    include /etc/nginx/sites-enabled/*;

}

Creiamo quindi i due file sito1 e sito2 per il Virtual Hosting:

<strong>/etc/nginx/sites-available/sito1 </strong>
    server {
        listen       80;
        server_name  sito1;
        access_log /var/log/nginx/sito1.access.log;

        location / {
            ## Only allow these request methods ##
            if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
            }
            ## Do not accept DELETE, SEARCH and other methods ##

            ## Deny certain Referers ###
            if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
            {
            # return 404;
            return 403;
            }
            ##
            proxy_pass http://appservers;
            include /etc/nginx/conf.d/proxy.conf;
        }
    location ~* ^.+.(jpe?g|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|swf|avi|mp3)$ {
            ## Only allow these request methods ##
            if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
            }
            ## Do not accept DELETE, SEARCH and other methods ##

            ## Deny certain Referers ###
            if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
            {
            # return 404;
            return 403;
            }
            ##

            expires 30d;
            root /usr/share/nginx/www/sito1;
        }
    }







<strong>/etc/nginx/sites-available/sito2 </strong>
    server {
        listen       80;
        server_name  sito2;
        access_log /var/log/nginx/sito2.access.log;

        location / {
            ## Only allow these request methods ##
            if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
            }
            ## Do not accept DELETE, SEARCH and other methods ##

            ## Deny certain Referers ###
            if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
            {
            # return 404;
            return 403;
            }
            ##
            proxy_pass http://appservers;
            include /etc/nginx/conf.d/proxy.conf;
        }
    location ~* ^.+.(jpe?g|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|swf|avi|mp3)$ {
            ## Only allow these request methods ##
            if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
            }
            ## Do not accept DELETE, SEARCH and other methods ##

            ## Deny certain Referers ###
            if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
            {
            # return 404;
            return 403;
            }
            ##

            expires 30d;
            root /usr/share/nginx/www/sito2;
        }
    }

Quindi abilitiamo i due siti e ricarichiamo la configurazione di nginx:

ln -s /etc/nginx/sites-available/sito1 /etc/nginx/sites-enambled
ln -s /etc/nginx/sites-available/sito2 /etc/nginx/sites-enambled
/etc/init.d/nginx restart

3) Configurazione di nginx sull’application server
Analoga configurazione andrà eseguita sull’application server. Partiamo con il file di configurazione generale di nginx:

<strong>/etc/nginx/nginx.conf</strong>
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

        ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

E i file dei due siti ospitati:

<strong>/etc/nginx/sites-available/sito1</strong> 
           server {
                listen 80;
                server_name sito1

                root /usr/share/nginx/www/sito1;
                index index.php;

            log_not_found off;

        location / {
            try_files   $uri $uri/ /index.php;
        }

        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    fastcgi_index  index.php;
            fastcgi_pass   127.0.0.1:9001;
                    fastcgi_param  SCRIPT_FILENAME /usr/share/nginx/www$fastcgi_script_name;
                    include fastcgi_params;
                }

       }






<strong>/etc/nginx/sites-available/sito2 </strong>
           server {
                listen 80;
                server_name sito2

                root /usr/share/nginx/www/sito2;
                index index.php;

            log_not_found off;

        location / {
            try_files   $uri $uri/ /index.php;
        }

        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    fastcgi_index  index.php;
            fastcgi_pass   127.0.0.1:9002;
                    fastcgi_param  SCRIPT_FILENAME /usr/share/nginx/www$fastcgi_script_name;
                    include fastcgi_params;
                }

       }

Da notare la porta diversa nella direttiva fastcgi_pass: difatti ciascun sito avrà la propria istanza di php-fpm che dovrà rispondere ad una porta univoca. Verdemo come al prossimo punto, per il momento limitiamoci a rendere attive le modifiche con:

ln -s /etc/nginx/sites-available/sito1 /etc/nginx/sites-enambled
ln -s /etc/nginx/sites-available/sito2 /etc/nginx/sites-enambled
/etc/init.d/nginx restart

4) Configurazione di php-fpm
Quindi ciascun sito, avrà la propria istanza di php-fpm avviata. Per farlo è necessario creare un file di configurazione per ogni sito in /etc/php5/fpm/pool.d:

<strong>/etc/php5/fpm/pool.d/sito1</strong>
[sito1]
listen = 127.0.0.1:9001
user = sito1
group = sito1
pm = dynamic
pm.max_children = 25
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 10
pm.max_requests = 500







<strong>/etc/php5/fpm/pool.d/sito2</strong>
[sito1]
listen = 127.0.0.1:9002
user = sito1
group = sito1
pm = dynamic
pm.max_children = 25
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 10
pm.max_requests = 500

Quindi riavviamo php-fpm con:

/etc/init.d/php5-fpm restart