Lisää laboratorioharjoitukseen valmistautumista

Hello World Nodejs Javascriptillä

Asennan ensin Nodejs:n näiden ohjeiden mukaisesti. Annan siis seuraavat komennot:

$ sudo apt-get update 
$ sudo apt-get install nodejs
$ sudo apt-get install npm
$ nodejs -v

v8.10.0

Tämän jälkeen alan noudattaa näitä ohjeita ja luon aluksi projektille kansion omaan kotihakemistooni:

noora@koekone:~/tiedostot/koodit$ mkdir testiapp
noora@koekone:~/tiedostot/koodit$ cd testiapp

Npm init-komento avustaa minua luomaan package.json-tiedoston:

noora@koekone:~/tiedostot/koodit/testiapp$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See npm help json for definitive documentation on these fields
and exactly what they do.
Use npm install <pkg> --save afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (testiapp)
version: (1.0.0)
description:
entry point: (index.js) app.js // <-- tämä ilmeisesti kannattaa muuttaa
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /home/noora/tiedostot/koodit/testiapp/package.json:
{
"name": "testiapp",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes) y

Tämän jälkeen asennan vielä web framework Expressin:

noora@koekone:~/tiedostot/koodit/testiapp$ npm install express --save

Ja vihdoinkin pääsen tekemään itse Hello World -tiedoston:

noora@koekone:~/tiedostot/koodit/testiapp$ nano app.js
noora@koekone:~/tiedostot/koodit/testiapp$ cat app.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
noora@koekone:~/tiedostot/koodit/testiapp$ node app.js
Example app listening on port 3000!

Tämän jälkeen näen selaimessa localhostin portissa 3000 tekstin Hello World!

Hello World Pythonilla

Vastaava Hello World sujuu Pythonilla aika paljon vaivattomammin:

noora@koekone:~/tiedostot/koodit$ sudo apt-get install python3

noora@koekone:~/tiedostot/koodit$ nano heimaailma.py
noora@koekone:~/tiedostot/koodit$ python heimaailma.py
Hei maailma!

Oman metapaketin tekeminen

Hyödynnän tätä tehdessäni näitä Tero Karvisen ohjeita.

Aloitan asentamalla Equivs:in:

$ sudo apt-get update 
$ sudo apt-get -y install equivs

Tämän jälkeen luon pakettiin liittyvän tiedoston seuraavalla tavalla:

noora@koekone:~/tiedostot/paketti$ equivs-control nooran-paketti.cfg
noora@koekone:~/tiedostot/paketti$ nano nooran-paketti.cfg

Tämän jälkeen kasaan paketin komennolla:

noora@koekone:~/tiedostot/paketti$ equivs-build nooran-paketti.cfg

ja yritän suorittaa sen, mutta huomaan, että minulta puuttuu gdebi, jonka asennan:

noora@koekone:~/tiedostot/paketti$ sudo gdebi -n nooran-paketti_1.0_all.deb
[sudo] password for noora:
sudo: gdebi: command not found
noora@koekone:~/tiedostot/paketti$ sudo apt-get install gdebi

Gdebin asentumisen jälkeen ajan komennon

$ sudo gdebi -n nooran-paketti_1.0_all.deb

uudestaan, ja nyt kaikki paketissa määritellyt ohjelmat ja niiden riippuvuudet asentuvat mukavasti.

Paketin nimen vaihtaminen

En ole varma, olisiko tähän jokin kätevämpi tapa, mutta itse hoidin nimen vaihtamisen näin:

noora@koekone:~/tiedostot/paketti$ ls -a
. .. nooran-paketti_1.0_all.deb nooran-paketti.cfg
noora@koekone:~/tiedostot/paketti$ cp nooran-paketti.cfg nooran-parempi-paketti.cfg
noora@koekone:~/tiedostot/paketti$ ls -a
. .. nooran-paketti_1.0_all.deb nooran-paketti.cfg nooran-parempi-paketti.cfg
noora@koekone:~/tiedostot/paketti$ nano nooran-parempi-paketti.cfg

Muokkasin nanolla paketin nimeä, versiota ja kuvausta:

...
Package: nooran-parempi-paketti
Version: 1.1
...
Description: uudelleen nimetty pakettini
...

Tämän jälkeen rakensin paketin samalla tavalla kuin edellisen paketin:

$ equivs-build nooran-parempi-paketti.cfg
...
$ sudo gdebi -n nooran-parempi-paketti_1.1_all.deb
noora@koekone:~/tiedostot/paketti$ ls -a
. nooran-paketti_1.0_all.deb nooran-parempi-paketti_1.1_all.deb
.. nooran-paketti.cfg nooran-parempi-paketti.cfg
noora@koekone:~/tiedostot/paketti$ sudo gdebi -n nooran-parempi-paketti_1.1_all.deb
Reading package lists… Done
Building dependency tree
Reading state information… Done
Reading state information… Done
(Reading database … 198322 files and directories currently installed.)
Preparing to unpack nooran-parempi-paketti_1.1_all.deb …
Unpacking nooran-parempi-paketti (1.1) over (1.1) …
Setting up nooran-parempi-paketti (1.1) …

Kaikki paketin ohjelmat ovat kuitenkin jo asennettuina, joten paketti ei enää asenna mitään uudestaan.

WordPressin asentaminen

Aioin kokeilla myös WordPressin asentamista, mutta en jostain syystä pääse enää kirjautumaan MariaDB:hen root-käyttäjänä. Saan vain seuraavan errorin:

ERROR 1698 (28000): Access denied for user 'root'@'localhost'

, joten olen aika varma, että saatoin laittaa root-salasanaksi jotain muuta kuin mitä oletin laittaneeni. Tyyppi-käyttäjälläni ei taas ole oikeuksia luoda tietokantoja, joten en pysty luomaan WordPressin tarvitsemaa uutta tietokantaa. Normaalisti asentaisin vain MariaDB:n uudestaan, mutta en enää tässä vaiheessa taida jaksaa, varsinkin kun Maiju on kirjoittanut jo hyvät ohjeet WordPressin asentamisesta. Tarvittaessa voin siis lueskella kokeessa niitä.

Muuta sekalaista itseäni kenties hyödyttävää materiaalia

Lätkäisen tähän postaukseen vielä kasan tuntimuistiinpanojani siltä varalta, että minulle olisi niistä huomenna (tai miksei sen jälkeenkin) jotakin hyötyä.

apt-cache search vector art | grep vector
mv t * Documents/ -> siirtää kaikki t-alkuiset tiedostot documentteihin

curl -i
tail -F seuraa
curl -si osoite | header
man -k keyword -> hakee manuaalista
grep -i <- case insensitive
date --iso=min
grep -ir color-always
grep -r <- rekursiivisesti eli hakemiston alta

df -h <- systeemin kuormitus
sudo lsof -i :6600 <-- mitä portissa 6600 tapahtuu

ssh-keygen
ssh-copy-id helkera@helkera.com
ssh helkera@helkera.com

rsync -vazh --progress meso.txt helkera@helkera.com
v verbose
a säilyttää oikeudet
z pakkaus
h human readable form
jos haluaa kopioida kansion, älä laita loppuun kauttaviivaa

eka asenna sshfs
sudo apt-get install sshfs
ladataan koneeseen johon meinataan mountata hakemisto
sshfs helkera@helkera.com: /mnt/horsma
fusermount -u /mnt/noora <-- unmounttaa aseman
älä ole kansiossa kun unmounttaat
sudo umount /mnt/noora <-- toimi paremmin

sshfs -o reconnect,ServerAliveInterval=5,ServerAliveCountMax=3 helkera@helkera.com: ~/mnt/horsma
http://terokarvinen.com/2018/sshfs-securely-mount-filesystems-over-the-internet-survive-suspend-and-network-down
sudo ufw allow 443/tcp <- sallii https-liikenteen

logging analysis of security tero karvinen
nproc <-- prosessoriydinten määrä
top
uptime
dstat <-- verkkoliikenne
nethogs <-- kaistan kuormitus
netstat -pean | less
dstat <-- downloads
free -h
free vs available <-- available oikea määrä, free saattaa olla hyvin pieni
mutta tilaa vapautuu heti jos sitä tarvitaan
sudo iotop -oa
io-väylällä eri prosessit odottavat vuoroaan, kovalevyväylä
pstree <-- prosessipuu

which mitä ohjelmaa ajetaan
which python

--- bash-skriptin teko
nano tiedosto
alkuun #!/bin/bash
muut rivit
chmod ugo+x tiedosto
sudo cp tiedosto /usr/local/bin/
suoritetaan tiedoston nimellä

---- hello world python
python tiedoston nimi
ohjelman ajaminen parametrilla
python nelio.py 2

lat=d["iss_position"]["latitude"]
lat=float(lat) <--muuntaa stringistä liukuluvuksi

--- proxy ssh:lla
ssh -D portti käyttäjä@hosttaiip
nc -vz localhost porttinumero esim 9080 <--testaa, että portti on auki
curl localhost:9080


touch roska{0..10} <-- luo monta tiedostoa

rsync -r -v --exclude='Documents/Trash' Documents helkera@iptaihost:

nc -vz 172.28.172.231 80 <-- testataan, onko portti 80 auki

terokarvinen hello world programming languages ubuntu 18.04

salasana.txt
chmod og-rwx salasanat.txt

sudo adduser nmottone <- ei ääkkösiä
full nameen voi laittaa ääkkösiä

install pwgen

sudo apt-get purge poistaa paketin kokonaan

df -h <-- onko tilaa kovalevyllä

http://terokarvinen.com/2018/name-based-virtual-hosts-on-apache-multiple-websites-to-single-ip-address
http://terokarvinen.com/2018/php-database-select-and-insert-example-php-pdo
http://terokarvinen.com/2018/install-mariadb-on-ubuntu-18-04-database-management-system-the-new-mysql
http://terokarvinen.com/2018/arvioitava-laboratorioharjoitus-linux-palvelimet-ict4tn021-6-torstai-alkukevat-2018-5-op

http://terokarvinen.com/2017/arvioitava-laboratorioharjoitus-linux-palvelimet-ict4tn021-4-tiistai-alkusyksy-2017-5-op#comment-3119

http://terokarvinen.com/2016/final-lab-exercise-of-linux-basics-dat8tf063-27-spring-2016#comment-21591


sudo software-properties-gtk
sudo apt-get update


Mainokset

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.

Kuudennet tehtävät – Hei maailma -ohjelma kolmella eri kielellä

Tämän viikon tunnilla tutustuimme bash-skriptien tekoon ja koodasimme muutaman pienen ohjelman Pythonilla. Kotitehtäväksi saimme Hei maailma -ohjelman kirjoittamisen kolmella eri kielellä ja siten myös tarvittavien ohjelmointiympäristöjen asennuksen. Opettajamme mainitsi, että hyvät kielet valittavaksi olisivat esimerkiksi Java, C ja Go, joita aionkin nyt yrittää. Taidan lähteä liikkelle Javasta, sillä se on edellisistä kielistä ainoa, josta minulla on kokemusta.

Hello World Javalla

Normaalisti olen koodannut Javaa Eclipsellä, joten minun ei ole tarvinnut aikaisemmin asentaa Java-ympäristöä komentoriviltä käsin. Ongelmaksi ensin muodostuikin oikean paketin valitseminen. Vaikka olen törmännyt JRE- ja JDK-lyhenteisiin aikaisemminkin, en enää muistanut, mitä eroa niillä oli. Tästä Stackoverflow-keskustelusta päättelin, että minun tulisi asentaa juuri JDK, sillä tarkoituksenani on luoda itse Java-ohjelma. JDK-pakettejakin kuitenkin vaikutti olevan montaa eri sorttia, joten päädyin googlettamaan myös asennusohjeet. Tämän jälkeen annoin ensimmäiseksi komennon

$ sudo apt-get update
$ sudo apt-get install default-jdk

ja asennuksen päätyttyä varmisin asennuksen onnistuneen komennolla

$  java --version

, joka tulosti terminaaliin seuraavat tiedot:

openjdk 10.0.2 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4, mixed mode)

Kaikki vaikutti olevan kunnossa ja seuraavaksi oli vuorossa itse ohjelman kirjoittaminen. Kuten aikaisemmin totesin, olen tähän mennessä koodannut Javaa Eclipsellä, joka huolehtii yleensä luokkien ja main metodien luomisesta, joten rehellisesti sanottuna en muista ulkoa, kuinka ne nyt menivätkään. Muistan vielä public static void main-rimpsun mutta args-kohtaan mennessä hyydyn pahasti. Pienen lunttaamisen jälkeen sain kuitenkin ohjelman kirjoitettua:

Seuraavaksi vuorossa oli ohjelman testaaminen. En ollut varma siitä, miten tämä tapahtuu, mutta Python-ohjelmien pyörittämisestä tuttua logiikkaa soveltaen kokeilin ensimmäiseksi komentoa

$ java HelloWorld.java

Tämä kuitenkin tuotti seuraavanlaisen virheilmoituksen:

Error: Could not find or load main class HelloWorld.java
Caused by: java.lang.ClassNotFoundException: HelloWorld.java

En ollut täysin varma mistä tämä johtui, joten palasin taas Stackoverflown hellään syleilyyn. Sainkin selville, että Java-ohjelmat pitää ennen ajamista kääntää, ja tämä hoituu minun tapauksessani komennolla

$ javac HelloWorld.java

Tämän jälkeen yritin uudestaan käyttää aikaisemmin syöttämääni komentoa, mutta tämä tuotti taas saman virheilmoituksen. Ilmeisesti komentoon ei siis voi laittaa tiedostopäätettä, vaan oikea komento on yksinkertaisuudessaan

$ java HelloWorld

Tämän jälkeen konsoliin tulostuu vihdoinkin Hello World!

Hello World C:llä

En ole koodannut C:llä aikaisemmin, joten lähdin suosiolla liikkeelle asennusohjeiden etsimisellä. Yllätyksekseni annettuani komennon

$ gcc --version

sainkin tietää, että Xubuntullani onkin jo näemmä C-ohjelmien tarvitsema kääntäjä. Saatoinkin siis siirtyä suoraan koodaamiseen, tai tässä tapauksessa lähinnä copy-pasteamiseen.

En oikein tiennyt, mitä ensimmäisen rivin stdio.h tarkoittaa, joten yritin ottaa asiasta selvää. Ilmeisesti stdio.h tuo mukanaan useampia valmiita funktioita, esimerkiksi tässä koodissa esiintyvätn printf-funktion. Javasta poiketen C:n main-metodi palauttaa int-arvon 0, jonka epäilen tarkoittavan sitä, että ohjelma suoritettiin onnistuneesti. Muistelen nähneeni error-viestejä, joissa on sanottu, että ohjelma sai palautusarvokseen 1.

Myös C-ohjelmat täytyy kääntää ennen ajamista, mikä tapahtuu komennolla

$ gcc -o hello helloworld.c

, jossa -o gcc:n manuaalin mukaan tarkoittaa, että komennon output laitetaan tiettyyn tiedostoon, jonka nimi tässä tapauksessa on hello. Tämän jälkeen ohjelman voi ajaa kuvan osoittamalla tavalla:

Kiinnostavaa on, että Hello, World! -teksti tulostuu terminaali-promptin kanssa samalle riville.

Hello World Go:lla

Tunnistan useita ohjelmointikieliä nimeltä, mutta tämä taitaa olla ensimmäinen kerta kun ylipäätäänsä kuulen Go:sta. Voi toki olla, että olen unohtanutkin, tai ehkä olen sivuuttanut maininnat siitä, sillä en ole tunnistanut kielen nimeä. Ensi töikseni päätinkin siis selvittää, millainen kieli Go yleisesti ottaen on. Tämän Wikipedia-artikkelin mukaan Go vaikuttaa ainakin olevan Javaan ja C:hen verrattuna huomattavasti uudempi kieli, mutta ei kuitenkaan niin uusi, että epäilisin sen selittävän, miksi en ole kuullut siitä aikaisemmin.

Yleisen perehtymisen jälkeen siirryin etsimään tietoa asennuksesta. Suurin osa aluksi löytämistäni Go:n asennusohjeista vaikutti epäilyttävän monimutkaisilta, mutta tältä sivulta löysin ohjeet Go:n asentamiseen Ubuntun repositorioiden avulla. Aloitinkin siis antamalla asennuskomennon

$ sudo apt-get install golang

ja varmistamalla asennuksen onnistumisen komennolla

$ go version

, joka tulosti seuraavan rivin:

go version go1.10.4 linux/amd64

Asennus vaikutti siis onnistuneen. Seuraavaksi vuorossa oli Go:n polun määritteleminen. Annoin komennot tismalleen samanlaisina kuin ohjeissa:

$ echo 'export GOPATH=$HOME/go' >> ~/.bashrc  
$ echo 'export PATH=${PATH}:${GOPATH}/bin' >> ~/.bashrc
$ source ~/.bashrc

Ohjeissa neuvottiin myös testaamaan go:n toimintaa valmiilla GitHubista löytyvällä Hello World -tiedostolla seuraavien komentojen avulla:

$ go get github.com/golang/example/hello
$ hello

Sainkin tulosteeksi

Hello, Go examples!

, kuten oli tarkoituskin. Täytyy sanoa, että go get url -muotoinen komento on kyllä aika hauska.

Go:n toiminnan varmistettuani siirryinkin siis tekemään omaa paikallista HelloWorld-ohjelmaa. En tiedä Go:n syntaksista mitään, joten päädyin jälleen kerran googlettamaan esimerkin.

Go:n versio C:n stdio.h:sta vaikuttaa olevan fmt. Main-metodin paluuarvoa ei ole nähdäkseni määritelty ollenkaan, mikä ainakin poikkeaa sekä Javasta että C:stä.

Javasta ja C:stä poiketen Go-ohjelmaa ei ilmeisesti ole pakko kääntää, vaan ohjelma voidaan suoraan ajaa komennolla

$ go run helloworld.go

Jos tiedostosta kuitenkin haluttaisiin ensin rakentaa suoritettava ohjelma, joka ajettaisiin, tämä tapahtuisi seuraavilla komennoilla:

$ go build hello-world.go
$./hello-world

Siinä olivatkin tämän viikon tehtävät! Vapaaehtoisina tehtävinä olisi ollut ns. oikeiden ohjelmien tekemistä kolmella eri kielellä, mutta en taida ryhtyä siihen nyt. Ilmoittautuin hiljattain CampusOnlinen kautta useille nonstop-kursseille, joita voi suorittaa omaan tahtiin vuoden 2019 aikana. Tavoitteenani olisikin kesän aikana perehtyä useisiin itselleni joko kokonaan uusiin tai melko vieraisiin ohjelmointikieliin (C, C#, C++, Ruby, PHP, Python) ainakin alkeiden tasolla. Jätänkin syvällisemmän uusiin kieliin perehtymisen siis suosiolla hieman myöhemmäksi ja siirryn nauttimaan tällä jaksolla arvoon arvaamattomaan nousseesta vapaa-ajastani.

// Edit1: Argh, olin laittanut itselleni ylös opettajamme kirjoittaman artikkelin, joka olisi helpottanut tämän harjoituksen tekemistä valtavasti, mutta unohdin käyttää sitä!

Viidennet tehtävät – SSH ja kuormitushistorian tutkiminen sysstatin avulla

Tämän viikon ensimmäisiin tehtäviin kuului SSH-demonin asentaminen ja SSH-liikenteen salliminen palomuurin läpi. Kummankin näistä toimenpiteistä olen tehnyt jo aikaisemmin omalle palvelinkoneelleni, sillä tunnilla yhdessä tekemämme harjoitukset edellyttivät SSH:n käyttöä. Muistiinpanoistani voin kuitenkin päätellä, että SSH-serverin asensin komennolla

$ sudo apt-get install openssh-server

ja vaikka muistaakseni sallimme SSH-liikenteen jo palvelimemme asennuksen yhteydessä, tämä olisi varmaankin tapahtunut komennolla

$ sudo ufw allow 22/tcp

. UFW on siis Ubuntun mukana tuleva palomuurinhallintatyökalu, jonka avulla edeltävällä komennolla sallitaan portin 22 kautta kulkeva liikenne, eli tässä tapauksessa SSH-yhteydet.

SSH mahdollistaa jo aikaisemminkin käyttämäni scp-komennon hyödyntämisen. Scp:n avulla voi turvallisesti kopioida tiedostoja koneelta toiselle. Oman virtuaalikoneeni työpöydällä on syystä tai toisesta tiedosto nimeltä jaujau.txt, jonka tässä esimerkissä kopioin palvelinkoneelleni.

Ylempi terminaali-ikkunani kuvaa siis antamani scp-komennon ja tiedoston siirtymisen, ja alemmasta ikkunasta on nähtävissä, että jaujau.txt todella ilmestyy palvelinkoneeni kohdehakemistoon.

Kirjautumisen automatisointi

Kävimme tunnilla läpi myös, kuinka SSH-kirjautumisen saa automatisoitua julkisen avaimen menetelmää käyttäen. Teinkin kyseisen operaation koulussa omalla läppärilläni, mutta kotikoneellani olevalle virtuaalikoneelle en ole kirjautumista vielä automatisoinut. Tähän tarvitaan onneksi vain muutama komento.

Aluksi luon virtuaalikoneelleni SSH-avainparin komennolla

$ ssh-keygen

Tämä luo koneelleni kaksi avainta. Toinen avaimista on yksityinen, ja sitä on tarkoitus säilyttää omalla koneella eikä sitä saa paljastaa kenellekään. Toinen avain on puolestaan julkinen, ja nimensä mukaisesti sitä käytetään yksityisen avaimen julkisena vastaparina. Esimerkiksi tässä tapauksessa siirrän oman julkisen avaimeni palvelinkoneelleni seuraavalla komennolla:

$ ssh-copy-id helkera@helkera.com

Tämän jälkeen SSH:n ei enää pitäisi kysyä minulta salasanaa kun kirjaudun palvelinkoneelleni, sillä se pystyy tarkistamaan, onko minulla hallussani oleva yksityinen avain palvelinkoneella olevan julkisen avaimen pari.

En muista, sainko viimeksi ensimmäisen komennon jälkeen näkyviä rivejä, joissa puhutaan jo asennetuista avaimista. Joko tämä on normaalia, tai sitten teksti liittyy aikaisemmin tunnilla luomaani avainpariin, jonka julkinen avain on jo palvelimellani. SSH-kirjautuminen kuitenkin toimii nyt ilman salasanaa, kuten kuvasta näkyy.

Järjestelmän tilan tutkiminen

Sysstatin asentaminen ja käynnistäminen

Seuraavana oli vuorossa sysstat-paketin asennus, konfigurointi ja käynnistäminen. Koska tehtävässä mainittiin, että sysstatin on hyvä antaa juosta ennen historian tutkimista noin päivän tai parin verran, asensin sysstatin itseasiassa jo eilen illalla. Päätin asentaa ohjelman palvelinkonelleni, sillä toisin kuin virtuaalikoneeni, se oli päällä yön yli.

Lähdin liikkeelle sopivan paketin etsimisestä. Annoin komennon

$ apt-cache search sysstat

, joka antoi minulle kuvassa näkyvät pakettien nimet, joista valitsin haluamani ohjelman.


Tiesin, että minun tulisi seuraavaksi konfiguroida sysstattia jollakin tavalla, mutta en ollut aivan varma, miten. Koitinkin kepillä jäätä ja annoin komennon sysstat config, joka ei kuitenkaan ollut tunnistettu komento. Seuraavaksi kokeilin tehtävänannossa mainittua komentoa sar, mutta sain seuraavanlaisen virheilmoituksen:

Cannot open /var/log/sysstat/sa23: No such file or directory
Please check if data collecting is enabled

Heitin kyseisen virheilmoituksen Googleen ja päädyin sivulle, jossa selitettiin, miten sysstatia piti konfiguroida ennen käynnistämistä.

Ohjeista viisastuttuani avasinkin siis nanolla tiedoston /etc/default/sysstat ja muokkasin järjestelmäinformaation keräämiseen liittyvän false-arvon true:ksi seuraavalla tavalla:

Tämän jälkeen annoin vielä komennon

$ sudo service sysstat start

, minkä jälkeen myös sar-komento alkoi tulostaa jotain. Jätin siis sysstatin hyvillä mielin rullaamaan. Mieleeni tuli kuitenkin, että ehkä palvelinkoneen lokit eivät olisi kovinkaan mielenkiintoista katseltavaa, sillä palvelimeni ei oikeastaan tee juuri mitään. Asensinkin sysstatin myös virtuaalikoneelleni varmuuden vuoksi. Ja hyvä niin, koska suurin osa seuraavista analyyseistä tulee liittymään juuri virtuaalikoneeseeni.

Sar (System Activity Reporter) -komennon tulosteiden tulkitseminen

Annettuani sar-komennon huomasin aluksi, että molempien koneiden tulosteet liittyvät tähän päivään. Virtuaalikoneeni tulosteessa näkyy, koska olen käynnistänyt koneen, mutta palvelinkoneestani ei vastaavaa tietoa näy, sillä se on ollut päällä yhtäjaksoisesti jo pidempään. Sysstatin datan tulostusintervalli vaikuttaa olevan kymmenen minuuttia.

Virtuaalikoneellani ei rivejä ole kuin muutama:

kun taas palvelinkoneellani pelkästään tämän vuorokauden alkuosaan liittyviä rivejä on jo vaikka millä mitalla:

Joistain sarakkeiden otsikoista pystyy melko hyvin päättelemään, mitä ne tarkoittavat. Esimerkiksi CPU varmaankin liittyy prosessoreihin, user käyttäjään ja niin edespäin. Tämä ei kuitenkaan varsinaisesti auta itse arvojen tulkitsemisessa. Sysstatista vaikuttaa löytyvän dokumentaatiota vaikka millä mitalla, mutta suurin osa siitä vaikuttaa itselleni melko raskaslukuiselta, joten päädyin ainakin näin aluksi tutkailemaan hieman yksinkertaisempia ohjeita sar-komennon käyttöön.

CPU-sarakkeessa näkyvä sana all kielii siis siitä, että esitetyt tiedot liittyvät kaikkien prosessorien toimintaan. Toimintaa saisi eriteltyä tarkemmin komennolla sar -P ALL, mutta koska kummassakin koneessani on vain yksi prosessori, tämä ei hyödytä minua juurikaan. User-kohdasta löytämissäni ohjeissa ei puhuta mitään, joten jatkoin sopivampien ohjeiden etsimistä.

Löysinkin toisen sivun, jossa sarakkeiden nimet on selitetty edes jollain tavalla. User-sarake siis kuvaa prosentuaalisesti prosessorin käyttämää aikaa erilaisiin (käyttäjän) prosesseihin liittyen. Palvelinkoneellani arvo ei ole missään vaiheessa noussut edes yhteen, ja virtuaalikoneellanikin arvo on maksimissaan ollut 2,48.

Halusinkin testin vuoksi suorittaa jotakin resursseja enemmän kuluttavaa prosessia virtuaalikoneellani, ja katsoa, mitä sar tulostaa tämän jälkeen. Avasin kokeeksi Youtuben ja aloin katsomaan musiikkivideota. Video ei alussa pyörinyt kovin sulavasti, mutta jonkin aikaa latailtuaan toiston laatu normalisoitui. Selailin samalla myös Reddittiä.

Tämän jälkeen saadut arvot näyttivätkin jo hieman erilaisilta. Ainakin user- ja system-sarakkeiden arvot ovat lähteneet kasvuun ja idle-aika oli siten vähentynyt.

Nice ilmeisesti viittaa arvoon, jonka mukaan suoritettavia prosesseja priorisoidaan ja nice-sarake kuvaakin niihin prosesseihin käytettyä aikaa, joiden nice-arvoa on muutettu.

System-sarakkeessa puolestaan kuvataan prosessorin käyttämää aikaa käyttöjärjestelmän omiin prosesseihin.

Iowait kuvaa aikaa, jonka prosessori käyttää odottaen järjestelmän laitteita. Kirjaimet i ja o tulevat sanoista input ja output.

Steal-sarakkeesta käy ilmi aika, jonka virtuaalinen prosessori käyttää odottaessaan resursseja fyysiseltä prosessorilta. Yllä olevassa virtuaalikoneeseeni liittyvässä tulosteessa arvo on aina 0, mutta palvelinkoneellani arvo nousee toisinaan nollan yläpuolelle. Ilmeisesti oma prosessorini palvelee virtuaalikoneeni tarpeita ilman odotusta, kun taas palvelinkoneeni pitää välillä odotella resursseja pienen hetken ajan?

Idle-sarakkeessa on kuvattu sen ajan osuus, jolloin prosessori ei tee mitään.

Yhteensä sarakkeiden arvojen summa on siis 100% ja kuormituksen kasvaessa idle-aika vähenee ja toisinpäin.

Iostat-komento

Seuraavana lähdin tutkimaan, millaista informaatiota saisin iostat-komennolla.

Tällä kertaa löysin myös ihan kunnollisen manuaalisivun, jossa on eritelty komennon tulostetta tarkemmin. Ensimmäiseksi iostat tulostaa siis prosessorien keskimääräiseen ajankäyttöön liittyvää tietoa samaan tapaan kuin sar-komento.

Seuraava osa puolestaan kuvaa laitteiden käyttöön liittyvää tietoa. En osaa hyvin kuvailla, mikä loop0 oikein on, mutta veikkaisin sen liittyvän tähän Wikipedia-artikkeliin. Sda taas on luultavasti virtuaalikoneeni kovalevy.

Tps kuvaa sitä, kuinka monta siirtoa kyseinen laite suorittaa sekunnissa. Seuraavat arvot kertovat, millä vauhdilla tietoa on kilobiteissä mitattuna luettu ja kirjoitettu ja kaksi viimeistä saraketta kuvaavat luetun ja kirjoitetun tiedon kokonaismäärää kilobitteinä.

Pidstat-komento

Kuten sopii odottaakin, pidstat-komennon tulostama litania on huomattavan pitkä, sillä siinä näkyvät kaikki koneen senhetkiset prosessit. Vaikka seuraava kuva onkin melko laaja, siinä ei silti näy läheskään kaikkia listattuja prosesseja.

Kahdessa ensimmäisessä sarakkeessa on prosessin tunnistamiseen liittyvää tietoa:

UID – sen käyttäjän identifioiva tunnus, johon kyseinen prosessi liittyy. Rehellisesti sanottuna en oikein ymmärrä, miksi pidstat tulostaa niin monta erilaista käyttäjä-id:tä. Tiedän, että 0 on root-käyttäjän UID ja ns. normaalien käyttäjien UID:t alkavat yleensä 1000:sta. Mutta pidstat listaa näiden lisäksi myös UID:t 101, 102, 103, 109, 113, 114 ja 117. Googlettamalla selvitin, että kaikki koneen käyttäjät voi listata komennolla

$ cat /etc/passwd 

niitä löytyykin vaikka millä mitalla. En ole edes tiennyt, että ilmeisesti esimerkiksi joitakin demoneita käsitellään käyttäjinä. Esimerkiksi avahi daemon käyttää koneellani UID:tä 117. Muutkin mainitsemani arvot vaikuttavat liittyvän erilaisiin käyttöjärjestelmän osiin ja palveluihin.

PID – prosessin identifioiva numero. Olen itse käyttänyt näitä esimerkiksi sellaisissa tilanteissa, joissa haluan tarkistaa, onko jokin tietty prosessi käynnissä, tai halutessani tappaa tietyn prosessin.

%usr-sarake kertoo, kuinka suuren prosentuaalisen osuuden käyttäjätasolla suoritettu prosessi vie prosessorin tehosta. System-kohta pitää sisällään vastaavaa tietoa, mutta käyttäjätason sijaan se kuvaa systeemitason kuormitusta.

Guest kuvaa virtuaalikoneessa suoritetun prosessin osuutta virtuaaliprosessorin toiminnasta. Wait-sarake puolestaan nimensä mukaisesti kuvaa aikaa, jonka prosessori on käyttänyt odottaessaan tehtävään liittyvää suorittamista.

%CPU kuvaa prosentuaalisesti sitä aikaa, jonka tietty prosessi vie prosessorin toiminnasta. Pelkkä CPU puolestaan kertoo, mikä prosessori tehtävää suorittaa. Koska virtuaalikoneessani on vain yksi prosessori, kaikki sarakkeen luvut ovat samat. Viimeisessä sarakkeessa on prosessiin liittyvän komennon nimi.

Kun ottaa huomioon, että katselin nimenomaan musiikkivideoita netin kautta, ei ole yllättävää, että suurimpia numeroita ovat prosesseista saaneet Web Content, firefox, ja Xorg. Muuten en edes tietäisi, mikä Xorg on, mutta asensin sen juuri vähän aikaa sitten omalle Arch Linuxilleni, joten minulla on tuoreessa muistissa, että sitä käytetään graafisten käyttöliittymien ja sen myötä muiden graafisten ohjelmien käytön mahdollistavana serverinä.

Siinä olivatkin tämän viikon varsinaiset tehtävät. Muutamia vapaaehtoisia tehtäviä olisi tälle viikolle myös, mutta taidan skipata ne tällä kertaa. Olen käyttänyt lomalla sen verran paljon aikaa Arch Linuxin kanssa hikoilemiseen, että aion laskea sen tässä yhteydessä henkilökohtaiseksi lisätehtäväkseni :D Kirjoitan omista Arch Linux -kokemuksistani ehkä joskus tulevaisuudessa, kunhan saan Archissa erinäiset asiat toimimaan. Tai oikeammin, JOS saan ne toimimaan :D Tähän mennessä edistyminen on ollut jokseenkin hidasta ja tuskallista, mutta hyvin opettavaista, minkä takia Archia rakentelemaan lähdinkin.

Neljännet tehtävät – julkisen virtuaalipalvelimen ja domain-nimen vuokraaminen ja käyttö

Aikaisemmista viikoista poiketen suurimman osan tämän viikon tehtävistä teimme jo edellisen oppitunnin aikana. Tästä syystä teen tällä kertaa raportointini suurimmaksi osaksi muistinvaraisesti. Ehdin jo ennen tehtävien lukemista hankkia omalle domainilleni SSL-sertifikaatinkin, ja huomasin vasta myöhemmin sen kuuluvan vapaaehtoisiin tehtäviin. Tämän viikon tehtävät eivät myöskään etene mielestäni missään erityisessä järjestyksessä, joten normaalien tehtävänumeroiden (tai kirjainten) sijasta käytän kuvaavampia väliotsikoita.

Virtuaalipalvelimen vuokraaminen ja käyttöönotto

Virtuaalipalvelimen vuokraaminen on kätevää ja kannattavaa, mikäli haluaa saada omaa sisältöään, kuten kotisivut, nettiin. Korvaava vaihtoehto voisi olla esimerkiksi oman palvelinkoneen kasaaminen ja sen kotona pyörittäminen. Tämä kuitenkin vaatii jonkinlaista rautapuolen osaamista sekä isompaa alkuinvestointia. Tämän lisäksi palvelimen on koko ajan oltava nettiyhteyden päässä ja sähköpistokkeessa kiinni. Tällaisessa tapauksessa esimerkiksi satunnainen sähkökatkos tai koneen rikkoutuminen johtaisivat siihen, etteivät vierailijat pääsisi kotisivulle normaaliin tapaan. Virtuaalipalvelimia vuokraavilla tahoilla puolestaan on omistuksessaan valtavia palvelinsaleja, joiden turvallisuudesta huolehditaan, ja esimerkiksi raudan rikkoutuessa palvelimen käyttäjän ei tarvitse itse ratkaista tilannetta.

Oman palvelimeni vuokrasin DigitalOceanilta, joka kutsuu omia virtuaalipalvelimiaan dropleteiksi. Palvelimen vuokraaminen edellyttää tunnusten luomista ja joko korttitietojen antamista tai Paypal-tunnusten käyttöä. Itse olen opiskelija, joten aktivoin aluksi oman Github Education Pack:ini, jonka mukana tulee mm. viidenkymmenen dollarin kuponki DigitalOceanin sivuille. Tämän kertaluontoisen kupongin saa aktivoitua syöttämällä annetun koodin DigitalOceanin sivuilla olevan Account-välilehden Billing-kohtaan. Kortiltani ei siis velotettu vuokraamisen yhteydessä mitään, vaan maksu otettiin saamastani saldosta.

Education Packia hakiessani täytin lomakkeen, jossa kysyttiin mm. valmistumisvuottani, ja sitä, missä opiskelen. Täytin lomakkeen mielestäni kokonaan, mutta olinkin vahingossa jättänyt yhden kentän tyhjäksi. Yrittäessäni lomakkeen lähetystä sain virheilmoituksen tyhjästä kentästä, ja kyseisen kentän täytettyäni lähetin lomakkeen uudestaan. Samalla sekunnilla kuin painoin lähetyspainiketta huomasin, että esimerkiksi valmistumisvuoteni oli vaihtunut valitsemastani vuodesta 2020 takaisin vuoteen 2019. En tiedä, saako aikaa jatkettua enää myöhemmin, joten halusin mainita tämän törttöilyni varoituksena muille. Olen ilmeisesti liian tottunut siihen, että yleensä virheilmoituksen saamisen yhteydessä virheettömästi täytetyt kentät eivät palaudu oletusarvoihinsa.

Tietojen syöttämisen jälkeen oli aika siirtyä itse palvelimen luomiseen valitsemalla DigitalOcean-sivun yläpalkista create -> new droplet. Suurin osa oletusasetuksista oli ihan käypää kamaa, mutta muutamia asioita muutimme. Käyttöjärjestelmäksi valitsimme jo itsellemme tutun Ubuntu 18.04.01:n ja automaattisesti ehdotetun koon vaihdoimme pienimpään mahdolliseen, sillä pienempi tila riittää peruskäyttöön aivan hyvin ja tarpeen tullessa sitä on helppo hankkia lisää. Datacenterin sijainniksi oli mielekästä valita Frankfurt, sillä ainoa toinen Euroopassa sijaitseva vaihtoehto on Lontoo, ja Brexit-sekoilut kannattaa ottaa tässä tilanteessa huomioon varmuuden vuoksi. Hostname-kohtaan kannattaa valita esimerkiksi jokin yksinkertainen sana. Tämä hostname tulee näkymään esimerkiksi terminaalissa silloin kun olet ottanut SSH-yhteyden kyseiseen palvelimeen. Omaksi host-nimekseni valitsin horsman, sillä se oli edesmenneen kotikoneeni nimi, ja nyt minulle tuli mahdollisuus pitää horsman muisto elossa :D Itselläni näkyisi terminaalissa siis helkera@horsma.

Sen jälkeen kun asetukset on saatu kuntoon, klikataan create-painiketta. Rekisteröityessä käytettyyn sähköpostiin ilmestyy tämän jälkeen viesti, jossa on luodun palvelimen tiedot, esimerkiksi yhteyden muodostamiseen tarvittava root-salasana. Palvelimen käyttöönottoon liittyvät hyvät ohjeet löytyvät opettajamme kotisivuilta, joten en itse kerro kyseisestä prosessista tässä kirjoituksessa. Ohjeissa ei käydä läpi Apachen asentamista, mutta sen taas tein edellisessä päivityksessäni, jossa kerron myös, miten käyttäjille myönnetään Apache-moduulin käyttöoikeus kotihakemistoon. Virtuaalipalvelimelle tein nämä asiat aivan samalla tavalla, joten en kuvaa prosessia enää tässä uudestaan.

Domain-nimen vuokraaminen

Kuten ylempänä linkittämässäni ohjeessa sanotaan, hyviä paikkoja domain-nimen vuokraamiseen ja erilaisten nimien saatavuuden tutkimiseen ovat esimerkiksi Namecheap ja Gandi. Ilmeisesti näistä kahdesta Namecheap on hieman halvempi, ja sieltä vähemmän kysyttyjä vapaina olevia osoitteita vaikuttaa saavan hieman alle kympillä vuodessa. Opettajamme kehotti meitä tarkistamaan, olisiko oma sukunimemme vapaana .com-päätteisissä osoitteissa, sillä tämäntyyppisen domainin omistaja voisi luoda esimerkiksi etunimi@sukunimi.com -tyyppisiä sähköpostiosoitteita vaikka koko suvulle. Juuri .com -päätteiset sivut ovat niitä, joita kannattaa vuokrata, sillä .com on puheessa hyvin vakiintunut pääte, jonka ihmiset tunnistavat ja johon luotetaan.

Moni kurssilaiseni saikin varattua itselleen tämäntyyppisen osoitteen, mutta itseäni ei lykästänyt. Rehellisesti sanottuna olisin ollut äärimmäisen yllättynyt, jos huttunen.com -osoite olisi ollut vielä vapaana, sillä Huttunen on hyvin yleinen sukunimi. Itse en kuitenkaan kokenut tästä mitään erityistä pettymystä, sillä olen aina esiintynyt netissä vakiintuneella nimimerkilläni oikean nimeni sijasta, enkä nää erityistä syytä muuttaa tapojani tässä asiassa. Ehkä yritän alitajuisesti pitää nimimerkkikulttuuria elossa, haha.

Vuokraamisen jälkeen oli vuorossa domain-nimen yhdistäminen virtuaalipalvelimeen, jonka teimme sen tämän ohjeen mukaisesti. Oli hieman omituista, että kummatkin valmiista recordeista olivat turhia ja ne poistettiin ennen omien A recordien lisäämistä. Lopputulos oli, että meillä oli ensimmäisen A recordin hostina @ eli root domain ja toisen A recordin hostina www. Tämä mahdollistaa sen, että vierailija ohjautuu oikealle sivulle riippumatta siitä kirjoittaako hän osoitteen alkuun www vai ei.

Seuraavaksi loin uuden tiedoston kansioon /etc/apache2/sites-available komennolla

$ sudo nano helkera.conf

ja muokkasin sen sisällön seuraavanlaiseksi:

Tallennettuani tiedoston painamalla Ctrl + X ja valitsemalla Y ja Enter annoin myös komennon

  $ sudo a2ensite helkera.conf

, joka lisäsi saman tiedoston myös enabled sites -kansioon aktivoiden samalla sivun käyttöä varten. Seuraavaksi piti tietenkin luoda kuvan mukaiseen hakemistoon index.html -sivu ja käynnistää Apache2 uudestaan komennolla

 $ sudo systemctl restart apache2

Kotisivujen käyttö

Edeltävien toimenpiteiden jälkeen helkera.com-sivullani näkyy kotihakemistossani sijaitseva index.html-tiedosto, joka tässä tapauksessa sattuu edelleen olemaan rakas maskottini, ASCII-kala:

Oikeastaan tein aluksi uuden index.html-tiedoston palvelinkoneellani ja kopioin siihen vanhan koodin, mutta jostain syystä <pre> -tageista huolimatta kala levisi yhdeksi pitkäksi merkkijonoksi. Lopulta siirsin alkuperäisen sivun sellaisenaan palvelimelle scp-komennolla, minkä jälkeen kala näytti taas normaalilta itseltään. Tämän viikon tehtäviin kuuluu nimenomaan scp:llä tiedostojen palvelimelle siirtäminen, mutta myös php-sivun kokeilu, joten lyön nyt kaksi kärpästä yhdellä iskulla ja siirrän jonkin php-koodia sisältävän sivun palvelimelle scp:llä. Ensin minun kuitenkin pitänee asentaa palvelinkoneelle php ja mahdollistaa käyttäjille php:n ajaminen omista kotihakemistoistaan käsin. Kävin myös tämän prosessin läpi viime viikon tehtävien c -kohdassa, joten en käy sitä läpi enää tässä.

Tehtyäni omalla virtuaalikoneellani pienen php-sivun, jonka ideana on tulostaa kävijän IP-osoite, siirsin sen palvelinkoneelleni komennolla

$ scp ipaddr.php helkera@helkera.com:/home/helkera/public_html

Ja nyt helkera.com:ista löytyykin uusi sivu:

Kuvassa Geditissä auki oleva koodi on minun virtuaalikoneellani, sillä palvelinkoneella ei ole graafista käyttöliittymää, jota vaaditaan Geditin käyttöön. Epähuomiossa viime tunnilla yritin vanhasta tottumuksesta käyttää Gedittiä palvelinkoneella ja kun tajusin, ettei sitä ollut, ajattelin että äkkiäkös minä sen asennan. Tajusin virheeni vasta kun olin jo antanut apt-get install -komennon ja näin kun Ubuntu alkoi lataamaan noin tuhatta ja yhtä pakettia. Onneksi sain asennuksen keskeytettyä, mutta hetken aikaa olin hieman huolissani ja häpeissäni. Palvelinkoneellani on tosiaan sen verran vähän muistia, että graafisten ohjelmien pyörittämisessä ei ole mitään mieltä. Mutta kuten äsken demonstroin, on hyvin kätevää tehdä koodi Geditillä omalla koneella ja lähettää vasta valmis tiedosto palvelimelle scp:llä.

Murtautumisyrityksiä

Palvelimen pystyttämisestä lähtien olen tarkkaillut satunnaisesti /var/log -hakemistossa sijaitsevaa auth.log-tiedostoa. Komennolla

$ tail -f auth.log

saa helposti seurattua reaaliajassa lokiin tulevia uusia rivejä. Ja niitä muuten tulee tajuttomalla tahdilla. Opettajamme ei todellakaan liiotellut kun hän totesi, että heti kun palvelin on yhteydessä nettiin, siihen yritetään murtautua. Tahdista päätellen nämä yritykset tulevat todennäköisesti erilaisilta bottiverkoilta. Useimmiten botit yrittävät kirjautua root-käyttäjänä, mikä on juuri se syy, miksi root-käyttäjän salasana deaktivoitiin palvelimen pystytyksen yhteydessä. Mikäli ulkopuolinen taho onnistuisi kirjautumaan palvelimelleni root-käyttäjänä, seuraukset olisivat varmasti äärimmäisen ikävät.

Olen kuitenkin nähnyt bottien yrittävän myös muille tunnuksille kirjautumista. Admin-tunnuksia olen nähnyt muutaman kerran, mikä ei ole yllätys, mutta myös ihmisten nimiä vilahtelee auth.login epäonnistuneissa kirjautumisyrityksissä toisinaan. Selkeästi murtautumisyritykset ovat myös erilaisia päivästä riippuen. Ensimmäisenä iltana palvelimen pystyttämisen jälkeen kaikki kirjautumisyritykset, joiden lähteen tarkistin whois-komennolla, tulivat Venäjältä. Mielestäni erikoista oli se, että kaikissa saamissani whois-tulosteissa mainittiin yksittäisten ihmisten nimiä ja katuosoitteita. Päättelinkin, että nämä käyttäjät saattavat olla normaaleja ihmisiä, joiden koneille hakkerit ovat jollain tapaa päässeet ja heidän koneensa on liitetty osaksi jonkinlaista hyökkäyksiä tehtailevaa bottiverkkoa.

Siinä missä ensimmäisen illan venäläinen bottiverkko vaikutti yrittävän myös satunnaisille tunnuksille kirjautumista, tällä hetkellä auth.logiin tulee pelkkiä root-käyttäjään kohdistuvia kirjautumisyrityksiä ja vain muutamasta eri IP-osoitteesta. Toinen osoitteista kuuluu DigitalOceanille, josta itsekin palvelimeni vuokrasin, ja toinen Chinanetille:

Jos annan whois-komennossa oman palvelimeni IP-osoitteen, niin tuloste on samanlainen kuin ensimmäisessä kuvassa. Tämän illan murtautumisyrityksistä vastuussa olevat tahot ovatkin varmaan hyödyntäneet samaa palveluntarjoajan whois protectionia kuin minäkin. Olisi kyllä kiinnostavaa tietää, tulevatko yritykset useammalta eri koneelta vai vain yhdeltä.

Tähänastisen kokemukseni perusteella vaikuttaa myös, että tietyt vuorokaudenajat ovat suositumpia kuin muut mitä murtautumisen yrittämiseen tulee. Kerran tarkastelin auth.logia päivällä koulussa istuessani ja silloin uusia yrityksiä tuli melko harvakseltaan. Keskimääräisesti arvioisin, että noin muutaman minuutin välein, mutta välillä yritysen väliin saattoi jäädä viisikin minuuttia. Tämä on melko radikaali ero, kun vertaa tahtia tähän hetkeen. Kello on nyt 4.04 lauantain ja sunnuntain välisenä yönä, ja uusia yrityksiä auth.logiin tipahtelee n. 1-20 sekuntin välein, ja monesti yrityksiä tulee lähes kerralla useita peräkkäin.

TLS-sertifikaatin hankkiminen

Kun ensimmäisiä kertoja tarkastelin omia sivujani selaimella, kiinnitin huomiota siihen, ettei sivu ollut Chromen mielestä turvallinen. Pidin tätä hieman tylsänä, joten lähdin selvittämään, kuinka asian saisi muutettua. Päädyin opettajamme suosittelemalle Let’s Encrypt -sivustolle, jonka kautta löysin hyvältä vaikuttavat ohjeet sertifikaatin hankkimiseen. Ilmeisesti prosessi on nykyään automatisoitu, ja sisältää lähinnä certbot-ohjelman sekä oikeanlaisen pluginin lataamisen. Seurasin näitä ohjeita, ja koska olin vuokrannut palvelimeni DigitalOceanilta, oikeaan pluginiin liittyvät ohjeet löytyivät täältä.

Kohtasin kuitenkin asennuksen aikana ongelman. Sain jatkuvasti virheilmoituksen siitä, ettei domain-nimeäni voitu varmistaa. Yritin googlettaa, mitä olin tehnyt väärin, mutta en aluksi löytänyt mitään kovin järkevää. Lopulta päädyin laittamaan oman sivustoni nimen SSL Checker -sivulle, jonka tarkastuksen epäonnistuessa sain virheilmoituksen, jossa viitattiin siihen, etten olisi ehkä sallinut HTTPS-liikennettä palvelimelleni. Ja siitähän ongelma johtuikin. Päädyin käyttämään DigitalOceanin ohjeita, joissa mainittiin myös tarvittava komento HTTPS-liikenteen sallimiselle. Tämän jälkeen certbot sai tehtävänsä hoidettua mallikkaasti ja sain vihdoin sivulleni sertifikaatin.

Linkki sivulle
Linkki sivulle

Asennuksen aikana minulta kysyttiin, haluaisinko ohjata kaiken saapuvan liikenteen turvalliseen osoitteeseen, ja jostain syystä sillä hetkellä vastasin kieltävästi. Myöhemmin tultuani katumapäälle yritin etsiä tapaa muuttaa asetus, ja löysinkin muutamia potentiaaliselta vaikuttavia keinoja, mutta halusin kokeilla asetusten muuttamisen ulkoistamista certbotille. Annoinkin komennon

$ sudo certbot --redirect

ja botti heräsi taas henkiin. Aluksi se pyysi minua valitsemaan, mille osoitteille haluaisin ottaa uudelleenohjauksen käyttöön, ja valitsin sekä juuriosoitteen että www-osoitteen. Tämän jälkeen certbot ilmoitti, että minulla vaikuttaa olevan jo voimassaoleva sertifikaatti, joten valitsin annetuista vaihtoehdoista, että muutos tehtäisiin aikaisempaan sertifikaattiini. Kaikki onnistui hyvin ja certbot teki itsenäisesti tarvittavat muutokset VirtualHost-tiedostooni:

Tämän jälkeen kun yritän selaimella mennä osoitteeseen helkera.com, minut ohjataan sivulle https://helkera.com, ja selain ilmoittaa sivun olevan turvallinen. Kyllä nyt sielu lepää!

Tämän viikon vapaaehtoisiin tehtäviin olisi kuulunut myös lukuisia WordPressiin liittyviä tehtäviä. Halutessani voisinkin siis nyt siirtää tämän WordPress-blogini omalle palvelimelleni. En aio kuitenkaan yrittää sitä operaatiota enää tänään, sillä minulla on vielä tämän illan kuntopyöräilyt tekemättä. Eli siirrynkin nyt ihan perinteisempään hikoiluun tällaisen metaforisen tehtävien parissa hikoilun jälkeen. Hyvää yötä vaan kaikille!

Kolmannet tehtävät – Apache, kotisivut ja lisää lokien analysointia

Aikaisemmilla viikoilla tehtäviä on ollut viisi kappaletta, mutta tällä viikolla niitä on peräti kaksitoista. Ideana kuitenkin on, ettei niistä tarvitse tehdä jokaista:

” Tee viisi vapaavalintaista kohtaa. Säädä vaikeustaso oikeaksi: jos olet ihan alussa ja tämä on haastavaa, tee helpoimmat a b c d i. Jos osaat jo perusteet, tee useampia tai vaikeampia kohtia. Tarkoitus on, että tehtävät tehtyäsi osaat enemmän kuin osasit ennen. ”

Tero Karvinen

Itse opin ensimmäiset tämän viikon aiheeseen liittyvät asiat vasta viime tunnilla, joten taidan suosiolla pitäytyä helpommissa tehtävissä. Sen lisäksi eilisen ncmpcpp-sekoilun jäljiltä yksinkertaisuuden kaipuuni on vahva.

Tehtävä a

Ensimmäisenä on vuorossa palvelinohjelma Apachen asennus ja sen toimivuuden testaaminen kotisivujen avulla. Teimme vastaavan harjoituksen viime tunnilla, mihin liittyen tein tällä kertaa myös muistiinpanoja. Yritänkin nyt seurata ihan omia ohjeitani (tai oikeammin siis Tero Karvisen ohjeita) sen sijaan että normaaliin tapaan alkaisin etsiä ohjeita Googlesta.

Ennen varsinaista Apachen asentamista on hyvä säätää ensin palomuurin asetukset kuntoon. Ubuntun oletustyökalu palomuuriasetusten säätämiseen on UFW eli Uncomplicated Firewall. Oletuksella palomuuri ei ole päällä, joten tämä asetus täytyy vaihtaa. Sitä ennen kuitenkin avataan TCP-portti numero 22, joka mahdollistaa mm. SSH-yhteyksien muodostamisen ja turvallisen tiedostojen siirtämisen scp-komennon avulla (Lähde).

$ sudo ufw allow 22/tcp

Tämän jälkeen palomuuri otetaan varsinaisesti käyttöön komennolla

$ sudo ufw enable

ja seuraavaksi avataan HTTP-liikenteen mahdollistava TCP-portti 80.

$ sudo ufw allow 80/tcp

Nyt kun asetukset on säädetty, katsotaan miltä palomuurin status näyttää.

Ainakin minun silmääni kaikki vaikuttaa olevan kuten pitääkin.

Seuraavaksi asennetaankin itse Apache komennolla

$ sudo apt-get install apache2

, jota ennen ajan myös komennon

$ sudo apt-get update

varmistuakseni siitä, että ladattavat paketit ovat mahdollisimman uusia.

Asennuksen valmistuttua avasin selaimen ja kirjoitin osoitekenttään localhost, jossa näkyi Apachen oletussivu, mistä päättelin asennuksen onnistuneen.

Tämän jälkeen kannattaa mahdollisimman pikaisesti ylikirjoittaa normaali index.html-sivu, sillä hakkerit erikseen etsivät kyseisen sivun perusteella palvelimia, jotka saattavat keskeneräisyydestään johtuen olla otollisempia murtautumiskohteita kuin sellaiset palvelimet, joita ollaan konfiguroitu enemmän. Hyvä komento sivun ylikirjoittamiseen on esimerkiksi

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

, josta nähdään myös, missä hakemistossa index.html-sivu sijaitsee. Tee-komento kirjoittaa echossa annetun tekstin annettuun tiedostoon. Tämän jälkeen selaimen näkymä muuttuu seuraavanlaiseksi:

Seuraavaksi lähdetään tekemään käyttäjille omia kotisivuja. Aluksi käyttäjille pitää myöntää oikeudet tehdä omiin kotihakemistoihinsa public_html-kansiot. Tämä tapahtuu komennolla

$ sudo a2enmod userdir

, joka sallii Apache2-moduulin käytön käyttäjien omissa hakemistoissa (Lähde). Tässä vaiheessa terminaaliin tulostuu

To activate the new configuration, you need to run:
systemctl restart apache2

, joten potkaiskaamme ehdotetulla komennolla Apache uudestaan käyntiin, jotta muutokset tulisivat voimaan.

Seuraavaksi navigoin omaan kotihakemistooni ja loin sinne public_html-kansion ja sen sisään index.html-sivun seuraavilla komennoilla:

$ mkdir public_html
$ cd public_html
$ nano index.html

Index-sivulle voi kirjoittaa, mitä nyt haluaakaan, oma http://localhost/~helkera -osoitteesta löytyvä sivuni näyttää pienen säätämisen jälkeen tältä:

Aluksi hieno ASCII-kala tulostui ilman tyhjiä merkkejä, minkä takia se näytti vaan epämääräiseltä littanalta merkkijonolta. Stackoverflow:sta sain selville, että ASCII-kuvat saa säilymään oikeassa muodossa käyttämällä <pre> -tageja kuvan ympärillä. Kyseinen kala on itseasiassa komentoriviohjelma Fish:n logo, josta joku ystävällinen sielu kyseli tekstinä kopioitavaa versiota GitHubissa.

Tehtävä b

Nyt kun kotisivut on saatu toimimaan, niitä olisi tarkoitus käyttää ja samalla tarkastella, mitä Apachen lokiin ilmestyy.

Apachen lokit ovat hakemistossa /var/log/apache2, ja sieltä löytyvät tiedostot access.log, error.log ja other_vhosts_access.log. Avasin ensin access.login ja aloin tarkastella sen viimeisimpiä rivejä, jotka olivat seuraavanlaiset:

127.0.0.1 - - [03/Feb/2019:17:36:22 +0200] "GET / HTTP/1.1" 304 179 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"
127.0.0.1 - - [03/Feb/2019:17:38:49 +0200] "GET / HTTP/1.1" 200 285 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"
127.0.0.1 - - [03/Feb/2019:17:38:49 +0200] "GET /favicon.ico HTTP/1.1" 404 500 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"
127.0.0.1 - - [03/Feb/2019:17:40:16 +0200] "GET /~jokumuu HTTP/1.1" 404 498 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"
127.0.0.1 - - [03/Feb/2019:17:41:17 +0200] "GET /~helkera/ HTTP/1.1" 200 669 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"

Ensimmäisenä kussakin lokimerkinnässä näkyy ip-osoite, josta GET-pyyntö on tullut, eli tässä tapauksessa localhost. Seuraavana toisen viivan paikalla voisi olla clientin identiteettiä kuvaava nimi, jota tässä tapauksessa ei ole kuitenkaan saatavilla. Hakasulkeiden sisällä on aika, jolloin palvelinta on kutsuttu. Seuraavaksi lokissa määritellään, että kyse oli juuri GET-pyynnöstä, joka kohdistui yleiseen index.html:ään käyttäen HTTP 1.1 -protokollaa.

Seuraavaksi tuleva koodi kuvaa serverin statusta pyyntöön liittyen. 304 tarkoittaa, että sivuun ei ole tehty muutoksia sen jälkeen kun se on tallennettu client-koneen välimuistiin, joten sivu haetaan välimuistista. 200 puolestaan tulostuu, jos selain ei hae sivua välimuistista, vaan lataa sen onnistuneesti palvelimelta. 404 taas ilmaisee, että haettua kohdetta ei löytynyt. Esimerkiksi sivun faviconin hakeminen tuotti 404-koodin, koska en ole asettanut sivulle faviconia. Myös yrittäessäni mennä osoitteeseen, jota ei ole olemassa, saatu koodi on 404. (Lähde)

Seuraava luku kuvaa pyydetyn objektin kokoa. Tämän jälkeen tuleva lainausmerkkien sisällä oleva viiva tarkoittaa, että käyttäjä tuli sivuille suoraan ilman että häntä olisi ohjattu jostain muualta, eli hän saattoi esimerkiksi kirjoittaa sivuston osoitteen suoraan osoitekenttään, kuten itsekin tein (Lähde). Tämän jälkeen tulee ns. User-agent -elementti, joka kertoo, mitä tietoja pyynnön tehnyt selain on lähettänyt itsestään, eli tässä tapauksessa tiedon siitä, että käytetty selain oli Mozilla Firefox ja käyttöjärjestelmä Ubuntu (Lähde).

Tehtävä c

C-tehtävän tarkoituksena on aiheuttaa virhe palvelimella ajettavaan koodiin ja etsiä lokeista kyseiseen tapahtumaan liittyvät rivit. Edellisessä tehtävässä en vielä tehnyt omalle nettisivulleni minkäänlaista koodia, joten se on edessä nyt. Tunnilla katselimme yhdessä php-koodia, joten pitäydyn tällä kertaa siinä, vaikka Python kiinnostaakin minua.

Hain oikeaa php-pakettia asennettavaksi komennolla:

$ apt-cache search php|grep php|grep -i apache

Aluksi komento siis hakee kaikkia ladattavia paketteja, joiden nimessä tai kuvauksessa mainitaan php. Niitä on kuitenkin valtava määrä, joten lisäämällä grep-komentoja mukaan saadaan rajattua hakutuloksia järkevästi. Edellä ajettu komento tuottaakin neljä hakutulosta, joista latasin Apache2:selle tarkoitetun php-moduulin oletusversion komennolla

$ sudo apt-get install libapache2-mod-php

Seuraavaksi potkaisin vielä Apachen uudestaan käyntiin, jotta tehdyt muutokset tulisivat varmasti voimaan:

$ sudo systemctl restart apache2

Tässä vaiheessa yritin jo ajaa pientä php-koodinpätkää, mutta sivulle tulostuikin pelkkää tyhjyyttä. Sen lisäksi sivun lähdekoodissa näkyi annettu php-koodi suoritetun koodin lopputuloksen sijasta, mikä ei todellakaan ole toivottava tilanne. Melko pitkään asiaa ihmeteltyäni muistin, että oletusasetukset eivät salli php-skriptien ajamista käyttäjien kotihakemistoista käsin, ja niinpä asetuksia pitää muuttaa. Antamalla komento

$ sudoedit /etc/apache2/mods-available/php7.2.conf

päästään muokkaamaan Apachen conf-tiedostoa siten, että muutetaan viisi alinta kuvassa näkyvää riviä kommenteiksi:

Tallentamisen jälkeen polkaisin Apachen käyntiin vielä uudestaan ylempänä mainitsemallani komennolla ja sen jälkeen oli aika luoda php:ta käyttävä sivu kotihakemiston public_html-kansioon. Itse en halunnut lisätä hienolle index.html-kalasivulleni ylimääräistä hässäkkää, joten loin kokonaan uuden tiedoston php:n testaamista varten komennolla

$ gedit hello.php

Olin aikaisemmin ladannut gedit-nimisen tekstieditorin tällaisia tilanteita varten, koska sen avulla on vähän kätevämpää koodailla. Käyttämäni koodinpätkä vaikutti toimivan sivulla, kuten seuraavasta kuvasta näkyy:

Seuraavaksi olikin vuorossa php-koodiin virheen tekeminen. Oletin, että tämä onnistuisi suhteellisen helposti esimerkiksi hankkiutumalla eroon lainausmerkeistä tai suluista. Poistinkin Hello World -tekstin edestä lainausmerkin ja myös laskutoimituksen jälkeisen sulun. Olin avannut jo valmiiksi tekstieditoriin /var/log/apache2-hakemistossa sijaitsevan error.log-tiedoston, ja heti kun tallensin virheellisen koodin ja latasin nettisivun uudestaan, lokiin ilmestyi uusi rivi:

[Sun Feb 03 19:46:08.319395 2019] [php7:emerg] [pid 14330] [client 127.0.0.1:59334] PHP Parse error:  syntax error, unexpected 'World' (T_STRING), expecting ',' or ';' in /home/helkera/public_html/hello.php on line 7

Ensin siis ilmoitetaan, koska kyseinen virhe tapahtui. En ole varma, mitä php7:emerg kokonaisuudessaan tarkoittaa, mutta pid on asianosaisen prosessin id-numero. Seuraavana listalla on ainakin client-koneen IP-osoite ja ilmeisesti myös portti. Sen jälkeen alkaa tarkempi selitys itse virheestä, joka tässä yhteydessä liittyy siihen, ettei koodia saatu parsittua syntaksivirheen vuoksi. Ilmoitus valittaa sanasta World, koska koodi ilmeisesti tyssää juuri siihen kohtaan lainausmerkkien puuttumisen takia. Koska koodin parsija ei tiedä, että kyseessä on tekstinpätkä, se olettaa rivin loppuvan Hello-sanan jälkeen, ja kaipailee siten esimerkiksi puolipistettä tämän merkiksi. Loppuun tulostuu myös, missä hakemistossa virheellinen tiedosto sijaitsee, ja vielä tarkemmin, millä rivillä koodissa virhe tapahtuu.

Tehtävä d

Seuraavaksi häiriötä piti aiheuttaa Apachen config-tiedostoihin. Valitsin kohteekseni /etc/apache2 -kansiossa olevan apache2.config:in. Selailin sitä pitkän aikaa yrittäen miettiä, minkä muuttamisesta tulisi varmasti virheitä. En kuitenkaan ollut ihan varma, joten päädyin siirtämään koko tiedoston pois omasta kansiostaan omaan kotihakemistooni. Sen jälkeen päivitin selaimessani auki olevan sivun ja tutkin, tuliko Apachen error.logiin näkyviin mitään. Yllätyksekseni ei tullut, ja kaikki toimi ihan hyvin ilman config-tiedostoakin. Ajattelin, että ehkä Apache pärjäilee omilla oletusasetuksillaan, vaikkei sillä olisikaan pääsyä config-tiedostoon. Siirsin siis tiedoston takaisin alkuperäiselle paikalleen ja avasin sen uudestaan

$ sudoedit apache2.conf

-komennolla. Tällä kertaa vaihdoin Timeout-kohdassa olevan numeron tekstiksi. Error.logiin ei tämänkään jälkeen ilmestynyt mitään, eikä syslogistakaan löytynyt mitään järkevää. Päätin siis kokeilla tehtävänannossa mainittua apache2ctl configtest -komentoa. Vihdoinkin sain terminaaliin virheilmoituksen:

AH00526: Syntax error on line 92 of /etc/apache2/apache2.conf:
Timeout takes one argument, Timeout duration (sec)
Action 'configtest' failed.
The Apache error log may have more information.

Nopean googletuksen perusteella vaikuttaa siltä, että AH00526 on Apachen syntaksivirheisiin liittyvä koodi, kuten tekstistäkin voi päätellä. Virheessä on myös kerrottu, missä tiedostossa ja millä rivillä kyseinen virhe sijaitsee, ja mukana on myös pienet ohjeet oikean arvon valitsemiseksi. Vaikka virheessä mainitaan, että Apachen virhelokissa saattaa olla lisätietoa, näin ei ainakaan tässä tilanteessa ollut. Viime töikseni editoin vielä config-tiedoston takaisin alkuperäiseen muotoonsa. Ajoin myös uudestaan apache2ctl configtest -komennon, ja vaikka oletin, että virheitä ei pitäisi enää tulla, sain kuitenkin seuraavanlaisen ilmoituksen:

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

Tämä ei kuitenkaan ole erityisen ihmeellistä, sillä Apache ei varmaankaan voi määritellä domain-nimeä automaattisesti, enkä minä ole sellaista asettanut. Config-tiedoston syntaksi on sentään nyt kunnossa.

Tehtävä i

Tässä ns. helppojen tehtävien viimeisessä tehtävässä oli tarkoituksena aiheuttaa lokiin mahdollisimman monta erilaista HTTP-statusta. Tehtävässä b sain jo aikaiseksi statukset 200, 304 ja 404, joten nyt lähdin metsästämään muita statuksia. Analysoin aikaisemmin jo aika tarkasti lokitulosteiden yleisen rakenteen, joten kommentoin tässä tehtävässä lähinnä saatuja statuskoodeja.

Aluksi avasin avukseni Wikipedia-sivun HTTP-statuksista ja lukiessani listaa kiinnitin huomiota koodiin 414, joka kertoo siitä, että annettu URI on liian pitkä. Yritin tavoitella tätä virhettä kirjoittamalla selaimen osoitekenttään niin pitkän osoitteen kuin mahdollista, mutta kuten ennakkoon arvelinkin, se ei riittänyt, sillä sain sen sijaan koodin 404:

127.0.0.1 - - [03/Feb/2019:21:08:41 +0200] "GET /~helkera/kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk HTTP/1.1" 404 718 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"

Seuraavaksi ajattelin, että koska en ole määritellyt sivulle mitään, mihin voisi käyttää POST-metodia, sen yrittäminen saattaisi tuottaa jonkinlaisen virheen. Tämäkään ei kuitenkaan toteutunut, ja käytettyäni löytämääni komentoa

wget --post-data "username=Helkera" http://localhost/~helkera/

sain silti statukseksi 200 sekä seuraavan ilmoituksen terminaaliin:

--2019-02-03 22:55:59--  http://localhost/~helkera/
Resolving localhost (localhost)… 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 634 [text/html]
index.html: Permission denied

Cannot write to ‘index.html’ (Permission denied).

Lokissakin yritykseni näkyi koodilla 200:

127.0.0.1 - - [03/Feb/2019:22:55:59 +0200] "POST /~helkera/ HTTP/1.1" 200 942 "-" "Wget/1.19.4 (linux-gnu)"

Asioiden liian hyvästä toimivuudesta ärsyyntyneenä päätin yrittää jotain vähän erilaista. Tein kokonaan uuden käyttäjän komennolla

 $ useradd holkura

, jonka jälkeen asetin käyttäjälle salasanan komennolla

$ passwd holkura

Salasanan syötettyäni kirjauduin uusille tunnuksille antamalla komennon

$ su holkura

ja syöttämällä juuri määrittelemäni salasanan. Sen jälkeen yritin seuraavanlaista GET-pyyntöä:

$ wget http://localhost/~helkera

ja vaikka odotin saavani 403-statuksen, joka kertoo että käyttäjällä ei ole lupaa pyydettyyn resurssiin, sainkin seuraavanlaisen vastauksen:

--2019-02-03 23:01:46--  http://localhost/~helkera
Resolving localhost (localhost)… 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80… connected.
HTTP request sent, awaiting response… 301 Moved Permanently
Location: http://localhost/~helkera/ [following]
--2019-02-03 23:01:46-- http://localhost/~helkera/
Reusing existing connection to localhost:80.
HTTP request sent, awaiting response… 200 OK
Length: 634 [text/html]
~helkera: Permission denied

Cannot write to ‘~helkera’ (Permission denied).

En ole varma, miksi sain statuksen, joka kielii siitä, että pyydetty resurssi olisi pysyvästi siirretty muualle kielletyn statuskoodin sijasta. Kuten edelliselläkin yrityksellä, lokitulosteet olivat myös nyt hieman erilaiset:

127.0.0.1 - - [03/Feb/2019:23:01:46 +0200] "GET /~helkera HTTP/1.1" 301 572 "-" "Wget/1.19.4 (linux-gnu)"
127.0.0.1 - - [03/Feb/2019:23:01:46 +0200] "GET /~helkera/ HTTP/1.1" 200 941 "-" "Wget/1.19.4 (linux-gnu)"

Koska tein pari aikaisempaa GET-pyyntöä suoraan terminaalista, tällä kertaa esimerkiksi selaintiedot puuttuvat. Terminaali selkeästi lähettää käyttöjärjestelmästään vähemmän spesifiä tietoa selaimeen verrattuna.

Seuraavaksi päätin tehdä holkura-käyttäjänä seuraavan GET-pyynnön:

$ wget http://localhost/~holkura

Normaalin, toimivan hakemistoni sijasta kutsuin siis sivua, jota ei ole olemassa, koska uudella käyttäjällä ei ole kotihakemistossaan public_html-kansiota, eikä myöskään tarvittavaa index-sivua. Omaan oikeaan kotihakemistooni tällä toisella käyttäjällä ei taas ole oikeuksia. Tällä kertaa lykästi ja sain tavoittelemani statuksen:

--2019-02-03 23:31:59--  http://localhost/~holkura
Resolving localhost (localhost)… 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80… connected.
HTTP request sent, awaiting response… 403 Forbidden
2019-02-03 23:31:59 ERROR 403: Forbidden.

Myös lokiin tulostui oheinen rivi:

127.0.0.1 - - [03/Feb/2019:23:31:59 +0200] "GET /~holkura HTTP/1.1" 403 509 "-" "Wget/1.19.4 (linux-gnu)"

Seuraavaksi päätin yrittää jotain jännittävämpää. Apachen config-tiedostoa tutkiessani näin siellä timeout-attribuutin, ja ajattelin, että jos muuttaisin sen arvon riittävän pieneksi, saattaisin saada jonkinlaisen aikakatkaisuun liittyvän virheen. Vaihdoin sudoeditillä oletusarvon 100:sta 0.0000001:teen, tallensin tiedoston ja potkaisin Apachen uudestaan käytiin. Kaikki toimi kuitenkin aivan entiseen malliin. Tarkistin vielä apache2ctl configtest -komennolla, oliko syöttämässäni asetuksessa jotain vikaa, mistä johtuen asetus ei olisi tullut voimaan, mutta mitään sellaista ei ainakaan tulosteesta ilmennyt. Myös yrittämäni pyynnöt saivat access.logissa statuksekseen 200. Ilmeisesti siis pyynnöt joko toimivat salamannopeasti (mikä tuntuu todennäköiseltä) tai jossain muualla on häikkää. Voi myös olla, että ymmärrän väärin, mihin aikakatkaisua tässä yhteydessä ylipäätäänsä käytetään.

Viimeisenä ajattelin yrittää tehtävänannossa mainittua statusta 500, eli internal server erroria. Tämä on geneerinen virheilmoitus, jota käytetään monesti silloin, kun spesifimpää virheilmoitusta ei voida antaa. Ottaessani selvää kuinka tällaisen virheilmoituksen saisi aikaiseksi kiinnitin huomiota siihen, että monet ihmiset kertoivat saaneensa 500-statuksen virheellisen php-koodin takia. Löysinkin tällaisen keskustelun, jonka innoittamana lisäsin omaan hello.php-tiedostooni olemattoman funktion kutsun seuraavalla tavalla:

Kuten kuvasta näkyy, funktion jälkeinen tekstielementti ei enää tulostu ja access.logiin on ilmaantunut uusi rivi:

127.0.0.1 - - [04/Feb/2019:00:28:54 +0200] "GET /~helkera/hello.php HTTP/1.1" 500 288 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0"

En olisi ikinä uskonut olevani näin mielissäni saadessani internal server errorin, haha!

Siinä olivat tämän viikon tehtävät. Näin jälkikäteen ajateltuna olisin kyllä ihan hyvin voinut sittenkin tehdä LAMP-stackin pystyttämistehtävän viimeisen tehtävän sijasta. Siihen olisi saattanut mennä vähemmän aikaakin :D Mutta tehty mikä tehty, enköhän minä sen LAMPin tule pystyttäneeksi joka tapauksessa ennemmin tai myöhemmin. Ja olihan tämä tarkoituksellinen virheiden tekeminen omalla tavallaan aika hauskaa.

”Nopea” ncmpcpp-päivitys

Huhhuh. Tein aikaisemmin illalla sen virheen, että ennen kolmansien tehtävien tekemistä päätin nopeasti vilkaista, saisinko jotenkin ratkaistua aikaisemmin mainitsemani VirtualBoxin äänenlaatuongelman. Yllätyksekseni koko homma hoituikin yllättävän nopeasti ja kivuttomasti, ja sisälsi vain audio controllerin vaihtamisen virtuaalikoneen audioasetuksista. Tästä videosta sain sen käsityksen, että aikaisempi asetukseni olisi soveltunut lähinnä vanhoille Windows-käyttöjärjestelmille. Toinen vaihtoehto oli nimeltään Intel HD Audio, ja koska koneessani on Intelin emolevy, ei ole yllättävää, että se oli tässä tapauksessa toimivampi vaihtoehto.

Asetuksen muutettuani laitoin virtuaalikoneeni innoissani päälle testatakseni oliko äänenlaatuongelma korjaantunut. Ncmpcpp ei kuitenkaan löytänyt musiikkikirjastoani ollenkaan, vaikka viimeisellä käyttökerralla kaikki toimi oikein hyvin. Aloin siis selvittämään, mistä tämä voisi johtua. Kovasta yrityksestä huolimatta en päässyt lähellekään ratkaisua tai edes yksiselitteistä teoriaa tilanteesta. Lopulta kyllästyin ja päätin poistaa sekä mpd:n että ncmpcpp:n ja asentaa ne kokonaan uudestaan. Poistin myös kaikki niihin liittyvät hakemistot ja seurasin asentaessani uusia ohjeita.

Ongelmat eivät kuitenkaan siihen loppuneet. Vaikka ncmpcpp käynnistyikin kerran normaalisti, ja pääsin ilokseni havaitsemaan, että ääni ei todella enää pätkinyt, sitä iloa ei kestänyt kauaa. Yleisesti ottaen tuntuu siltä, että ncmpcpp käynnistyy ongelmitta tasan ensimmäisen kerran asennuksen jälkeen, ja uusilla yrityksillä tulee jos jonkinlaisia ongelmia. Usein käy niin, ettei musiikkikirjasto ei lataudu ollenkaan, mutta välillä kun saan sen näkyviin ja alan soittaa kappaleita, muutaman kappaleen jälkeen ncmpcpp:n yhteys mpd:hen katkeaa ja ohjelma vaikuttaa kaatuvan.

Ainoa asia joka vaikuttaa ainakin satunnaisesti auttavan kappaleiden löytymisongelmaan on täällä mainittu tapa tappaa koko mpd-palvelu ja käynnistää se manuaalisesti uudestaan seuraavalla tavalla:

$ sudo service mpd stop

$ mpd

Tämän jälkeen komento

$ ncmpcpp

avaa soittimen niin, että musiikkihakemiston sisältö ja luomani soittolista näkyvät.

Luulisin, että mpd service saattaa lähteä jossain vaiheessa pyörimään jollain tavalla väärin ja uudelleen käynnistäminen nollaa tilanteen. Tämäkään ei kuitenkaan toimi aina. En tiedä, kuinka tästä ongelmasta pääsisi eroon ja aiheutuvatko saamani time out errorit myös tästä, vai onko taustalla joku isompi asia, josta en tiedä mitään.

Mutta niin. Audio ei rahise enää, mutta sain tilalle noin viisitoista muuta ongelmaa, joiden ratkaiseminen on huomattavasti hankalampaa :D Sen lisäksi en ole edes aloittanutkaan oikeiden tehtävien tekemistä. Ja kello on 04.09. Miksi olen tällainen.

Ja nyt vaikuttaa myös siltä, etten saa enää mpd-prosesseja edes tapettua.

Yritin seuraavaksi myös tarkastella tilannetta htop:in avulla.

Kuvan alalaidassa näkyy vaikka kuinka monta mpd-nimistä prosessia, mutta en saa hankkiuduttua niistä eroon edes htop:illa. Kiinnostavaa on myös, että vaikka pidof mpd -komento tulostaa koko ajan 1473, htopin listalta ei löydy sillä prosessi-id:llä mitään. Ehkä on aika jättää tämä mysteeri tältä päivältä tähän ja paneutua asiaan uudestaan joskus myöhemmin. Jos joku hullu mpd/ncmpcpp -guru tätä sattuisi lukemaan, niin apua otetaan mielellään vastaan.

… Kovasta yrityksestä huolimatta en kuitenkaan kyennyt lopettamaan hyvän sään aikana, vaan käynnistin virtuaalikoneen uudelleen ja hain htopilla uudestaan prosesseja mpd-hakusanalla. Ja nyt command-kohdassa pelkän mpd-sanan sijasta on /usr/bin/mpd –no-daemon. Ja näitä prosesseja löytyy noin seitsemän kappaletta. En tiedä, onko tämä normaalia, mutta muistan käyttäneeni –no-daemon -komentoa yrittäessäni kaikkia mahdollisia ehdoitettuja ratkaisuja ongelmiini. Voi olla, että olen sössinyt jotain ja minun olisi parasta koittaa asennusta kokonaan uudestaan. Tällä kertaa ncmpcpp lähti käyntiin ihan reippaasti, mutta hyytyi taas soittolistan toiseen kappaleeseen saatesanoilla ncmpcpp: Timeout while connecting. Eli jotain mätää tässä nyt selkeästi on.

Poistettuani sekä mpd:n että ncmpcpp:n komennolla

$ sudo apt-get remove mpd ncmpcpp

olisin olettanut, että pidof mpd ei olisi enää palauttanut mitään, mutta näin ei ollut. Sen lisäksi aikaisemmat /usr/bin/mpd-prosessit elivät ja voivat hyvin edelleen. Poistin siis sekä .mpd että .ncmpcpp -kansiot että mpd:n startupista ja käynnistin koneen uudelleen. Tämän operaation jälkeen htop ei enää löytänyt mpd-nimisiä prosesseja.

Seuraavaksi asensin ohjelmat uudelleen komennolla

$ sudo apt-get install mpd ncmpcpp

ja kopioin talteen ottamani config-kansiot takaisin omille paikoilleen. Tämän jälkeen ncmpcpp lähti taas normaalisti käyntiin ja nyt nähtäväksi jää, kuinka kauan tätä iloa kestää. Ja sieltähän se ensimmäinen timeout error tulikin heti ensimmäisen kappaleenvaihdon aikana. Kuitenkin kun vaihdoin seuraavaan kappaleeseen, ohjelma toipui ja aloitti kappaleen toistamisen. Onkohan mahdollista, että kappaleissani tai soittolistassani on jotain vikaa? Pitäisi varmaankin yrittää luoda uusi soittolista ja katsoa, jatkuvatko ongelmat senkin jälkeen.

Jos nämä ongelmat olisivat jotenkin systemaattisempia, niitä olisi helpompi ratkoa :D Nyt sain soitettua useamman kappaleen peräkkäin, vaikka soitin vaikuttaakin päättävän täysin mielivaltaisesti, alkaako se toistaa seuraavaa kappaletta automaattisesti vai ei. Välillä voin manuaalisesti laittaa seuraavan kappaleen soimaan, välillä sen yrittäminen taas tuottaa timeout errorin. Myös saman kappaleen sisällä eri kohtiin skippaaminen tuottaa saman lopputuloksen. Ja jos käynnistän ncmpcpp:n uudelleen se toimii äärimmäisen hitaasti ja heittää uudestaan Timeout while connecting -errorin.

Nyt kyllä pakotan itseni lopettamaan. Voisin yrittää rauhoittua syömällä vähän iltapalaa ja sen jälkeen menen kyllä vihdoinkin nukkumaan. Huomisen piti olla mukava ja rauhallinen päivä, mutta nyt siitä tuleekin työntäyteinen. Viime sunnuntaina kirosin sitä, että jätin tehtävät sunnuntaihin ja lupasin itselleni, että seuraavat tehtävät tekisin rauhassa lauantaina. Vaan kuinkas sitten kävikään…