Ari Rantala -> Oppaat [Viimeksi muutettu 18.2.2018 ]

6. CGI

Tämän luvun tarkoituksena on antaa perusvälineet CGI-rajapinnan toimintakunnon testaamiseen. Ks.

http://httpd.apache.org/docs-2.0/howto/cgi.htm

Yleistä

  • CGI (Common Gateway Interface) = rajapinta, joka määrittelee Web-palvelimen ja sen avulla käynnistettävän ohjelman kommunikointitavan.
  • luodaan tyypillisesti interaktiivisia Web-asiakkaan ohjaamia sovelluksia.
  • EI ohjelmointikieli. CGI-ohjelmia voidaan kirjoittaa lähes millä tahansa kielellä, joka pystyy käsittelemään ympäristömuuttujia. Esim:
    • sh, Perl, C, Tcl ja PHP

cgi.gif (4560 bytes)

CGI-moduuli on aktivoitava aluksi

Jotta CGI-rajapintaa voi käyttää, on CGI-moduuli aktivoitava aluksi (Ubuntu 16.04; monessa järjestelmässä tätä ei tarvi tehdä)
sudo a2enmod cgi

Miten kerrotaan, mitkä tiedostot ajetaan CGI-ohjelmina?

  • Web-palvelimen tulee tietää, mitkä HTTP-pyynnöt johtavat CGI-ohjelman käynnistämiseen!

ScriptAlias

Ubuntu-tiedosto: /etc/apache2/conf-available/serve-cgi-bin.conf

  • Kaikki ScriptAlias-direktiivillä määriteltyyn hakemistoon tallennetut tiedostot tulkitaan CGI-ohjelmiksi.
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
  • Voitaisiin kutsua: http://www.domain.example/cgi-bin/softa
  • Tiedoston päätteellä ei ole merkitystä!

AddHandler ja ExecCGI

Ubuntu-tiedosto (AddHandler): /etc/apache2/mods-enabled/mime.conf
Ubuntu-tiedosto (ExecCGI): /etc/apache2/*.conf

  • Halutaan määritellä ajettavat CGI-ohjelmat tiedostopäätteen perusteella
  • AddHandler-direktiivillä määritellään, millaisen päätteen omaavat tiedostot ajetaan CGI-ohjelmina. Asetetaan tällaisiksi esim cgi- ja pl-päätteet mime.conf-tiedostossa. Muista ottaa mahdollinen kommenttimerkki pois rivin alusta!
    AddHandler cgi-script cgi pl
  • Tarvitaan ExecCGI-arvoa Options-direktiiville esim. sille hakemistolle, josta näin ajettavaksi määriteltyjä CGI-ohjelmia halutaan ajaa. Esim tavallisten käyttäjien public_html-hakemistoille:

    <Directory /home/*/public_html>
    Options ExecCGI
    </Directory>
  • Jotta "Options ExecCGI" voitaisiin määritellä hakemistokohtaisessa .htaccess-tiedostossa, tulee httpd.conf-tiedostossa olla määritys AllowOverride Options kohdistettuna asianomaiselle hakemistolle.

Mitä oikeuksia CGI-ohjelmat tarvitsevat?

  • CGI-ohjelmat käynnistettäviä ohjelmia -> Tarvitaan suoritusoikeuksia (x=execute).
    • Tulkattavat skriptit (esim. perl) tarvitsevat lisäksi lukuoikeuksia (r=read)

SuExec käytössä

  • CGI-ohjelmat ajetaan ohjelman omistajan UID:llä
  • Riittää tavallisena käyttäjänä: chmod 700 softa.cgi
  • Muista lisäksi normaalisti kirjoitusoikeus ohjelman datatiedostoihin. Tavallisesti tässäkin riittää chmod 700 data.txt
  • CGI-ohjelmat EIVÄT voi olla pääkäyttäjän (root) omistuksessa.

SuExec EI käytössä

  • Tämä on Apachen oletusarvo (esim. itse käännetty palvelin)
  • CGI-ohjelmat ajetaan Apache-käyttäjän UID:llä. Tyypillisesti tämä käyttäjä on joko apache tai nobody. Web-palvelinta ajava käyttäjä selviää httpd.conf-tiedoston User-direktiivin arvosta:

    User www-data
    Group www-data

  • Tyypillisesti tarvitaan tavallisena käyttäjänä: chmod o+rx softa.cgi
  • Muista lisäksi normaalisti kirjoitusoikeus ohjelman datatiedostoihin. Yleensä tarvitaan chmod o+w data.txt
  • Web -palvelinta ajavalla käyttäjällä on oltava kirjoitusoikeus kaikkiin hakemistoihin, joihin se lisää/poistaa tiedostoja.
  • CGI-ohjelmat VOIVAT olla pääkäyttäjänkin omistuksessa (Harvoin järkevää).

Hello World!

  • Esitetään Hello World!-ohjelma kolmella kielellä sh, perl ja C.
  • Jos käytät tulkattavia skriptejä kuten sh, perl jne, muista, että skripti-tiedoston ensimmäinen rivi todella viittaa tulkin oikeaan paikkaan. Esim:

    #!/bin/sh
    #!/usr/bin/perl
  • Tarvisemasi tulkin sijainnin voit selvittää which-komennolla:

    # which perl
    /usr/bin/perl

hello1.cgi  (shell-skripti)

#!/bin/sh
echo "Content-type: text/html\n"
echo "Hello World! (sh)"

hello2.cgi (perl-skripti)

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello World! (perl)\n";

hello3.cgi (C-ohjelma)

/* Hello World! - CGI-esimerkki in C:llä */
#include <stdio.h>
int main (void)
{
printf ("Content-type: text/html\n\n");
printf("Hello World! (C)");
return;
}

C-ohjelma täytyy ensin kääntää suorituskelpoiseksi:

  • Tallenna yo. lähdekoodi nimellä hello3.c
  • cc hello3.c -o hello3.cgi
  • strip hello3.cgi

Huomautus: Skripteille (hello1.cgi ja hello2.cgi) tulee antaa sekä luku- että suoritusoikeudet ohjelmaa ajavalle käyttäjälle, mutta käännetylle C-ohjelmalle riittää pelkät suoritusoikeudet!

Tietoa ympäristöstä : env.cgi 

  • Env-komennolla saa tietoa CGI-ohjelman ajoympäristöstä.
#!/bin/sh
echo -e "Content-type: text/plain\n"
env

Tiedostoon kirjoittaminen: write.cgi

  • Kopioi ja asenna ohjelma johonkin hakemistoon, josta voit ajaa CGI-ohjelmia
  • Nuodata ohjelmakoodin kommentteihin kirjoitettuja käyttöönottoohjeita
  • Tutki datahakemistoon syntyneen tiedoston sisältöä ja tiedostomääritteitä (omistaja, oikeudet)
  • Tarkoituksena demonstroida, kuka ajaa CGI-ohjelmaa ja mitä oikeuksia tarvitaan.
#!/usr/bin/php666-cgi -q
<?php
/*

1) Asennetaan PHP:n CGI-versio

1.1) Tallenna kansiosta http://netisto.fi/php/
löytyvä tiedosto nimelle /usr/bin/php666-cgi

1.2) chmod +x /usr/bin/php666-cgi

3) Tee testi-kayttajana hakemisto:
mkdir /home/testi/public_html/data
chmod 777 /home/testi/public_html/data

*/

$wwwserver = $_SERVER['HTTP_HOST'];

$fp = fopen ("/home/testi/public_html/data/data.txt", "a");
fwrite($fp, "I Was Here\n");
echo "Katso <a href='http://$wwwserver/~testi/data/data.txt'>lopputulosta</a>";

?>


SuEXEC

HUOM: Tätä EI testatttu Ubuntu 16.04:ssä!

SuEXEC on moduuli, joka mahdollistaa CGI-ohjelmien ajamisen ohjelman omistajan oikeuksin. PHP:tä varten on olemassa suEXECiä käyttävä erillinen SUPHP-moduuli (libapache2-mod-suphp).

SuEXECin asennus

sudo aptitude install apache2-suexec-custom
sudo a2enmod suexec
sudo service apache2 restart
Ohjeet löytyvät mm.
man suexec
Konfigurointitiedosto:
/etc/apache2/suexec/www-data
Lokitiedosto:
/var/log/apache2/suexec.log
Moduulin kiinteästi käännetyt asetukset:
sudo /usr/lib/apache2/suexec -V

CGI:n lokitiedosto

  • ScriptLog-direktiivi määrittelee tiedoston, johon CGI-ohjelmien virheet voidaan lokittaa. Jotakin informaatiota saadaan jo error_log-tiedostosta.
  • Tiedosto määritellään esim. suhteessa ServerRoot-direktiivin (esim. /etc/httpd) arvoon:

    ScriptLog logs/cgi_log

    tai absoluuttisesti, jos normaalisti rootin omistuksessa olevaan logs-hakemistoon ei haluta antaa muille käyttöoikeuksia. Eli esim.

    ScriptLog /var/www/own_logs/cgi_log

  • Web-palvelinta ajavalla käyttäjällä (esim apache) tulee olla kirjoitusoikeudet ao. tiedostoon. Voidaan toimia siis esimerkiksi seuraavasti:

    # touch /etc/httpd/logs/cgi_log
    # chmod o+x /etc/httpd/logs/
    # chown apache.apache /etc/httpd/logs/cgi_log
    # chmod 700 /etc/httpd/logs/cgi_log

    tai

    # mkdir /var/www/own_logs/
    # chown apache.apache /var/www/own_logs/
    # chmod 700 /var/www/own_logs/