Il significato di CGI è Common Gateway Interface. Erroneamente CGI può essere definito un linguaggio di programmazione ma in realtà è un metodo attraverso cui è possibile l'interazione tra web-client e server.
I file CGI non sono necessariamente degli script ma sono spesso binari compilati da programmi scritti in C. Per scrivere gli script CGI è possibile utilizzare qualsiasi linguaggio di programmazione supportato dal server dove viene eseguito.
I linguaggi usati sono C, C++, script shell, Python ed il più utilizzato PERL.
I CGI vengono caricati ed eseguiti ogni qualvolta il server ne riceve la richiesta ed attraverso l'enviroment settato dal server e dall'URL è in grado di estrapolare tutte le informazioni necessarie per la sua funzionalità
Di seguito è riportato parte dell'enviromet settato da Apache:
SERVER_NAME
Il nome dell' host (o l' indirizzo IP) dove sta girando lo script
SERVER_SOFTWARE
Il software del server usato. Esempi: CERN/3.0 o NCSA/1.3
GATEWAY_INTERFACE
La versione CGI del server
SERVER_PROTOCOL
La versione del protocollo HTTP usato. Dovrebbe essere CGI/1.1
SERVER_PORT
La porta TCP alla quale il server e' collegato. Di solito questo valore e' 80
REQUEST_METHOD
Il metodo usato: GET, POST, HEAD
HTTP_ACCEPT
L' elenco dei Content-type che il browser e' in grado di gestire
HTTP_USER_AGENT
Il nome del browser che ha inviato le informazioni. Questa variabile di
solito contiene il nome del browser, la sua versione ed altre informazioni come la piattaforma usata
HTTP_REFERER
L' URL del documento che contiene la form
PATH_INFO
L' URL ed informazioni aggiuntive inviate dal browser quando viene usato
il metodo GET
PATH_TRANSLATED
Il path reale del sistema contenuto all' interno della variabile
PATH_INFO
L' URL ed informazioni aggiuntive inviate dal browser quando viene usato il metodo GET
SCRIPT_NAME
Il path di esecuzione dello script ed il nome
QUERY_STRING
Informazioni inviate tramite il metodo GET. In altre parole tutte le
informazioni inviate dopo il simbolo '?' all' interno dell' URL
REMOTE_HOST
Il nome logico dell' host che ha effettuato la richiesta
REMOTE_ADDR
L'IP dell' host che ha effettuato la richiesta
REMOTE_USER
Il nome dell' utente che ha inviato la richiesta (quando e' disponibile una forma di autenticazione)
REMOTE_IDENT
Il nome del server che ha inviato la richiesta (quando e' disponibile il
protocollo ident)
CONTENT_TYPE
Quando e' usato il metodo POST, il suo valore e':
'application/x-www-form-urlencoded'. Quando viene inviato un file, il
suo valore e': 'multipart/form-data'
CONTENT_LENGTH
Quando e' usato il metodo POST, il suo valore definisce la dimensione del canale di input. In altre parole il numero di bytes inviati
I CGI vengono gestiti dal modulo mod_cgi ed è possibile abilitarne le funzionalità in due modi differenti:
Direttiva Options
Tramite la direttiva Options e l'argomento ExecCGI, all'interno di un container, è possibile definire quale directory conterrà gli scripts. Esempio:
Options ExecCGI
Direttiva ScriptAlias
Un metodo alternativo è la direttiva ScriptAlias, la quale permette di settare una directory, anche esterna alla DocumentRoot, come CGI container (Soluzione adottata di default). Esempio:
ScriptAlias /cgi-bin "/usr/local/apache/cgi-bin/"
In questo caso Apache interpreterà tutte le richieste con l'url che conterrà cgi-bin come richieste per risorse all'interno della directory /usr/local/apache/cgi-bin/
Nel caso in cui occorra definire più directory contenenti CGI è possibile utilizzare più volte la direttiva ScriptAlias oppure appoggiarsi alla direttiva ScriptAliasMatch che permette l'uso delle regular expression. Esempio:
ScriptAlias /de/cgi-bin "/usr/local/apache/cgi-bin/"
ScriptAlias /it/cgi-bin "/usr/local/apache/cgi-bin/"
ScriptAlias /us/cgi-bin "/usr/local/apache/cgi-bin/"
La seguente configurazione può essere sostituita con una sola direttiva:
ScriptAliasMatch /*/cgi-bin "/usr/local/apache/cgi-bin/"
Nulla vieta di specificare un singolo file CGI e non una directory contenente più CGI, attraverso il File container Esempio:
<Files "/home/www/openskills/">
AllowOverride None
Options ExecCGI
SetHandler cgi-script
</Files>
oppure
<Files "/home/www/openskills/*.cgi">
AllowOverride None
Options ExecCGI
SetHandler cgi-script
</Files>
Tramite le direttive AddHandler è possibile definire quali file sono da interpretare come script CGI tramite l'estensione del file stesso oppure tramite la direttiva AddType a seconda del MIME Type. Esempi:
SetHandler cgi-scripts .cgi .pl .py
AddType application/x-httpd-cgi .cgi
Di seguito sono elencati alcuni metodi per la configurazione di una CGI directory definibili ottimali sia per quanto riguarda l'aspetto sicurezza sia per quanto riguarda la semplicità di configurazione.
Uso della direttiva ExecCGI e SetHandler.
<Directory "/usr/local/apache/cgi-bin">
AllowOverride None
Options ExecCGI
SetHandler cgi-script
Order allow, deny
Allow from all
</Directory>
Con il supporto della direttiva AddHandler o AddType possiamo specificare anche l'estensione dei file che devono essere considerati come CGI script
<Directory "/usr/local/apache/cgi-bin">
AllowOverride None
Options ExecCGI
AddHandler cgi-script .cgi
Order allow, deny
Allow from all
</Directory>
<Directory "/usr/local/apache/cgi-bin">
AllowOverride None
Options ExecCGI
AddType application/x-httpd-cgi .cgi
Order allow, deny
Allow from all
</Directory>
Apache tramite le seguenti direttive può limitare le risorse da destinare all'uso dei CGI:
- RlimitCPU - Limita il numero di secondi di CPU time che un processo di Apache può invocare, compreso un CGI scripts.
- RlimitMEM - Indica il limite di memoria che ogni processo può richiedere al sistema.
- RlimitNPROC - Limita il numero massimo di processi che un utente può creare.
Ogni direttiva prevede due parametri, il primo indica il "soft limit" ovvero il limite che può subire un override dal processo ed il secondo definito "hard limit" che di fatto risulta il vero e proprio limite poichè non può in alcun modo essere superato.
Entrambi accettano valori numerici oppure max che indica al sistema che può fornire tutte le risorse disponibili al processo.
Esempi:
RLimitCPU 100 max
RLimitMEM 256000 1024000
RLimitNPROC 3 10
Attenzione a come si utilizza la direttiva scriptAlias:
SI: ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
NO: ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin"
Lo / finale forza la residenza dello script all'interno della directory, altrimenti si potrebbe lanciare /usr/local/apache/cgi-bin
Utilizzando la direttiva ScriptAliasMatch
nel file di configurazione di Apache è possibile definire più directory "virtuali" dove possono essere eseguiti script CGI. In pratica coincide con la direttiva ScriptAlias
con in più la possibilità di usare wildcards e redular expressions nella definizione dei nomi degli alias.
Le direttive:
ScriptAlias /dir_a/cgi-bin/ "/usr/local/apache/cgi-bin/"
ScriptAlias /dir_b/cgi-bin/ "/usr/local/apache/cgi-bin/"
ScriptAlias /dir_c/cgi-bin/ "/usr/local/apache/cgi-bin/"
Possono essere sostituite con:
ScriptAliasMatch /dir_*/cgi-bin/ "/usr/local/apache/cgi-bin/"