Categorie
featured tutorial wordpress

CloudFlare: una CDN facile (e gratis)

Argomento un po’ complesso per cui preferisco partire con la definizione di CDN:

Le Content Delivery Network (CDN, Rete per la consegna di contenuti) … sono un sistema di computer collegati in rete attraverso Internet che collaborano in maniera trasparente, sotto forma di sistema distribuito, per distribuire contenuti agli utenti finali.

L’obiettivo di una CDN è di instradare una richiesta di contenuto sul nodo che viene individuato come ottimale. Se ottimizzate per le prestazioni, il nodo ottimale è quello che può soddisfare la richiesta nel minor tempo possibile: si può determinare per esempio scegliendo quello geograficamente o topograficamente (nel contesto di rete, minor numero di hops o minor ping) più vicino alla locazione del richiedente, oppure quello con un minor carico di lavoro (in inglese, load average).

Detto in modo più concreto si tratta di un sistema per ottimizzare e risparmiare carico server facendo in modo che alcuni contenuti (es. le immagini e/o i file statici come js e css) vengano erogati da server differenti ottimizzando la distribuzione a livello geografico in modo che sia il server più vicino a noi ad occuparsi del trasferimento.

Mi sono chiesto più volte in quale modo la nostra infrastuttura potesse beneficiare di questo tecnologia ma guardando le specifiche di Akamai e/o Amazon (che sono forse tra le più importanti realtà in questo settore) mi sono reso conto che i prezzi per la gestione di piccoli siti sono abbastanza proibitivi.

Poi, come sempre succede in queste cose, “la figlia del contadino” mi ha parlato di CloudFlare e del suo piano gratuito.

Ho deciso quindi di provare l’integrazione su questa pagine limitando però l’uso alle immagini e ai file javascript e css.
Questo, in breve, quello che ho fatto.

  1. Comprato un nuovo dominio “mavidacdn.in” su whois.com (in offerti in questi giorni a 3.88 dollari).
  2. Ho girato i name server sui server di Cloudflare
  3. Impostato un nuovo sottominio maurizio.mavida.com in modo che punti sul mio ip
  4. Configurato Apache per indirizzare correttamente. (sia maurizio.mavida.com che static puntano adesso allo stesso sito)
  5. Scritto un microplugin per fare in modo che l’indirizzo delle immagini pubblicare su queste pagine punti sul sottodominio CDN.
  6. Modificato nella pagina nelle impostazioni dei media il “Percorso URL completa ai file” con il sottodominio configurato su CloudFlare (http://maurizio.mavida.com/wp-content/uploads)

In questo modo CloudFlare oltre a fare da CDN svolge anche un lavoro come Reverse Proxy facendo cache dei contenuti. Quando viene chiesta un’immagine, o un file javascript/css CloudFlare verifica se è già nella sua cache e solo nel caso non lo sia la chiede al mio server. I benefici nel mio caso sono molto limitati in quanto il traffico generato è relativamente piccolo ma in situazioni più complesse una soluzione come questa potrebbe ridurre notevolemente il traffico.

Questo è il risparmio di banda (e di richieste) ottenuto in 5 giorni di utilizzo:

Adesso qualche dettaglio tecnico:
Qui sotto potete vedere il modo in cui vado ad effettuare la sostituzione dei link alle immagini che viene usata su filtri: ‘the_content’, ‘post_thumbnail_html’ e ‘widget_text’.


function CloudFlareImageReplace ( $content ) {

$pattern="/(" .$this->blog_url . ")(\/wp-content\/)(.*)(png|gif|jpg)/";
$replacement = $this->cf_cdnurl. "$2$3$4";

return preg_replace($pattern, $replacement,$content );

}

Mentre questa quella per js e css che viene attiva dal filtro su “script_loader_src”.

function CloudFlareScriptReplace ( $src ) {

$pattern="/(" . $this->blog_url . ")(\/wp-content\/)(.*)(js|css)/";
$replacement = $this->CloudFlareUrl . "$2$3$4";

// remove Query Strings From Static Resources
$src_parts = explode('?', $src);
return preg_replace($pattern, $replacement, $src_parts[0] );

}

Su GitHub potete trovare il sorgente versione completa (ancora in versione beta) ma se volte installarlo potete usare quella che ho pubblicato sul codex: http://wordpress.org/extend/plugins/cloudflare-url-replacement/.

Anche in quato caso sono graditi consigli e suggerimenti.


image credits: Derek Heisler

Categorie
featured wordpress

Estendere il server XML-RPC di WordPress

Leggere, scrivere e/o modificare i contenuti su WordPress non sempre può essere fatto da un’interfaccia di amministrazione (sia questa web, mobile o app). Ci possono essere esigenze in cui è necessario automatizzare alcuni processi appoggiandosi a strumenti esterni.

WordPress ci viene incontro con “una cosa” nota come XML-RPC.

 

In pratica si tratta di un componente che ci permette di dialogare secondo un protocollo standard attraverso internet. In questo modo un sito e/o applicazione esterna potrebbe pilotare la nostra installazione facendogli fare qualsiasi cosa.

In realtà “qualsiasi cosa” non è ancora prevista ma dalla nuova versione 3.4 ne saranno aggiunte parecchie. Ricordatevi solo di abilitarlo che di default è disattivato.

Il titolo di questo articolo però è “Estendere il server XML-RPC” non “Usare il server XML-RPC” quindi iniziamo a vedere cosa ci dice il codex: XML-RPC Extending

Like the rest of WordPress, the XML-RPC API contains numerous hooks to customize or extend its behavior.

Nel caso volessimo estendere il servizio XML-RPC attraverso un plugin in grado di restituire gli ultimi post non dovremo quindi fare altro che aggiugnere una roba come questa:

// aggiungo il fitro
add_filter( 'xmlrpc_methods', 'mycustom_methods');

// dichiaro i nuovi metodi
function mycustom_methods( $methods ) {
    $methods['getlastposts'] = 'get_LastPosts';
    return $methods;   
}

/*
 * restisuisco gli ultimi n. post in formato serializzato
 */
function get_LastPosts( $params ) {

  $args =  $params[0]
  $defaults = array(
	'numberposts' => 5, 
	'post_type' => 'post', 	
        'post_status'     => 'publish' 		
	);

  $args = wp_parse_args( $args, $defaults );			
  $posts = get_posts( $args );

  // restituisco l'oggetto serializzato
  return serialize($posts); 
}

Questo invece un esempio di come poter usare il vostro “nuovo” metodo usando il client offerto dalla libreria Zend

 $client = new Zend_XmlRpc_Client('http://tuosito.com/xmlrpc.php');
 $response = $client->call('getlastposts');
 $posts = deserialize($response)

 //con passaggio di parametri
 $client = new Zend_XmlRpc_Client('http://tuosito.com/xmlrpc.php');

 $args = array(
	'numberposts' => 3, 
	'post_type' => 'page'
	);

 $response = $client->call('getlastposts' , array( $args));
 $posts = deserialize($response)

Le cose nella pratica non sono così semplici e potrebbe servire un sistema di autenticazione.
Poi dato che spesso parlo di performance male non farebbe un piccolo sistema di cache.

Ecco quindi una nuova versione di “get_LastPosts” che accetta come parametri $blog_id, $username, $password e poi array con gli argomenti necessari a getposts.

function get_LastPosts( $params ) {

  $blog_id  =  $params[0]
  $username =  $params[1]
  $password =  $params[2]

  $args     =  $params[3]

  $defaults = array(
	'numberposts' => 5, 
	'post_type' => 'post', 	
        'post_status'     => 'publish' 		
	);

  $args = wp_parse_args( $args, $defaults );			
  extract( $args, EXTR_SKIP );

  if ( !$user = $this->login($username, $password) ) {
     // user o password non validi 
     return false;

  } else {

  // creo una chiave univoca per la cache
  $cache_key = "_xmlrpc_" . $username. md5( $numberposts . $post_type);

  $posts = get_transient( $cache_key );

  if (false === $posts) {
     $posts = get_posts( $args );
     set_transient( $cache_key , $posts, 60*60*4 );
  }

  // restituisco l'oggetto serializzato, compresso, ed in base64
  // per ripristinarlo: unserialize(gzuncompress(base64_decode($posts))); 
  return base64_encode(gzcompress(serialize($posts))); 
 }

}

Bene, adesso potete fare un po’ di prove e se nel fare copia e incolla ho sbagliato qualche cosa ditemlo che lo correggo.

Categorie
security wordpress

WordPress: Evitare “brute force” via .htaccess

Sempre più spesso dando un’occhiata ai log di sistema vedo attacchi “brute force” sulle pagina di login standard (wp-login.php) di WordPress.
Su alcuni sito sono arrivato ad avere centinaia di tentativi al giorno ma fortunatamente avendo password alfanumeriche da 12 caratteri e non usando l’utente “admin” di default non mi sono mai preoccupato più di tanto.

 

Nel tempo però mi sono reso conto di due grossi problemi problemi:

  1. Banda e sovraccarico del server: in questo caso e stato semplice intervenire e plugin come Simple Login Lockdown hanno reso la cosa molto semplice. In pratica dopo un numero configurabile di tentativi falliti, per un periodo di tempo altrettanto configurabile, viene bloccato l’IP impedendo l’accesso alla pagina.
    Io lo avevo configurato in modo che dopo 3 tentativi venisse bannato per 4 ore.
  2. Utenti Utonti: Questo è stato il problema più grave. Dato che nella maggior parte dei casi non sono io l’utilizzatore del sito ma il mio lavoro termina creado le credenziali per gli utenti che andranno ad operare, succede che per alcuni una password alfanumerica sia troppo complicata. Ecco quindi che di loro iniziativa la modificano con delle robe tipo “la data di nascita del figlio” perchè così è più facile da ricordare. La soluzione a questa “esigenza imprescindibile” l’ho trovata modificando e nascondendo l’url della pagina di login.
    Inizialmente ho usato “hide login” e successivamente anche “better security” ma alla fine ho preferito preparare uno snippet (che trovatre qui sotto) da mettere manualmente nel file .htaccess evitando in questo modo che il plugin possa essere disattivato.

Se volte implementarlo nel nostra installazione vi lascio solo alcune avvertenze in quanto prima di usarlo vanno modificate alcune variabili che sono dipendenti dal vostra configurazione.

[key] = chiave di controllo per il login – es. “0agw7afK” (2 sostituzioni)
[custom-login-path] = nuovo url per la pagina di login – es. “custom-login” (2 sostituzioni)

Attenzione: Prima di metterlo in produzione vi consiglio di provarlo localmente e di fare un backup del vostro precedente .htaccess. (non mi assumo responsabilità).

Rimango comunque disponibile nel caso doveste avere problemi o vogliate segnalarmi come migliorarlo.


update: maggio 2015
ho aggionto il file riducendo il numero di variabili

Categorie
wordpress

WordPress: strumenti per il Debug

Inizio citando me stesso: “E’ molto semplice iniziare a sviluppare template e plugin per WordPress ma è altrettando semplice scrivere del codice sporco e poco performante

 

Questo per dire che oltre alle “best practice” come il disaccoppiamento, l’utilizzo della cache o l’inclusione di file solo necessari spesso serve un aiuto per capire dove stiamo sbagliano e/o possiamo migliorare.

Questo è il motivo per il quale nella mia “cassetta degli attrezzi plugins” ci sono alcuni plugin che in più di un’occasione si sono rivelati molto molto utili.

Se non li conoscete ancora installate e provate (nb. provateli in locale o comunque sul vostro ambiente di sviluppo e non  produzione perchè ovviamente aggiungono ulteriore overhead )