Apache-www-palvelin

ITKP1011 Web-julkaiseminen · korjattu laitos

Tällä luennolla käsitellään oleellisimpia Apache HTTP Server -palvelinohjelmiston ominaisuuksia. Apache on yksi maailman käytetyimmistä www-palvelimista ja erityisen yleinen jaetussa palvelintilassa, koska se on ainoa suurista palvelimista, joka tukee .htaccess- tiedostoja. Sellaista käytetään myös JYU:n kotisivupalvelimella.

Suuri osa www-sivuston tarvitsemasta toiminnallisuudesta kannattaa toteuttaa jo palvelimella, koska siellä se toimii varmasti riippumatta käyttäjän selaimesta.

Oppimistavoitteet

Tämän luennon jälkeen sinun pitäisi osata:

Apachen versio

Tämä materiaali koskee Apache 2.4:ää, joka on ollut nykyinen versio vuodesta 2012. Verkossa on paljon ohjeita vanhemmille versioille 1.3, 2.0 ja 2.2, joiden tuki on päättynyt. Erityisesti pääsynhallinnan syntaksi muuttui kokonaan version 2.4 myötä, joten vanhan ohjeen mukaan kirjoitettu .htaccess ei toimi. Tarkista aina, että lukemasi ohje koskee versiota 2.4.

1. .htaccess

.htaccess on hakemistokohtainen asetustiedosto, jolla voi muuttaa palvelimen toimintaa ilman pääsyä palvelimen omaan konfiguraatioon. Sillä voi toteuttaa muun muassa salasanasuojauksen, uudelleenohjauksen ja mediatyyppien lisäykset.

Kolme asiaa, jotka menevät helposti pieleen
Jos mikään ei tapahdu

.htaccess-tiedosto toimii vain, jos palvelimen pääkonfiguraatio sallii sen AllowOverride-direktiivillä. Jos asetuksesi eivät vaikuta mitään eikä virhettäkään tule, kyse on todennäköisesti tästä. JYU:n kotisivupalvelimella tavallisimmat direktiivit ovat sallittuja.

2. Uudelleenohjaus

Uudelleenohjaus tehdään HTTP:n omilla vastauskoodeilla ja Location-otsikkotiedolla. Apachessa on tätä varten valmiit direktiivit.

Älä tee ohjausta sivulla

Uudelleenohjausta ei pidä tehdä väliaikaisella www-sivulla, joka siirtää käyttäjän eteenpäin meta refresh -tempulla tai skriptillä. Ne rikkovat selaimen paluupainikkeen, hämmentävät ruudunlukijan käyttäjää eivätkä kerro hakukoneille mitään sivun siirtymisestä.

2.1 Väliaikainen ohjaus (302)

Redirect /vanha/index.html https://appro.mit.jyu.fi/uusi/

Ohjattavan sivun osoite kerrotaan palvelimen juuresta lukien, ja kohdeosoite kirjoitetaan kokonaisuudessaan protokollaa myöten.

2.2 Pysyvä ohjaus (301)

Redirect permanent /vanha/index.html https://appro.mit.jyu.fi/uusi/

Pysyvä ohjaus tehdään lisäämällä avainsana permanent. Hakukoneet siirtävät silloin vanhan osoitteen sijoituksen uudelle osoitteelle.

Aloita väliaikaisesta

Selaimet tallentavat pysyvän ohjauksen välimuistiinsa ja noudattavat sitä kysymättä palvelimelta uudelleen, käytännössä pysyvästi. Väärin tehtyä 301-ohjausta on siis hyvin vaikea perua: käyttäjän selain ohjaa väärään paikkaan vielä senkin jälkeen, kun olet korjannut asetuksen. Tee ohjaus ensin väliaikaisena, varmista että se toimii, ja vaihda vasta sitten pysyväksi.

2.3 Useamman tiedoston ohjaus

Kun samaan kohteeseen halutaan ohjata useampi tiedosto, käytetään RedirectMatch-direktiiviä. Säännöllinen lauseke kirjoitetaan lähdepolkuun, ei kohteeseen.

RedirectMatch permanent ^/doc/tietokone/pc.*  https://appro.mit.jyu.fi/doc/tietokone/
RedirectMatch permanent ^/doc/kayttojarjestelma/win.*  https://appro.mit.jyu.fi/doc/kayttojarjestelma/

Merkki ^ kiinnittää kuvion polun alkuun. Muista, että piste on säännöllisessä lausekkeessa erikoismerkki, joka vastaa mitä tahansa merkkiä. Jos haluat tarkoittaa oikeaa pistettä, kirjoita se muodossa \.. Säännöllisiä lausekkeita käsitellään komentoriviluennolla.

Lähteen osia voi käyttää kohteessa sulkeilla ja viittauksilla $1, $2 ja niin edelleen:

RedirectMatch permanent ^/vanha/(.*)$  https://appro.mit.jyu.fi/uusi/$1

Lisätietoa: mod_alias.

3. Käytettävä merkistö

Palvelin voi kertoa vastauksen mukana, mitä merkistöä tiedostossa käytetään. Tällä on merkitystä, koska HTTP-otsikossa ilmoitettu merkistö voittaa aina dokumentin oman meta charset -määrityksen. Jos palvelin ilmoittaa väärän merkistön, ääkköset näkyvät väärin, vaikka tiedosto olisi oikein tallennettu ja meta-rivi paikallaan.

Kyse ei ole selainten erikoisuuksista

Vanhoissa ohjeissa asia esitetään niin, että "tietyt selaimet (ainakin Internet Explorer)" käyttäisivät palvelimen merkistöä. Näin toimivat kaikki selaimet, koska standardi määrää niin. Samoissa ohjeissa väitetään myös, että palvelimen oletusmerkistö olisi ISO-8859-1. Direktiivin AddDefaultCharset oletusarvo on Off, eli palvelin ei oletuksena ilmoita merkistöä lainkaan vaan jättää asian dokumentin itsensä kerrottavaksi.

Yksittäisten tiedostopäätteiden merkistön voi asettaa näin:

AddCharset utf-8 .html .css .js .txt
Varo AddDefaultCharset-direktiiviä

Merkintä AddDefaultCharset utf-8 pakottaa merkistön kaikkiin tekstimuotoisiin tiedostoihin ja ohittaa niiden omat määritykset. Jos hakemistossa on yksikin muussa merkistössä oleva tiedosto, se menee rikki. Käytä mieluummin AddCharset-direktiiviä, tai älä koske asiaan lainkaan ja varmista sen sijaan, että kaikki tiedostot ovat UTF-8-muodossa ja niissä on meta charset -rivi.

4. Mediatyypit

Mediatyyppi eli MIME-tyyppi kertoo selaimelle, millainen tiedosto on kyseessä ja miten se pitäisi käsitellä. Selain ei päättele tyyppiä tiedostopäätteestä vaan luottaa siihen, minkä palvelin ilmoittaa. Väärä tai puuttuva mediatyyppi on tavallinen syy siihen, että selain tarjoaa tiedostoa ladattavaksi sen sijaan että näyttäisi sen, tai ettei video toistu.

Tyyppi asetetaan AddType-direktiivillä:

# Määrätään .html-päätteisten tiedostojen mediatyypiksi text/plain,
# jolloin selain näyttää koodin sellaisenaan eikä tulkitse sitä
AddType text/plain .html

# ja päinvastoin
AddType text/html .txt

4.1 Usein tarvittavia mediatyyppejä

Apachen mukana tulee valmis luettelo tavallisimmista tyypeistä, joten useimmiten mitään ei tarvitse lisätä. Uudempi formaatti voi silti puuttua vanhemmasta asennuksesta.

AddType image/webp .webp
AddType image/avif .avif
AddType image/svg+xml .svg
AddType video/mp4 .mp4
AddType video/webm .webm
AddType audio/mpeg .mp3
AddType audio/ogg .ogg .opus
AddType application/pdf .pdf
AddType application/xml .xml
AddType application/xhtml+xml .xhtml
AddType text/vtt .vtt
Vanhoissa ohjeissa on virheellisiä tyyppejä
Vanhoissa ohjeissaOikein
application/x-oggaudio/ogg tai video/ogg
audio/x-mp3audio/mpeg
video/avivideo/x-msvideo
text/xml .xslapplication/xslt+xml .xsl

Etuliite x- oli aikoinaan tapa merkitä rekisteröimätön tyyppi, eikä sitä enää käytetä. Rekisteröidyt tyypit löytyvät IANAn luettelosta.

Lisätietoa: mod_mime: AddType ja MIME types (MDN). Mediatyyppien käyttöä kuvien ja videoiden kanssa käsitellään multimedialuennolla.

5. Hakemiston indeksitiedosto

Selaimella voidaan pyytää hakemistoa ilman tiedostonimeä, esimerkiksi https://users.jyu.fi/~tunnus/harkka/. Palvelin etsii silloin hakemistosta oletustiedoston, joka on tavallisesti index.html.

Oletustiedoston voi vaihtaa DirectoryIndex-direktiivillä:

DirectoryIndex index.shtml index.html

Vaihtoehtoja voi luetella useita. Palvelin tarjoaa ensimmäisen, joka hakemistosta löytyy. Esimerkissä tarjotaan ensin index.shtml-tiedostoa ja sen puuttuessa index.html-tiedostoa. Tätä tarvitaan, jos sivuilla käytetään SSI-komentoja.

5.1 Hakemistolistaus

Jos hakemistosta ei löydy yhtään DirectoryIndex-tiedostoa, palvelin voi luoda automaattisesti sivun, joka listaa hakemiston tiedostot. JYU:n kotisivupalvelimella automaattinen listaus on oletuksena pois päältä, jolloin selain saa virheen 403 (Forbidden).

Listauksen saa halutessaan käyttöön hakemistokohtaisesti:

Options +Indexes

Listausta voi myös siistiä. IndexIgnore jättää tiedostoja pois näkyvistä ja IndexOptions säätää esitystapaa:

Options +Indexes
IndexOptions FancyIndexing HTMLTable NameWidth=*
IndexIgnore .htaccess *.bak *~

Vastaavasti listauksen saa pois päältä merkinnällä Options -Indexes, jos se on jossain hakemistossa päällä.

Listaus näyttää kaiken

Automaattinen listaus paljastaa hakemiston kaikki tiedostot, myös keskeneräiset versiot, varmuuskopiot ja sellaiset, joihin et ole linkittänyt mistään. Ota se käyttöön vain hakemistoissa, joiden koko sisällön haluat julkiseksi, esimerkiksi kuvakansiossa.

Lisätietoa: mod_dir ja mod_autoindex.

6. Salasanasuojaus

Hakemiston voi suojata salasanalla .htaccess-tiedostolla. Tarvitaan kaksi tiedostoa: asetukset ja käyttäjätunnusten tiedosto.

Luo ensin salasanatiedosto komentoriviltä. Valitsin -c luo uuden tiedoston, ja se pyyhkii olemassa olevan, joten seuraavia käyttäjiä lisättäessä se jätetään pois:

htpasswd -c ~/.htpasswd matti     # luo tiedoston ja ensimmäisen käyttäjän
htpasswd ~/.htpasswd maija       # lisää käyttäjän olemassa olevaan

Kirjoita sitten suojattavan hakemiston .htaccess-tiedostoon:

AuthType Basic
AuthName "Suojattu alue"
AuthUserFile /home/omatunnus/.htpasswd
Require valid-user
Direktiivien merkitys.
DirektiiviMerkitys
AuthType BasicKäytettävä tunnistautumistapa
AuthNameTeksti, joka näkyy selaimen kysymysikkunassa. Lainausmerkit ovat pakolliset, jos siinä on välilyöntejä
AuthUserFileSalasanatiedoston koko polku palvelimen tiedostojärjestelmässä, ei www-osoite
Require valid-userKuka tahansa tiedostossa oleva käyttäjä pääsee sisään. Yksittäiset käyttäjät: Require user matti maija
Kaksi olennaista varoitusta
Syntaksi muuttui Apache 2.4:ssä

Verkossa on paljon ohjeita, joissa käytetään direktiivejä Order, Allow ja Deny. Ne kuuluvat versioon 2.2 eivätkä toimi enää; tilalle tuli Require. Jos ohje puhuu niistä, se on vanhentunut.

Katso myös pääteohjaustehtävän ohje, digipalvelujen ohje ja Authentication and Authorization.

7. Automaattinen kielivalinta

Apache osaa tarjota saman sivun eri kielisinä versioina sen mukaan, mitä kieliä käyttäjän selain ilmoittaa haluavansa. Ominaisuutta kutsutaan nimellä content negotiation.

Yksinkertaisimmillaan tiedostot nimetään kielikoodin mukaan (index.fi.html, index.en.html), ja palvelin valitsee sopivan, kun selain pyytää osoitetta index.html. Tarkemman hallinnan saa .var-tiedostoilla eli typemapeilla, joissa kerrotaan jokaisen version osoite, kieli ja mediatyyppi.

Ominaisuutta tarvitaan harvoin, ja nykyään monikielisyys hoidetaan yleensä erillisillä osoitteilla, esimerkiksi /fi/ ja /en/, koska silloin käyttäjä näkee osoitteesta millä kielellä sivu on ja voi jakaa linkin halutulla kielellä. Jos haluat perehtyä asiaan, Apachen oma ohje kertoo kaiken tarvittavan:

8. Toistuvien osien liittäminen

Sivustolla on yleensä osia, jotka toistuvat joka sivulla: navigointi, otsake, tekijätiedot. Jos ne kirjoitetaan jokaiseen tiedostoon erikseen, yhden linkin lisääminen vaatii kaikkien sivujen muokkaamista. Ratkaisu on kirjoittaa toistuva osa yhteen tiedostoon ja liittää se muihin.

8.1 SSI (Server Side Includes)

SSI-komennot ovat HTML-dokumenttiin kirjoitettuja käskyjä, jotka palvelin suorittaa ennen kuin lähettää sivun selaimelle. Selain ei siis koskaan näe komentoja vaan valmiin lopputuloksen.

Komento kirjoitetaan HTML-kommentin näköisenä, mutta risuaidalla heti aloitusmerkinnän jälkeen:

<!--#komento parametri="arvo" -->
Tiedostopäätteen on oltava .shtml

JYU:n www-palvelimella SSI-komennot suoritetaan vain tiedostoista, joiden pääte on .shtml. Tavallisesta .html-tiedostosta komennot eivät suoritu, vaan ne jäävät kommenteiksi eivätkä näy sivulla mitenkään. Tämä on tavallisin syy siihen, ettei SSI näytä toimivan.

Muista siis nimetä sivut .shtml-päätteellä ja lisätä hakemiston .htaccess-tiedostoon:

DirectoryIndex index.shtml index.html

Omalla palvelimella SSI otetaan käyttöön asetuksilla Options +Includes ja AddHandler server-parsed .shtml.

8.2 Tavallisimmat SSI-komennot

Toisen tiedoston sisällön liittäminen. Tämä on SSI:n tärkein käyttötapa. Käytä aina virtual-parametria, joka tulkitsee polun www-osoitteena, älä file-parametria.

<!--#include virtual="navigointi.ssi" -->
<!--#include virtual="/~omatunnus/yhteiset/alatunniste.ssi" -->

Liitettävä tiedosto sisältää pelkän katkelman HTML-koodia, ei kokonaista dokumenttia. Esimerkiksi navigointi.ssi:

<nav>
  <ul>
    <li><a href="/~omatunnus/">Etusivu</a></li>
    <li><a href="/~omatunnus/harkka/">Harjoitustyö</a></li>
  </ul>
</nav>

Muuttujan asettaminen ja tulostaminen. Näin saman tiedon voi kirjoittaa kerran ja käyttää monessa kohdassa sivua.

<!--#set var="otsikko" value="Nanonano" -->

<title><!--#echo var="otsikko" --></title>
...
<h1><!--#echo var="otsikko" --></h1>
Käytä heittomerkkejä attribuutin sisällä

Jos SSI-komento kirjoitetaan HTML-attribuutin arvon sisään, lainausmerkit menevät sisäkkäin ja merkintä hajoaa:

<!-- väärin: lainausmerkit menevät sisäkkäin -->
<link rel="stylesheet" href="<!--#echo var="css" -->" />

SSI hyväksyy myös heittomerkit, joten ongelma ratkeaa vaihtamalla sisemmät:

<!-- oikein -->
<link rel="stylesheet" href="<!--#echo var='css' -->" />

Yksinkertaisempi vaihtoehto on kirjoittaa koko rivi liitettävään tiedostoon.

Muutosajankohdan tulostaminen. Palvelin lukee ajan tiedoston tiedoista, joten se pysyy oikeana ilman käsityötä.

<!--#config timefmt="%Y-%m-%d %H:%M" -->
<p>Päivitetty <!--#echo var="LAST_MODIFIED" --></p>
Tavallisimmat SSI-muuttujat.
MuuttujaSisältö
LAST_MODIFIEDTiedoston muutosajankohta
DATE_LOCALPalvelimen nykyinen aika
DOCUMENT_NAMETiedoston nimi
DOCUMENT_URITiedoston osoite palvelimen juuresta

8.3 Kokonainen esimerkki

Tiedosto index.shtml:

<!DOCTYPE html>
<!--#set var="otsikko" value="Nanonano" -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="fi" xml:lang="fi">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title><!--#echo var="otsikko" --></title>
    <link rel="stylesheet" href="/~omatunnus/tyyli.css" />
  </head>
  <body>

    <!--#include virtual="/~omatunnus/yhteiset/navigointi.ssi" -->

    <main>
      <h1><!--#echo var="otsikko" --></h1>
      <p>Sivun sisältö tähän.</p>
    </main>

    <!--#include virtual="/~omatunnus/yhteiset/alatunniste.ssi" -->

  </body>
</html>

Tiedosto yhteiset/alatunniste.ssi:

<footer>
  <p>Päivitetty <!--#config timefmt="%Y-%m-%d" --><!--#echo var="LAST_MODIFIED" --></p>
  <address><a href="mailto:nobody@example.invalid">Nanonano</a></address>
</footer>
Validointi ja SSI

Palvelimelta haettu .shtml-sivu validoituu normaalisti, koska komennot on jo suoritettu. Sen sijaan paikallista tiedostoa ei kannata validoida: siinä komennot ovat vielä paikallaan ja liitettävät osat puuttuvat, jolloin dokumentti ei ole kokonainen. Käytä validaattorin Check by Address -vaihtoehtoa ja anna sille julkaistun sivun osoite.

Lisätietoa: mod_include ja Introduction to Server Side Includes.

9. Lisätietoa

Käyttäjien kommentit

Kommentoi Lisää kommentti