Apache httpd rewrite esempi redirect proxypass

Chiunque, e sottolineo chiunque, gestisca un sito web, prima o poi dovrà fare i conti (ma sono certo sia già successo) con l’ostico mondo delle rewrite, delle redirect e dei proxypass. Ed è a quel punto che scatterà la ricerca infernale su vecchi files di configurazione, o la caccia su Google, della stringa magica che fa al nostro caso e che risolverà (speriamo) tutti i nostri problemi.In questo articolo del blog parleremo quindi di Apache httpd rewrite con esempi di redirect e proxypass.

Che si tratti di cambiare il path di una pagina, di togliere il www dal nostro dominio, o di riscrivere in HTTPS il traffico HTTP, le forche caudine del RewriteEngine sono li ad aspettarvi.

Apache httpd rewrite esempi – Let’s go!!!

Alla base del funzionamento della riscrittura delle URL c’è un modulo di Apache che si chiama mod_rewrite. Cerchiamo di capire cos’è e cosa fa.

Cos’è il mod:Rewrite?

Il termine “mod_rewrite” si riferisce a un modulo per il server Web Apache, che “riscrive” o reindirizza le richieste del client al contenuto richiesto. Fondamentalmente, il modulo trasforma le richieste in arrivo tramite il browser in un path che punta a un file nel file system del server web. Grazie al mod_rewrite è quindi possibile “riscrivere” una URL. A tal fine viene definita una “RewriteRule”, che controlla questa riscrittura e si realizza con l’ausilio di espressioni regolari.

Entriamo nel vivo della discussione e vediamo come si attiva il mod_rewrite e come si scrivono le regole di riscrittura più comuni.

Come attivare il mod_rewrite su apache

Il mod_rewrite è un semplicissimo modulo di apache, già disponibile nel pacchetto base (per cui non è necessario compilarlo). Per attivarlo sarà sufficiente cercare all’interno del file di configurazione di apache, httpd.conf, la seguente stringa:

# LoadModule rewrite_module modules/mod_rewrite.so
HTTP

Una volta trovata la stringa, eliminiamo il commento (#) da inizio riga.

La nuova configurazione sarà la seguente:

LoadModule rewrite_module modules/mod_rewrite.so
HTTP

Riavviando il servizio httpd, il modulo sarà pronto per essere utilizzato e potremo iniziare a scrivere le nostre regole!!!

Per pulizia e smania di ordine, è mia abitudine creare un file esterno ai soliti files di configurazione, all’interno del quale inserisco tutte le regole, in modo da mantenere il più possibile vicini all’originale, i files di configurazione nativi.

Solitamente creo un file dedicato alle rewrites all’interno della cartella conf del nostro apache e lo includo nel file di configurazione:

Include conf/rewrites.conf
HTTP

All’interno del file inserirò tutte le mie rewrites. La prima riga da inserire nel file è l’abilitazione del modulo di rewrite che abbiamo attivato prima:

RewriteEngine on
HTTP

Sotto questa prima riga possiamo iniziare a scrivere tutte le regole di cui abbiamo bisogno.

Un’alternativa alla creazione di un file dedicato alle rewrite è quella di inserire tutte le nostre regole all’interno del file .htaccess. Dal punto di vista funzionale non cambia nulla. La differenza grande sta invece nelle performance. Inserendo le regole nel file di configurazione, le nostre regole verranno caricate in memoria al primo riavvio, con benefici in termini di velocità. Il file .htaccess invece, viene letto ad ogni chiamata che arriva al webserver. Ciò significa che per ogni chiamata in ingresso, il web server deve leggere il file con le relative regole, capire se attuarle, e poi si passa finalmente all’attuazione vera e propria. Lascio a voi le considerazioni :).

Ovviamente non risentiremo di ciò su un sito web che riceve poco traffico. Ma su un sito enterprise, con una grossa mole di visitatori, è fortemente sconsigliato l’utilizzo del file .htaccess.

Apache httpd rewrite esempi redirect proxypass e use cases

Iniziamo a fare qualche esempio di uso comune, in modo da spiegare anche il significato dei FLAGS, che sono fondamentali per un corretto funzionamento delle regole.

RewriteEngine on
RewriteRule ^mypage$ mypage.html [NC]
HTTP

In questo esempio, ^mypage$ è il pattern,  mentre mypage.html è la sostituzione, e [NC] è il flag. Leggendo la regola noterete che sono presenti alcuni caratteri “particolari”, che andiamo a spiegare di seguito e che saranno utili negli esempi successivi:

  • ^ indica l’inizio della nostra URI, ovvero tutto quello presente dopo il dominio.
  • $ Indica la fine della URI interessata dalla regola .
  • mypage è la stringa da matchare.
  • mypage.html è il file presente sul file system a cui accederà il visitatore.
  • [NC] significa “NCase sensitive” e fa si che la regola non faccia differenze tra maiuscole e minuscole

A questo punto potremo testare la nostra regole scrivendo sulla barra degli indirizzi del browser http[s]://TUODOMINIO/mypage. La regola farà in modo che la url digitata punti al file mypage.html:

  • http[s]://TUODOMINIO/mypage – funzionerà perché fa il match esatto con la regola
  • http[s]://TUODOMINIO/Mypage – funzionerà perché la regole è case insensitive
  • http[s]://TUODOMINIO/mypage.html, funzionerà perché la pagina reale presente sul file system sarà sempre raggiungibile

La regola invece non funzionerebbe se chiamassimo:

  • http[s]://TUODOMINIO/mypage/ perché abbiamo esplicitato chiaramente che la nostra regola (grazie al $) termina con la stringa mypage e non prende in considerazione quello che c’è dopo.
  • http[s]://TUODOMINIO/homepage, perché non fa match con la stringa “mypage” presente nella regola.

Ora che abbiamo un’idea generale di come funziona una regola di rewrite, vediamo qualche altro esempio pratico

ESEMPIO DI REWRITE CAMBIO DOMINIO

Il nostro sito TUODOMINIO.com deve cambiare nome in NEWDOMAIN.IT:

  RewriteCond %{HTTP_HOST} ^TUODOMINIO.com$ [OR]
  RewriteCond %{HTTP_HOST} ^www.TUODOMINIO.com$
  RewriteRule (.*)$ https://www.NEWDOMAIN.com/$1 [R=301,L]

Abbiamo introdotto alcune nuove componenti:

  • RewriteCond è la condizione che deve verificarsi affinché la RewriteRule venga applicata. Equivale quindi a una IF.
  • %{HTTP_HOST} è l’FQDN richiamato. Quindi la prima riga significa: Se l’FQDN richiamato sarà TUODOMINIO.COM
  • $1 è una variabile e serve a mantenere invariata la URI richiesta. Se per esempio chiamassimo https://TUODOMINIO.COM/contatti.html o https://www.TUODOMINIO.COM/contatti.html, la chiamata verrà ridiretta su https://www.NEWDOMAIN.com/contatti.html. L’utilizzo delle variabili è fondamentale quando, nel cambiare il nome del dominio, restano invece invariate i contenuti e i relativi nomi delle pagine.

Apache httpd rewrite esempi di dettaglio

Altra opzione di redirezione del traffico per cambio domini è la seguente:

Redirect 301 / https://www.NEWDOMAIN.com/

Qui però non manteniamo la URI richiesta e tutto il traffico andrà sempre nella home del nuovo dominio. 

Se chiamassimo https://TUODOMINIO.COM/contatti.html, verremmo rediretti su https://www.NEWDOMAIN.com. Come vedete, la URI contatti.html viene persa. Questo accade perchè nella regola non è presente la variabile $1 (che abbiamo visto nell’esempio precedente).

Questo può essere utile soltanto se non ci interessa mantenere attivi i contenuti del vecchio sito.

Organizing websites is highly dynamic and often chaotic. Thus, it is crucial that host web servers manipulate URLs in order to cope with temporarily or permanently relocated resources, prevent attacks by automated worms, and control resource access.

The Apache mod_rewrite module has long inspired fits of joy because it offers an unparalleled toolset for manipulating URLs. The Definitive Guide to Apache mod_rewrite guides you through configuration and use of the module for a variety of purposes, including basic and conditional rewrites, access control, virtual host maintenance, and proxies.

Acquista Introduction to Apache mod_rewrite (English Edition) online su amazon

REDIRECT DI UNA SINGOLA PAGINA O DI UN SINGOLO FILE

Redirect /path/old/file/oldfile.html /path/new/file/new.html

# oppure, altro esempio

Redirect /contatti.html /contattaci.html
HTTP

Questa modalità di redirect si applica principalmente quando vogliamo cambiare il nome di una pagina, mantenendo però al suo interno gli stessi contenuti.

Senza questa regola, tutte le persone abituate a visitare questa pagina, magari grazie a un bookmark, riceverebbero un errore 404. Con la regola invece, pur chiamando contatti.html, che magari non esiste più, si viene rediretti automaticamente sul nuovo contenuto offerto dalla pagina contattaci.html.

REDIRECT DI UNA PAGINA SU UNA PAGINA DI UN SITO ESTERNO

Redirect /oldfile/oldfile.html https://www.example.com/newfile/newfile.html
HTTP

Questo codice risponderà con una redirect 302, ovvero con una redirect temporanea. Nel caso in cui volessimo farla diventare definitiva, ovvero una redirect 301, sarà sufficiente scrivere:

Redirect <strong>301</strong> /oldfile/oldfile.html https://www.example.com/newfile/newfile.html
HTTP

Alcune precisazioni su quest’ultimo esempio.

Il primo path, ovvero quello del vecchio file (/oldfile/oldfile.html), deve essere un percorso UNIX locale e relativo, NON il percorso assoluto. Quindi, se la tua docroot si trova nella directory /home/username/htdocs, non dovrai includere il path completo (assoluto). Il primo “/” infatti rappresenta la directory della docroot, ovvero /home/username/htdocs. Pertanto il file /path/oldfile/oldfile.html indicato nella regola, sarà presente sul file system al path: /home/username/htdocs/oldfile/oldfile.html, ma noi lo richiameremo nella regola con /oldfile/oldfile.html.

Il secondo percorso (quello relativo alla destinazione) può essere un percorso UNIX locale, ma può anche essere un URL completo, per collegarsi a una pagina su un server diverso, o sullo stesso server. Come potete vedere infatti, la regola ha come destinazione https://….. e non un path locale, che invece inizierebbe con /… (senza https://).

REDIRECT DA UNA CARTELLA A UN FILE HTML CON REDIRECTMATCH

RedirectMatch 301 ^/blog/about /blog/about.html
HTTP

n questa regola abbiamo introdotto una nuova variabile, ovvero quel 301 che vedete dopo RedirectMatch. Quel 301 rappresenta il response code http che il webserver invia al client. 301 significa Permanently Moved, ovvero “spostato definitivamente”. Ciò significa che il browser si salverà questa risposta del webserver e alla successiva chiamata alla vecchia pagina, farà automaticamente la riscrittura, senza chiedere la vecchia pagina al server.

REDIRECT DA DEFAULT.HTML A INDEX.HTML

Redirect /default.html /index.html
HTTP

REWRITERULE DA VECCHIA DIRECTORY A NUOVA DIRECTORY

RewriteRule ^blog/archives/(.*)$ /newarchives/$1 [R=301,NC,L]
HTTP

In questo esempio ritroviamo il $1. Ciò significa che ogni volta che nel browser scriveremo /blog/archives/*, verremo rediretti al path /newarchives/*.

Esempio pratico:

Chiamo https://MIOSITO.NET/blog/archives/biblioteca.html e verrò ridiretto su https://MIOSITO.NET/newarchives/biblioteca.html.

REDIRECT DI PAGINE NON ESISTENTI, VERSO LA HOME (es. index.php)

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
HTTP

!-f – se il file richiamato non esiste

!-d – se la directory richiamata non esiste

RIDIRIGIAMO GLI ERRORI 404 SU UNA PAGINA SPECIFICA

ErrorDocument 404 https://example.com/404.html
HTTP

Ovviamente possiamo usare questa regola anche per tutte le altre pagine di errore come le 500 o le 502.

ErrorDocument 502 https://example.com/502.html
HTTP

FORZIAMO L’USO DEL WWW

RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
HTTP

Chiamando example.com, il server risponderà al cliente con una rewrite permanente (301) verso www.example.com

RIMUOVIAMO IL WWW

RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule (.*) https://example.com/$1 [R=301,L]
HTTP

Questa regola fa l’esatto opposto della precedente.

FORZIAMO L’HTTPS CON UNA REWRITE PER TUTTO IL TRAFFICO
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"
HTTP

o in alternativa

RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"
HTTP

In questo secondo esempio dobbiamo ricordarci di cambiare www.example.com con l’FQDN del nostro dominio. La prima regola invece è completamente dinamica.

RENDIAMO STATICA UNA URL DINAMICA
RewriteRule ^([0-9]+).html /abc.php?id=$1 [QSA,L]
HTTP

Questa regola è più complessa delle altre. Proviamo a spiegarla.

Se un cliente chiama http[s]://MIOSITO.COM/unqualunquenumero.html (es 919.html), il nostro server erogherà il contenuto presente in http[s]://MIOSITO.COM/abc.php?id=919.

Questo tipo di regola viene solitamente utilizzata per staticizzare e quindi rendere le URL più semplici da leggere, sia per i clienti che per i motori di ricerca (SEO. Discorso che prima o poi affronteremo in futuro. Anche il 301 affrontato finora è fondamentale per il SEO. Ne parleremo). D’altro canto è molto più semplice scrivere https://miosito.com/919.html che https://miosito.com/abc.php?id=919.

Vi faccio un altro esempio. Pensate a un catalogo di abbigliamento. E’ più facile scrivere:

https://miosito.com/it/scarpe/uomo/mocassini.html

oppure

https://miosito.com/catalogo.php?category=scarpe&sgenere=uomo&type=mocassini

Ci siamo risposti 😍 Questa tipologia di regola serve proprio a questo.

Entriamo nel dettaglio della regola. 

([0-9]+) – qualunque numero.

([a-z-]*) qualunque lettera minuscola, più il “-” come separatore. Se invece volete supportare anche le lettere maiuscole, allora dovrete usare “([a-zA-Z-]*). Per esempio:

RewriteRule ^place/([a-zA-Z-]*).html /place/abc.php?id=$1 [QSA,L]
HTTP

[QSA,L] Query String Append aggiunge il paramento inviato come query string. La “L” invece significa Last Rule e blocca l’esecuzione di tutte le regole successive.

ESPONIAMO UN FILE POSIZIONATO IN PATH DIVERSO DA QUELLO RICHIAMATO

RewriteCond %{REQUEST_URI} ^/robots.txt
RewriteRule ^/(.*) /static/robots/robots.txt [PT,NC,L]
HTTP

Questo può essere utile se per qualche motivo non abbiamo possibilità di inserire il robots.txt nella root della nostra docroot.

Blocchiamo spider, crawler, user agents e bots

Per bloccare uno spider, un crawler, uno specifico user agents o un particolare bot, vi consiglio la nostra guida Apache bloccare bot e user agent con mod_rewrite

PROXYPASS PER CHIAMATE VERSO UN SISTEMA INTERNO NON ESPOSTO SU INTERNET
ProxyPass /login http://10.10.10.10/login
ProxyPassReverse /login https://10.10.10.10/login
HTTP

Questa configurazione è utile nel caso in cui volessimo esporre su internet un servizio erogato da un nostro server di backend che non è esponibile direttamente su internet.

Nel caso in cui il servizio di backend rispondesse in https (cosa ovviamente consigliata) allora la configurazione da attuare dovrà essere la seguente:

SSLProxyEngine On
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyTimeout 40 # choose your own config
ProxyPass /login http://10.10.10.10/login
ProxyPassReverse /login https://10.10.10.10/login
HTTP
RIMUOVIAMO LE QUERY STRINGS DALLE URI (update 30/11/2022)

Poniamo il caso che abbiamo delle url, indicizzate su google, del tipo:

https://miosito.com/contatti?region=uk

https://miosito.com/contatti?region=usa

Se per qualche motivo le region uk e usa non dovessero più esistere, ma la pagina dei contatti dovesse rimanere la stessa, potrebbe essere utile rimuovere dalle SERP le pagine con le query strings di contatti. Vediamo che tipo di regola attuare:

RewriteCond %{QUERY_STRING} .+
RewriteCond %{REQUEST_URI} (.*)
RewriteRule ^(.*)$ https://miosito.com%{REQUEST_URI} [L,R=302,QSD]
HTTP

L e R=302 le abbiamo già analizzate in precedenza.

Abbiamo un nuovo FLAG che si chiama QSD = Query Strings Delete

Le pagine richieste dal visitatore del sito, verranno epurate delle query strings e grazie al paramentro %{REQUEST_URI} verremo rediretti alla pagina richiesta (in questo caso /contatti). La regola è dinamica, pertanto non dovrete preoccuparvi di specificare la pagina di destinazione.

Rimuovere lo slash / dalla fine del PATH

In alcuni casi può risultare utile rimuovere lo / (slash) dalla fine della URL. Per farlo, potete utilizzare questa semplice regola di rewrite:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/+$ $1 [L,R=301]
HTTP

Apache httpd rewrite esempi – Tools utili

Come avrete notato nell’articolo, molto spesso le nostre regole contengono, anzi devono contenere, delle regular espressions. Molto spesso è proprio la scrittura di queste regole che più ci mette in difficoltà. Le scriviamo, ma non succede quello che ci aspettiamo.

online regex testing tool
online regex testing tool

Per risolvere Ci sono alcuni tools utili presenti sul web, attraverso i quali è possibile testare le nostre regular espressions. Quello che uso più spesso e che trovo estremamente utile è senza dubbio https://www.regextester.com.

Tra le utility che mette a disposizione c’è anche un mini riassunto delle Top Regular Expressions:

Cheat Sheet

Character classes

. any character except newline

\w \d \s word, digit, whitespace

\W \D \S not word, digit, whitespace

[abc] any of a, b, or c

[^abc] not a, b, or c

[a-g] character between a & g

Anchors

^abc$ start / end of the string

\b word boundary

Escaped characters

\. \* \\ escaped special characters

\t \n \r tab, linefeed, carriage return

\u00A9 unicode escaped ©

Groups & Lookaround

(abc) capture group

\1 backreference to group #1

(?:abc) non-capturing group

(?=abc) positive lookahead

(?!abc) negative lookahead

Quantifiers & Alternation

a* a+ a? 0 or more, 1 or more, 0 or 1

a{5} a{2,} exactly five, two or more

a{1,3} between one & three

a+? a{2,}? match as few as possible

ab|cd match ab or cd

Bloccare i bot tramite mod_rewrite

Qualora vogliate mettere in sicurezza il vostro sito web, bloccando i bots e user agents indesiderati, vi lascio il link al mio tutorial dedicato al blocco dei bots tramite mod_rewrite.

Apache httpd rewrite esempi redirect proxypass Video Tutorial

Vi condivido quest’utile tutorial presente su Youtube. Il video è veramente completo, con oltre 2 ore di lezione.

Apache httpd rewrite esempi -Conclusioni

Chiaramente, questa voleva essere soltanto un’introduzione al troppo vasto mondo delle regole di rewrite e delle regular espressions che la fanno da padrone in quest’ambito. Spero che questa piccola infarinata generale possa essere d’aiuto a qualcuno di voi. Sicuramente lo sarà per me, che correrò qui a fare copia/incolla quando ne avrò bisogno 😆.

Mi impegnerò ad aggiungere altri esempi man mano che mi capiteranno nel lavoro di tutti i giorni. Se vorrete aggiungerne altri, vi invito a commentare l’articolo. Provvederò ad aggiornarlo con le vostre indicazioni.

Anche ulteriori risorse di test potrebbero essere utili. Pertanto, se avete altre risorse da segnalare, utilizzate semper i commenti 😂.

Condividete se l’articolo vi è sembrato interessante. 😊

Il confronto è sempre costruttivo.

I wish you a funny job

Fabio Iegri

Vi lascio il link di questa newsletter qualora vogliate iscrivervi: https://www.linkedin.com/newsletters/web-in-cloud-6945274376917274624/

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *