Seitsemännet tehtävät – vanhan arvioitavan laboratorioharjoituksen ratkaiseminen

Kurssimme alkaa nyt olla aivan loppusuoralla ja ensi tiistaina on vuorossa enää arvioitavan laboratorioharjoituksen tekeminen. Tämän viikon tehtävänä onkin jonkin omavalintaisen aikaisemman laboratorioharjoituksen ratkaiseminen. Tein itse jo tunnilla suurimman osan tästä harjoituksesta, joten tarkoituksenani on nyt ratkaista jokin muu harjoitus. Tämä vuoden 2017 alkusyksyn harjoitus vaikuttaa teemansa puolesta siisteimmältä, joten taidan valita sen.

LAMP-stack

NinjaTietokanta 

Haluamme tehdä palvelun, jossa listataan ninjaliikkeitä makeuden, tyylisuunnan ja muiden keskeisten ominaisuuksien suhteen.
Kehittäjämme haluavat käyttää LAMP (Linux Apache MySQL PHP) -pinoa. Asenna tarvittavat ohjelmistot ja tee tietokantaa käyttävä esimerkkiohjelma.

Aloitin testaamalla, vastaako localhost selaimesta. Ei vastaa, eikä pitäisikään. Asennan Apache2:sen komennolla

$ sudo apt-get install apache2

Tämän jälkeen localhost näyttää Apachen oletussivun, jonka ylikirjoitan komennolla

$ echo hei|sudo tee /var/www/html/index.html

Tämän jälkeen sivulle tulee lukemaan vain ”hei”. Tiedän jo tässä vaiheessa, että käyttäjiä tulee olemaan useita, ja heille tulee kaikille omat kotisivut, joten sallin tämän komennolla

$ sudo a2enmod userdir

, jonka jälkeen ajan myös komennon

$ sudo systemctl restart apache2

, jotta muutokset tulisivat voimaan.

Seuraavaksi testaan, että tähän mennessä tekemäni asiat toimivat. Teen omaan kotihakemistooni public_html -kansion, jonne teen yksinkertaisen index.html-sivun seuraavaa koodia käyttäen:

<html>
<head>
<meta charset="UTF-8">
<title>Hei Ninja!</title>
</head>
<body>
<p>Hei Ninja!</p>
<body>
</html>

Tallentamisen jälkeen menen selaimessa osoitteeseen localhost/~noora/ ja sivulle ilmestyy näkyviin teksti ”Hei Ninja!” kuten kuuluukin. Voin siis lähteä hyvillä mielin asentamaan MariaDB:tä ja PHP:tä. Asennan ensin PHP:n komennolla

$ sudo apt-get install php

Seuraavaksi sallin php:n suorittamisen käyttäjien kotihakemistoissa muokkaamalla tiedostoa /etc/apache2/mods-available/php7.2.conf
siten, että kommentoin viisi alinta riviä pois käytöstä. Tämän jälkeen käynnistän Apachen uudestaan komennolla

$ sudo systemctl restart apache2

ja siirryn muokkaamaan omaa index.html:ääni. Muutan tiedoston päätteeksi aluksi .php komennolla

$ mv index.html index.php

Tämän jälkeen lisään koodiini muutaman PHP-rivin:

<html>
<head>
<meta charset="UTF-8">
<title>Hei Ninja!</title>
</head>
<body>
<p>Hei Ninja!</p>
<?php echo "Hei taas, Ninja!"; ?>
<?php print (6+6); ?>

</body>
</html>

Selaimeen ilmestyy sivun tallentamisen ja päivittämisen jälkeen teksti ”Hei taas, Ninja! 12”, joten PHP vaikuttaisi toimivan. Seuraavaksi on siis vuorossa MariaDB, jonka asentamiseen käytän tukena Tero Karvisen sivuilta löytyviä ohjeita. Aloitan siis antamalla komennon

$ sudo apt-get install mariadb-client mariadb-server

MariaDB:n asennus vaatii ilmeisesti palomuurin, joten nyt lienee hyvä hetki säätää UFW:n asetukset kuntoon. Annankin seuraavat komennot:

noora@koekone:~/public_html$ sudo ufw allow 22/tcp
Rules updated
Rules updated (v6)
noora@koekone:~/public_html$ sudo ufw allow 80/tcp
Rules updated
Rules updated (v6)
noora@koekone:~/public_html$ sudo ufw enable
Firewall is active and enabled on system startup
noora@koekone:~/public_html$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)

Tämän jälkeen SSH- ja HTTP-liikenteen pitäisi olla sallittu ja voin siirtyä MariaDBn varsinaiseen asennukseen komennolla

$ sudo mysql_secure_installation

Asennuksessa määrittelen root-käyttäjälle uuden salasanan ja määrittelen muut asetukset seuraavasti:

Set root password? [Y/n] 
New password:
Re-enter new password:
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Seuraavaksi olisi tarkoitus luoda uusi tietokanta, jonne syötetään dataa. Tämän tehdäkseni kirjaudun MariaDB:hen komennolla

$ sudo mariadb -u root -p

Tämän jälkeen luon testitietokannan ja annan käyttäjälle tyyppi luvan sen käyttöön:

MariaDB [(none)]> CREATE DATABASE testdb;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
4 rows in set (0.00 sec)

MariaDB [(none)]> GRANT ALL ON testdb.* TO tyyppi@localhost IDENTIFIED BY 'XD8ZE3d_.n';
Query OK, 0 rows affected (0.00 sec)

Salasanan generoimiseksi asensin pwgen-ohjelman komennolla

$ sudo apt-get install pwgen

, jonka jälkeen generoin salasanan komennolla

$ pwgen -s 10 1 -1 -y

näiden ohjeiden mukaisesti. -s on lyhenne secure:sta, eli pwgen ei yritä erikseen tehdä salasanasta helpommin muistettavaa, vaan se arpoo merkit täysin satunnaisesti. Sitä seuraavat numerot tarkoittavat, että halusin yhden 10 merkkiä pitkän salasanan, jossa on vähintään yksi erikoismerkki.

Tämän operaation tehtyäni kirjauduin MariaDB:stä ulos ja kirjauduin uudestaan sisään juuri luomillani tunnuksilla:

$ mariadb -u tyyppi -p

ja tein tietokantaan seuraavat muutokset:

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| testdb |
+--------------------+
2 rows in set (0.00 sec)
MariaDB [(none)]> USE testdb;
Database changed
MariaDB [testdb]> CREATE TABLE thing (id int auto_increment not null, name varchar(30),primary key(id));
Query OK, 0 rows affected (0.01 sec)
MariaDB [testdb]> INSERT INTO thing(name) VALUES("Ninja"),("Dinosaur"),("Owl"),("Book");
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
MariaDB [testdb]> SELECT * FROM thing;
+----+----------+
| id | name |
+----+----------+
| 1 | Ninja |
| 2 | Dinosaur |
| 3 | Owl |
| 4 | Book |
+----+----------+
4 rows in set (0.00 sec)

Tämän jälkeen poistuin MariaDB:stä ja siirryin muokkaamaan omaa index.php-sivuani. Lisäsin omalle sivulleni opettajamme kirjoittaman koodin omaan käyttööni muokatussa muodossa:

 <html>
<head>
<meta charset="UTF-8">
<title>Hei Ninja!</title>
</head>
<body>
<p>Hei Ninja!</p>
<?php echo "Hei taas, Ninja!"; ?>
<?php print (6+6); ?>

<p>All the things:</p>

<?php
// connect
$pdo=new PDO("mysql:host=localhost;charset=UTF8;dbname=testdb", 'tyyppi', 'XD8ZE3d_.n');
// list
$pdoStatement=$pdo->prepare('SELECT * FROM thing;');
$pdoStatement->execute();
$hits=$pdoStatement->fetchAll();
foreach($hits as $row) {
echo "<p>".$row['id']." ".htmlentities($row['name'])."</p>\n";
}
?>

</body>
</html>

Tässä vaiheessa taas muistin, että olin unohtanut asentaa erään puuttuvan palasen, ja korjasin tilanteen komennoilla:

$ sudo apt-get install php-mysql
$ sudo systemctl restart apache2

Tämän jälkeen listaus tuli sivulle näkyviin.

SSH:n asentaminen

Etätyötä
Haluamme työskennellä etäältä (kuin ninjat piiloistaan).

Oletan tämän tehtävänannon tarkoittavan, että SSH-yhteys pitäisi saada käyttöön. Aiemmin sallin SSH-yhteyden käytön palomuurin läpi, joten nyt puuttunee enää SSH:n asennus, joka tapahtuu komennolla

$ sudo apt-get install openssh-server

Käyttäjien kotisivut

Käyttäjät
Työntekijämme ovat toimitusjohtaja Nakke Nertola, Håkan Värs, Einari Mikkonen, Einari Öljysaari ja Eija Vähäkäähkä. Tee kaikille käyttäjille esimerkkikotisivut.

Työntekijöiden joukossa vaikuttaa olevan kaksi Einaria, joten käyttäjänimet on tässä tapauksessa todennäköisesti hyvä muodostaa sekä etu- että sukunimestä. Käyttäjänimet eivät saa sisältää ääkkösiä, joten luon seuraavanlaiset käyttäjätunnukset:

nakkener
hakanvar
einarmik
einarolj
eijavaha

ja laitan ne tiedostoon users.txt. Muutan sen jälkeen tiedostoa siten, että vain minä ja omaan ryhmääni kuuluvat henkilöt voivat lukea tai muokata sen sisältöä:

noora@koekone:~/tiedostot$ ls -l
total 4
-rw-rw-r-- 1 noora noora 45 maali 10 21:48 users.txt
noora@koekone:~/tiedostot$ chmod o-r users.txt
noora@koekone:~/tiedostot$ ls -l
total 4
-rw-rw---- 1 noora noora 45 maali 10 21:48 users.txt

Tämän jälkeen generoin kaikille käyttäjille omat salasanat users.txt -tiedostoon seuraavalla komennolla:

$ for i in $( cat users.txt ); do pwgen -s -1 10 1 | sed "s/^/$i /"; done

Komento antaa myös terminaaliin seuraavan tulosteen:

nakkener eQ9WjRcPeG
hakanvar Adq0VHlHsH
einarmik woBNWAxrP1
einarolj naPCdkMZj1
eijavaha nZw9eZAWq3

Nyt kaikilla käyttäjillä on suhteellisen hyvät salasanat, ilman erikoismerkkejä tosin. Voin siis alkaa lisäämään käyttäjiä.

Lisään kaikki käyttäjät samaan tyyliin kuin tässä tapauksessa, vain tunnukset, salasanat ja nimet vaihtuvat:

noora@koekone:~/tiedostot$ sudo adduser eijavaha
Adding user eijavaha' ... Adding new groupeijavaha' (1005) …
Adding new user eijavaha' (1005) with groupeijavaha' …
Creating home directory /home/eijavaha' ... Copying files from/etc/skel' …
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for eijavaha
Enter the new value, or press ENTER for the default
Full Name []: Eija Vähäkäähkä
Room Number []:
Work Phone []:
Home Phone []:
Other []:
chfn: name with non-ASCII characters: 'Eija Vähäkäähkä'
Is the information correct? [Y/n] y

Tämän jälkeen voin vielä varmistaa, että kaikki on niin kuin pitääkin antamalla komennon

$ less /etc/passwd 

Tiedoston hännillä on nyt lista juuri lisätyistä käyttäjistä:

nakkener:x:1001:1001:Nakke Nertola,,,:/home/nakkener:/bin/bash
hakanvar:x:1002:1002:Håkan Värs,,,:/home/hakanvar:/bin/bash
einarmik:x:1003:1003:Einari Mikkonen,,,:/home/einarmik:/bin/bash
einarolj:x:1004:1004:Einari Öljysaari,,,:/home/einarolj:/bin/bash
eijavaha:x:1005:1005:Eija Vähäkäähkä,,,:/home/eijavaha:/bin/bash

Nyt puuttuu enää käyttäjien kotisivujen tekeminen. Haluaisin kaikkien käyttäjien kotisivuille hieman erilaiset tekstit, joten näiden ohjeiden avulla kehittelin pienen koodinpätkän, joka tulostaa sivulle PHP-skriptin omistajan käyttäjätunnuksen:

<html>
<head>
<meta charset="UTF-8">
<title>Kotisivut</title>
</head>
<body>
<?php
echo "Hei kaikille! Minun käyttäjätunnukseni on " . get_current_user();
?>
</body>
</html>

Nyt voin kopioida saman sivun käyttäjien kotihakemistoihin. Käyttäjillä ei tosin ole omia public_html-kansioita, joten kirjaudun jokaisen käyttäjän tunnuksille seuraavantyylisellä komennolla

$ ssh nakkener@localhost

ja luon public_html-kansion kotihakemistoon komennolla

$ mkdir public_html

Kunkin käyttäjän hakemiston luomisen jälkeen kirjaudun ulos komennolla exit. Nyt kun jokaiselle käyttäjälle on luotu public_html -kansio, voin alkaa siirtelemään user.php-tiedostoa ympäriinsä scp-komennolla. Halusin, että oma user.php:ni näkyy suoraa kunkin käyttäjän kotihakemistossa, joten kopioin oman user.php:n ensin itselleni toiseen kansioon (minullahan on jo index.php, jonka toimintaa en halua häiritä), ja vaihdoin sen nimen index.php:ksi. Tätä index.php:tä kopioin muille käyttäjille:

noora@koekone:~/tiedostot$ ls -a
. .. index.php users.txt
noora@koekone:~/tiedostot$ scp index.php nakkener@localhost:/home/nakkener/public_html/
nakkener@localhost's password:
index.php 100% 216 386.8KB/s 00:00
noora@koekone:~/tiedostot$ scp index.php hakanvar@localhost:/home/hakanvar/public_html/
hakanvar@localhost's password:
index.php 100% 216 255.6KB/s 00:00
noora@koekone:~/tiedostot$ scp index.php einarmik@localhost:/home/einarmik/public_html/
einarmik@localhost's password:
index.php 100% 216 234.8KB/s 00:00
noora@koekone:~/tiedostot$ scp index.php einarolj@localhost:/home/einarolj/public_html/
einarolj@localhost's password:
index.php 100% 216 846.2KB/s 00:00
noora@koekone:~/tiedostot$ scp index.php eijavaha@localhost:/home/eijavaha/public_html/
eijavaha@localhost's password:
index.php 100% 216 411.2KB/s 00:00

Tämän jälkeen tarkistin selaimella, että index.php tuli näkyviin kaikkien käyttäjien kotisivuille, ja niin se tulikin. Tässä yksi kuva esimerkiksi:

Tulimuuri

Suuri muuri
Suojaa kone tulimuurilla.

Tämän tein jo MariaDB:n asentamisen yhteydessä, mutta kopioin prosessin vielä uudestaan tähän:

noora@koekone:~/public_html$ sudo ufw allow 22/tcp
Rules updated
Rules updated (v6)
noora@koekone:~/public_html$ sudo ufw allow 80/tcp
Rules updated
Rules updated (v6)
noora@koekone:~/public_html$ sudo ufw enable
Firewall is active and enabled on system startup
noora@koekone:~/public_html$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)

Bash-skriptin teko

WhoWhere
Tee kaikkien käyttäjien käyttöön komento, joka tulostaa Ninjamaisen tervehdyksen “Hello Ninja”, koneen IP-osoitteen ja komentoa ajavan käyttäjän nimen.

Tein omaan kotihakemistooni ensin nanolla tiedoston whowhere:

#!/bin/bash
printf "Hello Ninja\n"
hostname -I
whoami

En muistanut ulkoa bashin print-funktion käyttöä, rivinvaihtoa tai lyhyttä IP-osoitteen tarkistuskomentoa, joten jouduin metsästämään ne Googlesta. Skriptin ensimmäinen rivi kertoo, että skripti on tarkoitus ajaa nimenomaan bashilla.

Testattuani tiedoston toimintaa komennolla

$ ./whowhere

tajusin, ettei minulla ole vielä oikeuksia ajaa skriptiä, joten annoin oikeudet itselleni ja muille skriptin ajamiseen komennolla

$ ugo+x whowhere

Tämän jälkeen annoin komennon

$ sudo cp whowhere /usr/local/bin/

, eli siirsin tiedoston hakemistoon, josta sen voi suorittaa kuka tahansa käyttäjä riippumatta siitä, missä hakemistossa hän sillä hetkellä on. Testatakseni tätä kirjauduin Nakke Nertolan tunnuksille komennolla

$ ssh nakkener@localhost

ja whowhere-skripti toimikin myös hänen kotihakemistostaan käsin:

nakkener@koekone:~$ whowhere
Hello Ninja
10.0.2.15
nakkener

Viralliset kotisivut ja ninjatietokanta

SneakyGarden.Example.com
Virallinen ninjaliikesivumme tulee Eijan ylläpidettäväksi. Tee Eijalle valmis esimerkkisivu, jossa tietokannassa on seuraavat esimerkkiliikkeet vaikeustasoineen

Hyppykiertopotku 27
Kuperkeikka 3
Karjaisu 1

Sivun tulee olla Eijan muokattavissa ja ninjaliikkeiden näkyä osoitteessa http://SneakyGarden.Example.com. Nimipalvelun toimintaa voit simuloida hosts-tiedostolla.

En nyt tee Eijalle omia tietokantatunnuksia, vaan hän saakoon käyttää aikaisemmin luomiani tunnuksia. Kirjaudun aluksi Eijan tunnuksille komennolla

$ ssh eijavaha@localhost

ja tämän jälkeen kirjaudun MariaDB:hen tekemään aikaisemmin luomaani testdb-tietokantaan uuden ninjaliikkeet-taulun.

MariaDB [(none)]> USE testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [testdb]> CREATE TABLE ninjaliikkeet(id int auto_increment not null, nimi varchar(40),vaikeus int, primary key(id));
Query OK, 0 rows affected (0.01 sec)
MariaDB [testdb]> INSERT INTO ninjaliikkeet(nimi, vaikeus) VALUES ("Hyppykiertopotku", 27),("Kuperkeikka", 3),("Karjaisu", 1);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [testdb]> SELECT * FROM ninjaliikkeet;
+----+------------------+---------+
| id | nimi | vaikeus |
+----+------------------+---------+
| 1 | Hyppykiertopotku | 27 |
| 2 | Kuperkeikka | 3 |
| 3 | Karjaisu | 1 |
+----+------------------+---------+
3 rows in set (0.00 sec)

Tämän jälkeen teen Eijan kotihakemistoon public_sites -kansion ja sinne kansion nimeltä SneakyGarden.Example.com, jonka sisälle teen index.php-sivun:

<html>
<head>
<meta charset="UTF-8">
<title>Ninjaliikkeet</title>
</head>
<body>
<p>Ninjaliikkeet:</p>

<?php
// connect
$pdo=new PDO("mysql:host=localhost;charset=UTF8;dbname=testdb", 'tyyppi', 'XD8ZE3d_.n');
// list
$pdoStatement=$pdo->prepare('SELECT * FROM ninjaliikkeet;');
$pdoStatement->execute();
$hits=$pdoStatement->fetchAll();
foreach($hits as $row) {
echo "<p>".$row['id']." ".htmlentities($row['nimi']).", vaikeus: " .$row['vaikeus']."</p>\n";
}
?>

</body>
</html>

Tämän jälkeen palasin takaisin omille tunnuksilleni ja laitoin sivun käyttökuntoon Tero Karvisen ohjeiden mukaisesti:

noora@koekone:~/tiedostot/skriptit$ sudoedit /etc/apache2/sites-available/SneakyGarden.Example.com.conf
[sudo] password for noora:
noora@koekone:~/tiedostot/skriptit$ cat /etc/apache2/sites-available/SneakyGarden.Example.com.conf
<VirtualHost *:80>
ServerName SneakyGarden.Example.com
ServerAlias www.SneakyGarden.Example.com
DocumentRoot /home/eijavaha/public_sites/SneakyGarden.Example.com
<Directory /home/eijavaha/public_sites/SneakyGarden.Example.com>
Require all granted
</Directory>
</VirtualHost>
noora@koekone:~/tiedostot/skriptit$ sudo a2ensite SneakyGarden.Example.com
Enabling site SneakyGarden.Example.com.
To activate the new configuration, you need to run:
systemctl reload apache2
noora@koekone:~/tiedostot/skriptit$ sudo systemctl restart apache2
noora@koekone:~/tiedostot/skriptit$ sudoedit /etc/hosts
noora@koekone:~/tiedostot/skriptit$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 koekone
127.0.0.1 SneakyGarden.Example.com
127.0.0.1 www.SneakyGarden.Example.com

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Tämän jälkeen ninjaliikesivu tuli näkyviin osoitteessa sneakygarden.example.com:

Vallan vaihto

Uusi ylläpitäjä
Uusi ylläpitäjä on Jussi Laitavalo. Tee hänelle käyttäjätunnus jussi ja anna hänen käyttöönsä täydet pääkäyttäjän oikeudet.

Arvoin ensin myös Jussille salasanan pwgen -s 10 1 -1 -y -komennolla. Tämän jälkeen tein hänelle käyttäjätunnukset ja lisäsin hänet sudo-ryhmään seuraavalla tavalla:

noora@koekone:/etc/apache2/sites-available$ sudo adduser jussi
Adding user jussi' ... Adding new groupjussi' (1006) …
Adding new user jussi' (1006) with groupjussi' …
Creating home directory /home/jussi' ... Copying files from/etc/skel' …
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for jussi
Enter the new value, or press ENTER for the default
Full Name []: Jussi Laitavalo
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] y
noora@koekone:/etc/apache2/sites-available$ sudo adduser jussi sudo
Adding user jussi' to groupsudo' …
Adding user jussi to group sudo
Done.

Ilmeisesti on olemassa myös adm-ryhmä, jonka jäsenet pystyvät esimerkiksi lukemaan tiettyjä lokitiedostoja, joten lisään Jussin myös tähän ryhmään:

noora@koekone:/etc/apache2/sites-available$ sudo adduser jussi adm
Adding user jussi' to groupadm' …
Adding user jussi to group adm
Done.

Ja näin loppuun lisään vielä yhden kuvakaappauksen, jossa näkyvät kaikki tehdyt tehtävät, joskin kuvan pienestä koosta johtuen aika epäselvästi:

Siinä oli se harjoitus! Tarkastelen vielä itsekseni muita harjoituksia tämän jälkeen ja mikäli huomenna jää aikaa niin saatan tehdä vielä jonkin pienen materiaalien kokoelmapäivityksen, jota voin hyödyntää kokeessa.

Tietoa kirjoittajasta

Noora Huttunen

Opiskelen ohjelmistotuotantoa Haaga-Helian tietojenkäsittelylinjalla.