---
# System prepended metadata

title: Inhoudsopgave

---

<h1 style="text-align:center">Linux Webserver</h1>
<br><br><br>

![](https://i.imgur.com/5DKkOU6.png)

<br><br><br><br><br><br><br><br><br>


| Naam    | Klas | Vak | Opleiding | Docent
| -------- | -------- | -------- | -- | -- |
| Natan van der Meulen     | ICT1D     | Linux     | Lerarenopleiding technisch beroepsonderwijs ICT | Koos Stoker|

<div style="page-break-after: always;"></div>

# Inhoudsopgave
- Installatie Debian
- Commands & Configuratie
     - Instellen van SSH sleutel
     - Verbinden d.m.v. SSH
     - Activeren sudo
     - Docker installeren
     - NGINX server maken
     - Beheren en mounten van de websitebestanden
     - Back-up & Restore
     - Logging
     - Test gebruikers
         - Gebruiker zonder rechten
         - Gebruiker met rechten
- Kale configuratie
- Bronnen

<div style="page-break-after: always;"></div>

# Installatie Debian 

Voor onze webserver gaan we gebruik maken van een Debian omgeving waarop we een docker image gaan draaien waar de webserver op draait.
Allereerst zullen we debian moeten installeren:
Via de Debian website kunnen we een .iso bestand downloaden:
`https://www.debian.org/download`

Voor dit voorbeeld gebruiken we een virtuele machine die wij in gaan richten. Wanneer we de .iso inladen in VM krijgen we het volgende scherm te zien:

![](https://i.imgur.com/xMQfOoZ.png)

Omdat we een server gaan inrichten hoeven we geen GUI te hebben, dus kiezen we voor de tweede optie. Volg de normale installatie tot de hostname van je server gevraagd wordt:

![](https://i.imgur.com/muZEOM5.png)

Omdat we een webserver gaan draaien op een linux server, kiezen we logisch gewijs voor de naam `linux-webserver`.

Wanneer er gevraagd wordt om een root-wachtwoord in te geven zorgen we ervoor dat we dit wachtwoord leeg houden:

![](https://i.imgur.com/Kdxkg4e.png)

In de tekst zien we namelijk staan dat als we het rootwachtwoord leeg laten, er geen rootaccount wordt aangemaakt. De gebruiker die later wordt gecreeërd heeft de permissie om rootrechten te krijgen via het `sudo` commando.

![](https://i.imgur.com/v0yadrm.png)

Even verderop in de installatie maken we de gebruiker `natan` aan. En vullen we het wachtwoord `Welkom01!` in. Dit wachtwoord is bedoeld als demonstratie, in een reële omgeving kiezen we natuurlijk een veiliger wachtwoord.


![](https://i.imgur.com/IYfzWD5.png)

Ten slotte tegen het einde van de installatie wordt er gevraagd welke onderdelen we standaard kunnen installeren op de server.

![](https://i.imgur.com/5AlVebp.png)

Hier kiezen we enkel voor `SSH`, omdat we de webserver zo kaal mogelijk willen houden.

Als je alles goed hebt ingevuld, is de installatie van Debian compleet.

<div style="page-break-after: always;"></div>

# Commands & Configuratie 

## Instellen van SSH sleutel 

Om een veilige inlogmethode te gebruiken, maken we een SSH sleutel. Met het volgende commando wordt deze gegenereerd:

```bash=
ssh-keygen
# druk twee keer op enter om beide wachtwoord-invoervelden leeg te laten
# druk nog een keer op enter om de standaard bestandslocatie te gebruiken
```

Er is nu een ssh folder inclusief ssh-key aangemaakt in je gebruikersfolder. In deze folder staat een bestandje dat `id_rsa.pub` heet. In dit bestand bevindt zich de ssh-key. Deze kunnen we kopieëren.

Op het debian systeem kunnen wij deze ssh vervolgens toevoegen.
Met het commando `mkdir ~/.ssh` maken we een folder aan waarin we de ssh-keys kunnen opslaan. Vervolgens maken we d.m.v. nano een bestand aan waarin wij `authorized_keys` opslaan. Dit doen we door het commando `nano .ssh/authorized_keys` te gebruiken. 

```bash=
mkdir ~/.ssh
nano .ssh/authorized_keys
```
Hierin plakken we de ssh-key die we hebben gegenereerd op onze desktop:

![](https://i.imgur.com/VHinIcX.png)

We kunnen nu verbinden met SSH, zonder dat we een wachtwoord hoeven in te vullen.

<div style="page-break-after: always;"></div>

## Verbinden d.m.v. SSH 

Na de installatie van Debian willen we de server beheren via SSH. We vragen hier het IP-adres van de server op door het volgende commando te gebruiken:

```bash=
ip address
```

![](https://i.imgur.com/FTXDSxX.png)


We zien dat het IP-adres `192.168.14.129` is. Via de Command Prompt van onze lokale machine kunnen we nu via ssh connecten d.m.v. het commando:

```bash=
ssh natan@192.168.14.129
```

![](https://i.imgur.com/sSFvoCv.png)

We zijn nu via SSH verbonden met de server.

## Activeren sudo 

Om `sudo` rechten te krijgen, gaan we eerst `sudo` activeren zodat we niet elke keer het wachtwoord hoeven in te voeren wanneer we een sudo commando gebruiken.

```bash=
sudo -v 
# Nu kunnen we het password invoeren: Welkom01!
```

<div style="page-break-after: always;"></div>

## Docker installeren 

Om Docker te kunnen installeren willen we via `curl` het installatiescript van docker ophalen. Hiervoor moeten we eerst curl installeren:

```bash=
sudo apt install curl
```

Nu kunnen we het installatiescript van docker ophalen.
Het installatiescript pipen we direct naar bash, zodat het script wordt uitgevoerd.

```bash=
curl https://get.docker.com | bash
```

Nu we docker hebben geinstalleerd moeten we de user `natan` toevoegen aan de dockergroep:

```bash=
sudo adduser natan docker
```

Om de groepswijziging toe te passen, dient er opnieuw ingelogd te worden.

Om te valideren of we daadwerkelijk zijn toegevoegd aan de group docker, kunnen we het volgende commando gebruiken:

```bash=
groups
```

Zoals we kunnen zien staat de group `docker` tussen de lijst met groups. We zijn dus toegevoegd aan de `docker` group.

![](https://i.imgur.com/OMhWOhm.png)

Nu we Docker hebben geinstalleerd kunnen we controleren of we ook een docker image kunnen aanmaken door het volgende commando te gebruiken:

```bash=
docker run hello-world
```

![](https://i.imgur.com/0TqWekt.png)

<div style="page-break-after: always;"></div>

## NGINX server maken 

Nu gaan we de webserver installeren op onze Docker-omgeving. Normaal gesproken kan dat met dit commando:

```bash=
docker run --detach --publish '80:80' --name "web-server" --restart "always" "nginx:latest"
```

We zien dat er erg veel parameters zijn wat dit commando erg foutgevoelig maakt. Het is in dit geval makkelijker om een yml bestandje aan te maken dat we opslaan in het mapje `/web-server`. Zo zijn de parameters een stuk makkelijker te beheren. Dit mapje maken we zo aan:

```bash=
mkdir web-server
cd web-server
nano docker-compose.yml
```

Plak vervolgens de volgende inhoud in het bestand.

```yaml=
services:
  nginx: 
    image: 'nginx:latest'
    container_name: 'web-server'
    restart: 'always'
    ports:
      - '80:80'
```

Dit scriptje bouwt een docker omgeving met de naam `web-server`. De restart zorgt ervoor dat de docker omgeving altijd wordt opgestart wanneer de debian server wordt aangezet. De parameter `ports` geeft aan dat poort 80 van de container opengesteld wordt op poort 80 van de host.


Met het volgende commando zorgen we ervoor dat de docker omgeving opgemaakt wordt. Dit commando kunnen we later ook gebruiken voor het opnieuw opmaken van de container, wanneer er iets is gewijzigd.

```bash=
docker compose up -d
```

de `-d` zorgt ervoor dat het proces op de achtergrond wordt uitgevoerd. Dat kunnen we controleren met het volgende commando:

```bash=
docker compose ps
```

![](https://i.imgur.com/yMVqOiZ.png)

Zoals we kunnen zien draait het proces op de achtergrond.

<div style="page-break-after: always;"></div>

## Beheren en mounten van de websitebestanden

Op de Debian server maken we een folder aan waarin we de websitebestanden kunnen beheren.
Dit doen we door een mapje `www` aan te maken:

```bash=
cd ~/web-server
mkdir www
cd www
nano index.html
```

In het `index.html` bestand kunnen we inhoud van de website plaatsen:

```htmlembedded=
<html>
    <title>Onze eigen webserver gemaakt met NGINX!</title>
    <h1>
        Dit is een index.html
    </h1>
    <p>
        Dit bestand kan aangepast worden op de webserver.
    </p>
</html>
```

Om de zojuist gemaakte folder te mounten in de container moeten we het yuml bestand van de docker-container aanpassen en het volgende toevoegen: 

```diff=
services:
  nginx: 
    image: 'nginx:latest'
    container_name: 'web-server'
    restart: 'always'
    ports:
      - '80:80'
+    volumes:
+      - './www:/usr/share/nginx/html'
```

Het mapje `/www` is het mapje waarin wij de websitebestanden willen beheren, en wij mounten dat aan het mapje waar de html staat op de webserver: `/usr/share/nginx/html`

Wanneer we nu de docker updaten met het volgende commando, zal de webserver onze index.html laten zien:
```bash=
docker compose up -d
```

Het volgende verschijnt als we naar `192.168.14.129` navigeren:

![](https://i.imgur.com/sAaorVX.png)

<div style="page-break-after: always;"></div>

## Back-up & Restore 

In de docker container draaien wij enkel de webserver en is back-up en restore hier niet van toepassing. De bestanden van de webserver beheren wij op de debian server. Van deze bestanden gaan we elke dag een backup laten maken. Van de Debian server zelf kunnen we eventueel nog dagelijks snapshots maken, maar voor nu focussen we ons vooral op de backup van de bestanden.

In de `web-server` folder naast de map `www` maken wij een `backup` folder aan:

```bash=
mkdir ~/web-server/backup
```

Met een bashscript zorgen we ervoor dat alle bestanden in de `www` folder worden gekopieerd in een map met de huidige datum:

Dit backupscript zetten wij in een `bin` folder, die wij in de home directory plaatsen. We maken ook direct een `log` folder aan die de log van de backup bijhoudt.


```bash=
mkdir ~/{bin,log}
nano ~/bin/backup-webserver
```

De inhoud van het bashscript is als volgt:

```bash=
#!/bin/bash

# Dit commando zorgt ervoor dat het script in de console verschijnt. Erg handig voor logging.
set -xe

# De bronfolder die wij willen kopieëren.
BACKUP_SRC=/home/natan/web-server/www
# De bronfolder waar we de bestanden naartoe willen kopieëren
BACKUP_DEST=/home/natan/web-server/backup

# Navigeren naar de bestemmingsfolder
cd "$BACKUP_DEST"

#De naam van de backup folder geven we de datum van vandaag mee.
BACKUP_NAME=$(date + '%Y-%m-%d')
mkdir -p "${BACKUP_DEST}/$BACKUP_NAME"

BACKUP_PATH="${BACKUP_DEST}/${BACKUP_NAME}"

# Het kopieëren van de bronfolder naar onze backupfolder. De -r zorgt ervoor dat hij alle 'child' directories meeneemt.
cp -r "$BACKUP_SRC" "$BACKUP_PATH"
```

We willen dat dit backupscript elke nacht draait, zodat we elke dag een backup hebben van de websitebestanden. We gaan hiervoor een cronjob aanmaken. We openen de `crontab` in edit modus met het volgende commando:

```bash=
crontab -e
```

Hier voegen wij de volgende regel aan toe:

```bash=
0 1 * * *     bash /home/natan/bin/backup-web-server &>> /home/natan/log/backup.log
```

Deze regel zorgt ervoor dat er elke nacht om 1 uur het bashscript `backup-web-server` draait en de logs weggeschreven worden naar `log/backup.log`.

Nu hoeven we alleen nog een restore script te schrijven:
```bash=
cd ~/bin
nano restore-web-server
```

Daar voegen we de volgende code aan toe:
```bash=
#!/bin/bash

# Dit commando zorgt ervoor dat het script in de console verschijnt. Erg handig voor logging.

DATE=$1

if [[ -z "$DATE" ]]; then
    echo "Datum is verplicht (YYYY-MM-DD)"
    echo "Mogelijke datums: "
    ls -1 /home/natan/web-server/backup | tail -n 10
    exit 1
fi

# De bronfolder die wij willen kopieëren.
RESTORE_SRC=/home/natan/web-server/backup/${DATE}/www
# De bronfolder waar we de bestanden naartoe willen kopieëren
RESTORE_DEST=/home/natan/web-server

if ! [[ -d "$RESTORE_SRC" ]]; then
    echo "Backup met deze datum ($DATE) bestaat niet"
    exit 1
fi

# Het kopieëren van de bronfolder naar onze backupfolder. De -r zorgt ervoor dat hij alle 'child' directories meeneemt.
cp -r "$RESTORE_SRC" "$RESTORE_DEST"
```

Als we nu het commando `bash restore-web-server 2022-05-15` uitvoeren, wordt de backup van 15 mei teruggezet.

<div style="page-break-after: always;"></div>

## Logging 

Het voordeel van docker is dat het ingebouwde logging per proces heeft. Wanneer we het volgende commando draaien krijgen we de logging van de webserver te zien:

```bash=
docker compose logs -f
```

de `-f` zorgt ervoor dat je een realtime log te zien krijgt.

![](https://i.imgur.com/QD06gKs.png)

De logging van de Debian server is terug te vinden in de `/var/logs` folder.

<div style="page-break-after: always;"></div>

## Test gebruikers

We hebben de groep `docker` waarin gebruikers zitten die toegang hebben tot de dockeromgeving. We maken ook een groep `website` aan, voor gebruikers die bij de websitebestanden mogen.

```bash=
sudo groupadd website
```
We zorgen ervoor dat we de owner van de directory aan gaan passen met het volgende commando:

```bash=
sudo chown root:website ~/web-server
```

Tot slot passen we de permissies van de directory aan:

```bash=
sudo chmod 770 ~/web-server
```

### Gebruiker zonder rechten 

Om aan te tonen dat niet iedereen zomaar bij de docker omgeving, of de websitebestanden kan komen, maken we een gebruiker aan zonder deze rechten.

```bash=
sudo useradd --create-home test-user
sudo passwd testpassword1
```

En vervolgens herhalen we het wachtwoord `testpassword1`.
Deze user voegen we **niet** toe aan de group `docker` en `website`.
De test user heeft dus geen rechten om bij de dockeromgeving of de 
websitebestanden te komen.

Wanneer we met deze `test-user` naar de web-server map proberen te navigeren krijgen we de melding dat dat niet kan:

![](https://i.imgur.com/7ozbvak.png)


### Gebruiker met rechten 

Om een administrator aan te maken die de websitebestanden aan kan passen, maken we een test-admin aan die wij toevoegen aan de groepen `website` en `docker`.

```bash=
sudo useradd --create-home --groups docker,website test-admin
sudo passwd adminpassword1
```

Met de `test-admin` gebruiker kan ik wél navigeren naar de web-server map:

![](https://i.imgur.com/aAId94f.png)

<div style="page-break-after: always;"></div>

## Kale configuratie 

Nu we alle onderdelen van de server hebben geïnstalleerd kunnen we doormiddel van het `htop` commando zien dat de server alleen de essentiele processen draait die nodig zijn voor een webserver.

<div style="page-break-after: always;"></div>

# Bronnen 





[Curl](https://curl.se/)
[Docker](https://www.docker.com/)
[NGINX](https://www.nginx.com/)
[How to setup SSH](https://www.makeuseof.com/tag/beginners-guide-setting-ssh-linux-testing-setup/)
[How to install Docker](https://www.youtube.com/watch?v=ZDnVGZU0Apk)
[Mount folder to Docker](https://docs.openvino.ai/2019_R2/_docs_Workbench_DG_Mount_Folder_to_Docker_Container.html)
[Docker documentatie](https://docs.docker.com/)
[Backup scripts en Bash](https://ubuntu.com/server/docs/backups-shell-scripts)
[Cronjob generator](https://crontab-generator.org/)
[Daan ICT - Linux](https://www.youtube.com/c/DaanICT)









