diff --git a/data/config.json b/data/config.json
index 4558a8e..9625c1c 100644
--- a/data/config.json
+++ b/data/config.json
@@ -1,5 +1,5 @@
{
- "title": "Brevifolia",
- "description": "Starter blog using Tina CMS with Next.js.",
+ "title": "Blog Winderickx.me",
+ "description": "Technologie blog vol informatie",
"repositoryUrl": "https://github.com/kendallstrautman/brevifolia-next-tinacms"
}
\ No newline at end of file
diff --git a/data/info.md b/data/info.md
index ab9296b..6177e7a 100644
--- a/data/info.md
+++ b/data/info.md
@@ -2,6 +2,14 @@
title: info page
background_color: '#AEC4BE'
---
-## This blog was created using [NextJS](https://nextjs.org/)
+## Welkom op deze blog
-## To get started, read the NextJS [docs](https://nextjs.org/docs) or checkout the [repository](https://github.com/kendallstrautman/brevifolia-nextjs).
+Bedankt voor je bezoek. Hopelijk heb je iets aan deze blog. Je kan steeds contact opnemen met mij via onderstaande platformen. Aarzel niet en neem gerust contact op!
+
+- [Github](https://github.com/winderickxeli)
+- [Gitlab](https://gitlab.com/eliwinderickx)
+- [LinkedIn](https://www.linkedin.com/in/eli-winderickx-507944223)
+
+Vriendelijke groet
+
+Eli
\ No newline at end of file
diff --git a/pages/blog/[slug].js b/pages/blog/[slug].js
index 734c4f1..6bafbb2 100644
--- a/pages/blog/[slug].js
+++ b/pages/blog/[slug].js
@@ -29,7 +29,7 @@ export default function BlogTemplate({ frontmatter, markdownBody, siteTitle }) {
{markdownBody}
- Written By: {frontmatter.author}
+ Gemaakt door: {frontmatter.author}
)
diff --git a/posts/10Aug-AWK_basis.md b/posts/10Aug-AWK_basis.md
new file mode 100644
index 0000000..ba0f8e5
--- /dev/null
+++ b/posts/10Aug-AWK_basis.md
@@ -0,0 +1,86 @@
+---
+title: "Een AWK-basis"
+excerpt: "Heel tof dat jij scripts kan schrijven. Tijd voor een versnelling hoger met AWK. Een onmisbare tool om oneliners te schrijven"
+date: "2023-08-10T15:00:00.000Z"
+author: Eli Winderickx
+hero_image: /awk.png
+category: AWK,GNU-tools,Linux,Scripting
+---
+## Wat eerst?
+Het commando `awk` (of `gawk`) is een supersterke tool die meegeleverd wordt met de meeste `GNU/Linux` distributies en een eerste versie bestaat al sinds 1977. De `gawk` is de `GNU` implementatie van de `awk`-tool. Als je een `ls -alh $(which awk)` uitvoert, merk je dat dat een symlink is naar de `gawk` executable.
+
+> Leuk weetje: de Naam `AWK` komt van de oorspronkelijke ontwikkelaars; Aho, Weinberger en Kernighan.
+
+Deze tool ga je kunnen gebruiken voor tekst verwerking en manipulaties. Specifiek gaat `awk` lijnen, records of tekst zoeken die aan bepaalde patronen voldoen. De gefilterde content kunnen we dan uitvoeren met bepaalde manipulaties. `Awk` is eigenlijk ook een volledige programmeertaal waarmee je tal van functies in en buiten `awk` kan benutten voor wat je probeert te bereiken.
+
+### De alternatieven
+Velen zullen ongetwijfel ook gekend zijn met `grep` en `sed`. Beide commando's zijn ook vaak beschikbaar en alhoewel ook stevige opties, kunnen ze niet zo veel als `awk`. Leer alle commando's sowieso kennen maar als je je specialiseert in één van de drie, kies dan zeker voor `awk`. De tool `grep` is voornamelijk gekend voor eenvoudig tekst in bestanden terug te vinden. `Sed` daarnaast is een specialist als `stream editor` om tekst eenvoudig aan te passen. Hou deze blog zeker in het oog als je ook van deze tools meer wilt weten.
+
+```bash
+# Zoek recursief naar TEKST en inverteer dan de selectie
+grep -v -r "TEKST" /pad/naar/map/of/bestand
+# zoek naar alle TEXT entries vanaf lijn 3 in een bestand en verander naar TEKST
+sed -n `3,$ s/TEXT/TEKST/g`
+```
+
+## Belangrijk om te weten
+`AWK` gebruikt een aantal automatische variabelen om je op weg te helpen. Dit zijn de voornaamste die je gaat willen gebruiken:
+- RS (**R**ecord **S**eperator): Standaard gaat `AWK` lijn per lijn willen verwerken. Dit gaat in vele gevallen ook telkens een nieuwe record aangeven. Als dat niet het geval is, kan je dit aanpassen naar een andere waarde.
+- NR (current input **N**umber **R**ecord): Per record dat er verwerkt wordt, wordt er ook bijgehouden op welk record nummer we zitten. Dat nummer wordt opgeslagen in het `NR`. Je kan zo de even of onevenrecords filteren of misschien alleen de eerste lijn laten vallen.
+- FS/OFS ((**O**utput) **F**ield **S**eperator): Binnen een lijn of record zitten verschillende fields of data items. In een CSV-bestand worden die vaak gesplitst met een `,` of een `;`-teken. De `FS` is dan het record waarmee `AWK` de input gaat splitsen. Achteraf bij het printen van de output, kan dat opnieuw gesplitst worden met de `OFS`-variabele.
+- NF (**N**umber **F**ield): Dit geeft aan hoeveel data items er in het huidige record bevinden. Dit kan handig zijn als `FS` nog steeds een standaard whitespace is. Zo weet je meteen hoeveel woorden er in het record zitten.
+
+## Een paar commando's
+
+Het meest basis commando is: print alle records. Dat doen we zo:
+```bash
+awk '1 {print}'
+# Omdat dit de default actie is, kunnen we ook
+awk 1
+```
+
+Omdat we de standaard actie `print` kennen, kunnen we deze weglaten en een paar complexere bewerkingen typen.
+```bash
+# Toon alles behalve de eerste lijn / record
+awk 'NR>1'
+# Toon enkel de eerste lijn / record
+awk 'NR==1'
+# Toon lijn / record 2 en 3
+awk 'NR>1 && NR<4'
+# Verwijder alle witlijnen
+awk 'NF'
+```
+
+We kunnen ook zoeken op tekst en die tekst aanpassen:
+```bash
+# Zoek naar "TEKST"
+awk '/TEKST/ {print $0}'
+# Vervang TEXT naar TEKST
+awk '{gsub(/TEXT/,"TEKST")}{print}'
+```
+
+> Standaard gaat `awk` de output naar de terminal sturen. Maak daar gebruik van om jouw wijzigingen eerst te controleren. Achteraf kan je dit gemakkelijk doorsturen naar een onder bestand met `>` of `>>`. Wil je toch het originele bestand aanpassen gebruik dan `awk -i inplace`.
+
+Wiskundige berekeningen zijn ook geen probleem. Lijnen of records tellen of de data zelf optellen? Dat doe je zo:
+```bash
+# Tel alle records van kolom 4 en tel dan enkel die waar waarin TEKST voorkomt
+awk '{count[$4]++} END {print count["TEKST"]}' FS=,
+# Maak een som van alle waarde in de eerste kolom
+awk '{ SOM=SOM+$1 } END {print SOM}' FS=; OFS=;
+# Als een waarde in de eerste kolom hoger is dan 9000, print dan die lijn
+awk '{ if ($1 > 9000) {print $0} }'
+```
+
+Met die laatste entries zie je al dat we richting een echte programmeertaal aan het gaan zijn. Nu gaan we nog een stapje verder met een `for`-lus. Als je niet vertrouwd bent met programeren, gaat deze data als een groupering of array beschouwen. Voor iedere aparte waarde, gaan we dan een bewerking doen. In dit geval optellen per naam.
+```bash
+awk `+$1 { CREDITS[$3]+=$1} END { for (NAAM in CREDITS) print NAAM, CREDITS[NAAM]}` FS=,
+```
+
+Naast een `for`-lus, heb je ook `if-else` of `switch`-statements voor conditionele statements en `while`- en `do-while`-lussen voor iteratie.
+
+Tot slot nog een ander leuk trukje is externe commando's oproepen en de output daarvan toevoegen aan jouw data. Hieronder halen we zo bijvoorbeeld de datum op door het `date`-commando uit te voeren. Dit gebruiken we om een hoofdding aan te maken om aan te geven wanneer het bestand aangepast is.
+```bash
+awk 'BEGIN { printf("AANGEPAST OP: "); system("date")} /^AANGEPAST OP:/ {next} 1'
+```
+
+[De volledige `GAWK` handleiding is vrij en gratis beschikbaar op de website van GNU.org.](https://www.gnu.org/software/gawk/manual/gawk.html)
\ No newline at end of file
diff --git a/posts/11Okt-HashicorpVault.md b/posts/11Okt-HashicorpVault.md
new file mode 100644
index 0000000..4b060a7
--- /dev/null
+++ b/posts/11Okt-HashicorpVault.md
@@ -0,0 +1,123 @@
+---
+title: "Hashicorp Vault"
+excerpt: "Wachtwoorden op een veilige manier gebruiken met Hashicorp Vault. Een wachtwoordmanager die met API's en thirdparty tools kan werken!"
+date: "2023-10-11T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Vault_cover.png
+category: Wachtwoord manager,Linux,Beveiliging
+---
+## Hoe beginnen we hieraan?
+Een wachtwoord manager is tegenwoordig geen overbodige luxe om te hebben. Containers vormen vaak een basis van ontwikkelingen en die moeten automatisch en op een veilige manier hun configuratie krijgen. Het is dan niet veilig als je dan een wachtwoord als `clear text` in een bestand laat staan. Iedereen met toegang tot de configuratie, kan dan meteen het wachtwoord uitlezen. Veel beter is dan een wachtwoordmanager zoals Vault van Hashicorp. Dit soort wachtwoordmanager is niet bedoelt voor jouw dagdagelijks gebruik zoals een Bitwarden in jouw browser of smartphone. Deze is ontworpen zodat andere computers, API's en dergelijke, hier gemakkelijk gebruik van kunnen maken. Hoe dat gebeurt, lees je hieronder. Eerst hebben we en paar zaken nodig voor we van start gaan.
+
+### Repo
+Om te beginnen, moeten we de repo van Hashicorp toevoegen. Hun software zit namelijk niet in de standaard repo's van Red Hat of Fedora. Toevoegen van die repo's is eenvoudig werk. Je vindt hun repo ook vrij snel op hun website. Hier toch even de stappen voor jouw gemak. 😉
+
+```bash
+wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
+mv hashicorp.repo /etc/yum.repos.d/
+sudo dnf update
+sudo dnf -y install vault
+```
+
+
+
+### Certificaat
+Om een beveiligde verbinding te kunnen maken met onze server, moeten we ook een certificaat hebben. In het veld wil je steeds één van de volgende opties gebruiken:
+- Een certificaat ondertekend door een interne Certificate Authority (CA).
+- Een certificaat van een erkende CA.
+- Een geldig certificaat via [`Let's encrypt`](https://letsencrypt.org/).
+
+> Bekijk [mijn blog post over Let's Encrypt](https://blog.winderickx.me/posts/8Okt-Certbot) om na te gaan hoe je `certbot` op jouw toestel zet. Daarmee kunnnen we nu een geldig certificaat genereren.
+
+Als je het certificaat rechtstreeks op de server genereert, kan je het `Let's Encrypt` certificaat terugvinden in `/etc/letsencrypt/live/domeinnaam/fuulchain.pem` en de key in dezelfde map maar dan `privkey.pem`. Deze ga je in de volgende stap willen invullen.
+
+## Configure Vault
+We hebben nu ons certificaat en Vault is geïnstalleerd. We zijn er bijna, toch? Neen toch niet maar hou dat enthousiasme vast! In de configuratie ga je nu een verwijzing willen maken naar jouw certificaat. Die configuratie vind je in: `/etc/vault.d/vault.hcl`.
+
+```
+#HTTPS listener
+...
+listener "tcp" {
+ address = "0.0.0.0:8200"
+
+ tls_cert_file = "/opt/vault/tls/domain.crt"
+ tls_key_file = "/opt/vault/tls/domain.key"
+...
+}
+```
+
+Nu dat klaar is, moeten we Vault daar ook toegang tot geven. Een elegante oplossing is een extra group aanmaken en de `vault` gebruiker daar lid van te maken. Deze groep kunnen we dan de nodige rechten geven op de map met ons certificaat. We moeten ook zeker zijn dat als de host naar ons domeinnaam wilt, die naar de lokale server verwijst. Dat kunnen we doen door ons domeinnaam aan `/etc/hosts` toe te voegen.
+
+> Je kan deze stap overslaan als je Let's Encrypt niet op deze server hebt uitgevoerd. Dan moet het certificaat enkel de juiste rechten hebben. Dat kan dan `vault` als eigenaar en groep van de bestanden.
+
+```bash
+sudo groupadd pki
+sudo chgrp -R pki /opt/vault/tls/
+sudo chmod -R g+rx /opt/vault/tls/
+sudo usermod -a -G pki vault
+echo 127.0.0.1 | sudo tee -a /etc/hosts
+```
+
+Start en initialiseer vervolgens Vault. Bij het initialiseren, geven we een paar opties mee. `Key shares` verwijst naar het aantal tokens dat we gaan maken om onze kluis te ontgrendelen en `key threshold` is het aantal tokens die nodig zijn om de kluis effectief te ontgrendelen.
+
+```bash
+# Start service
+sudo systemctl enable --now vault.service
+# Geef aan hoe de vault bereitk wordt
+export VAULT_ADDR=https://:8200
+# Initialeseer de kluis
+vault operator init -key-shares=3 -key-threshold=2
+```
+
+> Let op dat je de Root EN Unseal Tokens goed noteert. Deze gaan niet meer opnieuw getoond worden en zijn de enigste manier om in jouw kluis te komen.
+
+## Werken met de vault
+
+Onze kluis is aangemaakt en standaard is die meteen vergrendeld. Voordat we nu dus kunnen werken met onze kluis, moeten we die dus eerst ontgrendelen. Omdat we `key threshold` op twee gezet hebben, moeten we twee `Unseal Tokens` ingeven. Dat kunnen we door onderstaand commando tweemaal uit te voeren. Je kan dan iedere keer een andere token ingeven.
+
+```bash
+vault operator unseal
+```
+
+Nu onze kluis ontgendeld is, kunnen we aan het echte werk beginnen. We kunnen een key vault activeren, geheimen daar in steken en die ook oplijsten of ophalen.
+
+```bash
+root_token=
+VAULT_TOKEN=$root_token vault secrets enable kv
+# Lijst secrets
+VAULT_TOKEN=$root_token vault secrets list
+# schijf secret
+VAULT_TOKEN=$root_token vault write kv/message value=mypassword
+# Lees secrit
+VAULT_TOKEN=$root_token vault read kv/message
+```
+
+### Policies maken
+Dit is voorlopig nog niet erg handig. We hebben namelijk maar één manier om de kluis te openen en dan staat de deur ineens open voor alles. Dit kan beter. Dit kunnen we compartmentaliseren. Via een `policy` kunnen we een API of externe tool toch gegevens laten uitwisselen maar dan enkel de info die wij goedkeuren. Belangrijk is dus dat we dan eerst goed aangeven wat er exact mag. Onze applicatie mag bijvoorbeeld enkel gegevens uitlezen vanuit `kv/message`. Om dat te realiseren steken we dat in een bestand zoals bijvoorbeeld: `kv_message_read.hcl`
+
+> Verzamel jouw policies in een gedeelde map en geef deze beduidende namen. De naam `policy.hcl` is dus een slecht voorbeeld. Beter is dan `kv_message_read` waarin je meteen aangeeft waarover het gaat en wat toegestaan is.
+
+```
+path "kv/message" {
+ capabilities = ["read"]
+}
+```
+
+Dit bestand kunnen we nu inlezen om er daarna een `App token` van te maken. Deze token, kunnen we dan gebruiken in onze externe tool of API. Noteer deze dus goed als je onderstaande commando's uitvoert. Die token is het toegangsticket voor onze externe tool.
+
+```bash
+VAULT_TOKEN=$root_token vault policy write message-readonly kv_message_read.hcl
+VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
+```
+
+Nu we onze `app_token` hebben, kunnen we deze in onze API of tool gebruiken. Ben je curieus wat nu wel of niet werkt? Voer de commando's onder `Werken met Vault` opnieuw uit maar dan met de `app_token`. Als alles goed gaat, kan je nu enkel de gegevens lezen uit kv/message.
+
+```bash
+app_token=
+# Dit werkt
+VAULT_TOKEN=$app_token vault read kv/message
+# Dit niet
+VAULT_TOKEN=$app_token vault list kv/
+```
+
+Wil je hiermee nog wat verder spelen? Lees dan zeker de verdere documentatie van [Hashicorp](https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-policies). Daarnaast probeer ik dit voorbeeld nog verder uit te werken met een praktisch voorbeeld. Stay tuned voor deel 2!
\ No newline at end of file
diff --git a/posts/12Okt_ACL.md b/posts/12Okt_ACL.md
new file mode 100644
index 0000000..94a0305
--- /dev/null
+++ b/posts/12Okt_ACL.md
@@ -0,0 +1,96 @@
+---
+title: "Rechtenbeheer on steroids"
+excerpt: "Het standaard rechtenbeheer is vrij beperkt in toegang regelen. Gelukkig kan je met ACL een heel pak meer. Hier meer daarover!"
+date: "2023-10-12T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_ACL.png
+category: ACL,Linux,Beveiliging
+---
+## Discretionary Access Control
+Een moeilijke naam voor het standaard rechtensysteem in Linux. Dit systeem bepaalt wie wat mag doen wel welke bestanden of mappen. Standaard is dat opgedeeld in drie groeperingen van rechten;
+- Gebruiker (of eigenaar)
+- Groep
+- Alle andere gebruikers
+
+Per deze drie groepen kan je opnieuw drie rechten geven; Read, Write en Execute. Deze rechten zijn dan in te stellen met chown (change owner) om de eigenaar of groep te veranderen en chmod (change mode) om de rechten voor de drie entiteiten aan te passen. De basiskennis gaat verder. Je kan de rechten instellen met symbolische of numerieke waarden. Waar je bij symbolische waarden volledig moet uitschrijven welke rechten voor eigenaar, groe. en anderen zijn (u=rwx,g=rwx,o=rwx)en voor numerieke waarden kan je een snel sommetje maken. (777 => iedere 7 is 4,voor leesrechten, plus 2, voor schrijfrechten plus 1 voor uitvoerrechten). Meer over die rechten in [een eerder post](https://blog.winderickx.me/posts/22Jul-Permissions)
+
+## Probleemstelling
+In sommige gevallen heb je meerdere teams die niet noodzakelijke dezelfde rechten mogen hebben maar toch moeten samenwerken in dezelfde locatie. Het basisrechtenbeheer systeem schiet hier tekort. Als we leden van één groep bepaalde rechten geven, kunnen we niet een andere groep andere rechten geven zonder dat we alle andere gebruikers diezelfde rechten ook geven.
+
+## De oplossing: ACL
+Access Control List is een uitbreiding op het basis rechtensysteem en stelt ons in staat om meerdere groepen en gebruikers rechten te geven op bestanden. Ieder bestand en map heeft nog steeds slechts één eigenaar en groep eigenaar maar daarnaast kunnen extra rechten verdeeld worden. De tools hiervoor zitten standaard in onze favoriete Distro's zoals RedHat, Rocky Linux en uiteraard Fedora genaamd `getfacl` en `setfacl`.
+
+Wanneer we `getfacl` uitvoeren op een map, krijgen we de standaard rechten te zien maar iets leuker gepresenteerd. Daarnaast kunnen we ook een flag `-t` meegeven om dezelfde info ook in kollommen gepresenteerd te krijgen.
+
+```bash
+getfacl .
+# file: .
+# owner: ewinderickx
+# group: ewinderickx
+user::rwx
+group::---
+other::---
+
+getfacl -t .
+# file: .
+USER ewinderickx rwx
+GROUP ewinderickx ---
+other
+```
+
+### Extra rechten instellen
+Na `getfacl`, gaan we aan de slag met `setfacl`. Hiermee kunnen we de extra rechten beheren. De syntax om extra rechten toe te voegen is heel simpel.
+
+```bash
+# Instellingen voor gebruikers of groepen
+setfacl -m user:bob:rw /home/development/
+setfacl -m group:devtest:rwx /home/development/
+# Kortere versie om alles ineens uit te voeren
+setfacl -m u:bob:rw,g:devtest:rwx /home/development/
+```
+
+De gebruiker `bob` heeft nu additioneel aan de eigenaar en de groep eigenaar ook lees en schrijfrechten. De `dev` groep heeft daarbovenop ook nog eens uitvoerrechten. Dat terwijl andere gebruikers helemaal geen rechten moeten hebben.
+
+Als we nu `getfacl` uitvoeren op de `/home/development` map ziet het er normaal zo uit. We hebben hier 770 ingesteld als basis rechten met de SGID en sticky bit. De groepseigenaar zal nu developers blijven en iedereen kan enkel bestanden verwijderen die daar eigenaar van is.
+
+```
+# file: .
+# owner: root
+# group: developers
+# flags: -st
+user::rwx
+user:bob:rw-
+group::rwx
+group:devtest:rwx
+mask::rwx
+other::---
+```
+
+### Default rechten
+Complexe rechten zoals die met ACL worden standaard niet toegepast. Als je de `setfacl` uitvoert zoals hierboven, voer je eenmalig een operatie uit. Dat is niet handig als er nieuwe bestanden worden aangemaakt. Hiervoor is er wel nog de `defaults` optie in ACL. Als je de rechten instelt op een map met de `-d` flag, worden de rechten automatisch toegepast op de nieuwe bestanden onder die map.
+
+```bash
+setfacl -d -m u:bob:rw,g:devtest:rwx /home/developers
+```
+
+Dat geeft dan:
+```
+# file: .
+# owner: root
+# group: developers
+# flags: -st
+user::rwx
+user:bob:rw-
+group::rwx
+group:devtest:rwx
+mask::rwx
+other::---
+default:user::rwx
+default:user:bob:rw-
+default:group::rwx
+default:group:devtest:rwx
+default:mask::rwx
+default:other::---
+```
+
+Een bestand dat iemand uit de developers groep aanmaakt, krijgt nu dus ook de rechten van voor devtest en bob zoals hierboven staat. Handig maar vooral ook extra veilig!
\ No newline at end of file
diff --git a/posts/16Aug-GetAGrep.md b/posts/16Aug-GetAGrep.md
new file mode 100644
index 0000000..ba59c4a
--- /dev/null
+++ b/posts/16Aug-GetAGrep.md
@@ -0,0 +1,87 @@
+---
+title: "Grep-tools"
+excerpt: 'Welke grep tools ken jij allemaal? Hier lijst ik er een paar op met een aantal voorbeelden zodat je het bos door de bomen ziet.'
+date: '2023-08-11T21:00:00.000Z'
+author: Eli Winderickx
+hero_image: /grep_cover.png
+category: Grep,Linux
+---
+## Wat is `grep`?
+Volgens de `man`-pages is `grep` een programma dat naar patronen zoekt in bestanden. Er zijn zo verschillende soorten patronen die ondersteunt worden telkens een bepaalde vorm van reguliere expressies (regex). Regex verdient een eigen post dus daar in ga ik nog niet dieper in. Het soort patroon dat je wenst te gebruiken in grep, kan je bepalen met een flag;
+- G: Basis reguliere expressie. Dit is de standaard optie en moet je dus niet meegeven.
+- F: **F**ixed strings. Je gaat een opeenvolging van karakters meegeven en die moeten letterlijk teruggevonden worden. Hier kies je dus voor geen regex.
+- E: **E**xtended: Dit is de meer complexere regex. Deze ga je willen gebruiken als je echt regex wilt gebruiken.
+- P: **P**erl compatible regular expressions (PCREs): Alsof reguliere expressies nog niet voldoende moeilijk was, bestaan er meerdere varianten. Deze vorm is afkomstig van de Perl programmeertaal.
+
+> Als je hulp nodig hebt met het opstellen van je regex query, kan je gebruik maken van [regex 101](https://regex101.com) om eenvoudig je query te testen.
+
+### Enkele voorbeelden
+```bash
+# De meest basis zoekopdracht. Zoek TEKST in het bestand.
+grep 'TEKST'
+# Toon alle lijnen behalve die met TEKST in het bestand
+grep -v 'TEKST'
+# Zoek letterlijk naar onderstaande opeenvolging van karakters.
+grep -F '.*\n'
+# Zoek in alle bestanden van onderliggende mappen naar TEKST.
+grep -r 'TEKST' /pad/naar/map
+# Zoek recursief naar meerdere patronen in een map. Dit is TEKST1 OF TEKST2.
+grep -r -e 'TEKST1' -e 'TEKST2' /pad/naar/map
+# Zoek in meerdere bestanden naar lijnen die eindigen met TEKST.
+grep -E '^.TEKST$' -f -f
+```
+
+## Andere `grep`-tools
+### Compressie
+Vooral als we met log bestanden in een log rotatie werken, kan het zijn dat oudere logs gecomprimeerd worden om zo de bestandsgrootte te verkleinen. Toch kan het voorkomen dat we moeten zoeken in die bestanden naar problemen die zich nu voordoen en misschien al langen voorgedaan hebben. Je kan dan die bestanden terug uitpakken en dan grep gebruiken of je kan ook onderstaande tools gebruiken afhankelijk van de compressie en ineens zoeken in de gecomprimeerde bestanden.
+
+- bzgrep, bzfgrep, bzegrep: bzip2 compressie
+- zgrep: gzip compressie
+- zipgrep: zip compressie
+- xzgrep, xzegrep, xzfgrep, lzgrep, lzegrep, lzfgrep: compressie met xz, lzma, gzip, bzip2, lzop of zstd
+
+Omdat dit een beetje complexer is doorlopen we hier even eenvolledig scenario. Ik kies om te werken met xzgrep omdat deze de meeste compressie standaarden ondersteunt. De kans is ook het grootste dat je deze nodig zal hebben.
+
+```bash
+# Eerst maken we een paar bestanden aan:
+echo "appel" > bestand1
+echo "1234567890" > bestand2
+# Daarna stoppen we deze in een tarbal en vervolgens comprimeren we.
+tar -cf bestanden.tar bestand1 bestand2
+bzip2 -z bestanden.tar.bz2
+# Nu kunnen we zoeken naar tekst in de gecomprimeerde map
+xzgrep appel bestanden.tar.bz2
+# Als de tekst gevonden wordt krijgen we onderstaande boodschap terug.
+grep: (standard input): binary file matches
+# Als het niet gevonden wordt, krijg je niets terug
+xzgrep banaan bestanden.tar.bz2
+```
+
+### Processen
+Met `pgrep` kunnen we proces ID's zoeken. Deze tool hangt ook nauw samen met `pkill` en `pidwait`. Dit kan handig zijn om te zien welke processen bij een specifieke gebruiker horen. Daarnaast kan je ook zoeken of een bepaalde gebruiker een bepaald programma gebruikt, zoals bijvoorbeeld `ssh`. Op eerste zicht misschien niet zo handig om een lijst met PID's terug te krijgen. Dit commando wordt vooral interessant als je het combineert met andere commando's. Hieronder enkele voorbeelden.
+```bash
+# Stop alle tmux processen?
+pkill $(pgrep tmux)
+# Processen die je zelf uitvoert
+pgrep -u $(whoami)
+# Welke processen worden uitgevoerd vanaf /opt
+pgrep -f '/opt'
+# Chrome mag minder resources in gebruik nemen
+renice +4 $(pgrep chrome)
+# Controleer hoeveel resources Chrome in gebruik heeft
+ps -ufp $(pgrep chrome)
+```
+
+### Bonus: `git grep`
+Niet echt een aparte tool maar wel leuk om weten dat `git` ook een optie `grep` bevat. Deze zal gelijkaardig werken als de originele grep en ondersteund ook grotendeels dezelfde flags. Let wel dat je hiervoor een git repository moet zitten om hiervan te genieten. Enkele voorbeelden:
+
+```bash
+# Zoek naar solution maar het mag niet in Documentatie zitten.
+git grep solution -- :^Documentation
+# Zoek naar bestanden met TEKST1 EN TEKST2
+git grep --all-match -e TEKST1 -e TEKST2
+# zoek naar TEKST in bestanden die untracked zijn
+git grep --untracked TEKST
+# Negeer git ignore en zoek in alle bestanden naar TEKST
+git grep --no-exclude-standard TEKST
+```
\ No newline at end of file
diff --git a/posts/16Jul-rebranding-zabbix.md b/posts/16Jul-rebranding-zabbix.md
new file mode 100644
index 0000000..bbb8c35
--- /dev/null
+++ b/posts/16Jul-rebranding-zabbix.md
@@ -0,0 +1,57 @@
+---
+title: "Zabbix rebranden"
+excerpt: 'Zabbix heeft standaard een mooie look and feel. We kunnen hiernaast toch nog een huisstijl toepassen.'
+date: '2023-07-16T18:00:00.000Z'
+author: Eli Winderickx
+hero_image: /ZabbixRebranding_cover.png
+category: Aanpassen,Zabbix,Logo's
+---
+## Vereisten
+Omdat we een rebranding gaan doen hebben we een aantal items nodig;
+- Een groot logo: 114x30px
+- Een logo voor de zijbalk: 91x24px
+- Een compact logo voor de zijbalk: 24x24px
+
+> Sysadmin tip: Heb je geen logo's of grafische vaardigheden? Gebruik een tekst editor naar keuze (neovim, Libreoffice Writer, ...) typ daar een naam in en maak een screenshot.
+
+Als je ook de kleuren wilt aanpassen, moet je ook weten naar welke kleuren je dit wilt doen. Hou dus zeker de hexadecimale notatie bij de hand!
+
+## De logo's
+Hier ga ik er even van uit dat je ``NGINX`` gebruikt als webserver. In ``/etc/nginx/conf.d/zabbix.conf`` ga je normaal dan de configuratie van jouw site terugvinden en normaal is de standaard document root ``/usr/share/zabbix``. Maak hierin een map die al jouw logo's gaat bevatten.
+
+````bash
+sudo mkdir /usr/share/zabbix/my_images
+sudo cp logo*.png /usr/share/zabbix/my_images/
+````
+
+Nu kan je onder ``/usr/share/zabbix/local/conf`` het bestand ``brand.conf.php`` aanpassen. Als deze niet bestaat, kan je die gewoon aanmaken. Deze moet een array teruggeven van de verschillende logo's en eventueel kan je hier ook de footer en help pagina meegeven.
+
+````php
+ '/my_images/EliFull.png',
+ 'BRAND_LOGO_SIDEBAR' => '/my_images/EliFullSmaller.png',
+ 'BRAND_LOGO_SIDEBAR_COMPACT' => '/my_images/EliSmall.png',
+ 'BRAND_FOOTER' => '©Eli Winderick',
+ 'BRAND_HELP_URL' => 'https://winderickx.me/'
+];
+````
+
+## Kleuren aanpassen
+Opnieuw in de document root van de zabbix website (/usr/share/zabbix) ga je in de map ``assets/styles/`` verschillende CSS bestanden terugvinden. Kopieer hier gerust een theme als startpunt. Hierna kan je hier aanpassen wat nodig. Het is een heel bestand dus ik overloop hier de voornaamste items.
+
+````bash
+sudo cp /usr/share/zabbix/assets/styles/blue-theme.css /usr/share/zabbix/assets/styles/new-theme.css
+sudo vim /usr/share/zabbix/assets/styles/new-theme.css
+````
+
+Een simpele maar toch ingrijpende aanpassing is de kleur van de sidebar. Deze kan je een duidelijke kleur van jouw huisstijl geven en zo dus meteen naar je hand zetten. Je kan de volledige ``look and feel`` aanpassen hier dus wees voorzichtig met grote wijzigingen, bouw stuk per stuk op en vooral:
+``KEEP IT SIMPLE, STUPID``
+
+````css
+/* ... */
+.sidebar {
+/* ... */
+ background: #ff0000;
+````
diff --git a/posts/18Okt-InABind.md b/posts/18Okt-InABind.md
new file mode 100644
index 0000000..9031459
--- /dev/null
+++ b/posts/18Okt-InABind.md
@@ -0,0 +1,246 @@
+---
+title: "Host je eigen DNS server in je labo"
+excerpt: "Een labo is heel leuk maar het wordt nog veel leuker als je lokaal een eigen DNS server hebt."
+date: "2023-10-18T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Bind_Cover.png
+category: Bind,DNS,Linux
+---
+## Waarom willen we een eigen DNS server?
+Het is heel leuk als we onze eigen Gitlab server of Zabbix opzetten. Maar als alleenstaande installaties hebben we er niet zo veel aan. We kunnen wel in alle servers de `hosts` bestanden gaan aanpassen tot een paar servers. Daarna wordt het eigenlijk niet meer beheerbaar. Iedere server moet een entry krijgen en moet up to date gehouden worden.
+
+De DNS server kan ons niet alleen helpen om het beheer van die IP-adressen te centraliseren. Daarnaast is het ook fijn om met hostnamen te kunnen werken. Die onthouden toch iets beter dan een reeks IP-adressen.
+
+Een populaire keuze in de Linux wereld voor DNS is BIND.
+
+## Installatie
+We hebben twee onderdelen nodig om deze service op te zetten:
+
+```bash
+sudo dnf install bind bind-utils -y
+```
+
+Dit installeert de `named` service. Configuratie kan gemaakt worden in `/etc/named.conf`. Daar gaan we nu de configuratie doorvoeren.
+
+## Configuratie
+Eerst moeten we instellen via welke weg we configuratie beschikbaar willen stellen. De poort staat vaak al goed. Daarnaast moeten we het IP-adres van de server nog toevoegen alsook wie verzoeken mag sturen. Hier heeft mijn server het IP-adres `192.168.124.115`. Andere servers in mijn labo bevinden zich in hetzelfde subnet dus die mogen verzoeken sturen; `192.168.124.0/24`
+
+```
+...
+listen-on port 53 { 127.0.0.1; 192.168.124.115; };
+...
+allow-query { localhost; 192.168.124.0/24; }
+```
+
+Onderaan dat bestand kunnen we dan aangeven welke zones we gaan aanbieden. Doe dat net boven de `include` regel. Per zone kan je een domein configureren. Hier gaan we twee entries voorzien. De eerste is voor het forward domain zone en de tweede is voor de reverse DNS.
+
+Onthou goed wat je onder `file` noteert. Dat worden de namen van de bestanden voor de volgende stap.
+
+```
+...
+zone "winderickx.me" IN {
+type master;
+file "forward.winderickx.me";
+allow-update { none; };
+};
+
+zone "124.168.192.in-addr.arpa" IN {
+type master;
+file "reverse.winderickx.me";
+allow-update { none; };
+};
+include "/etc/named.rfc1912.zones";
+...
+```
+
+Nu deze configuratie klaar staat, kunnen we de effectieve data invullen in de bestanden die we in de vorige stap hebben ingegeven. Deze bestanden staan standaard in `/var/named` map.
+
+> Domeinnamen in DNS eindigen altijd met een . om duidelijk het TLD (Top Level Domain) aan te geven.
+
+`forward.winderickx.me`
+```
+$TTL 86400
+@ IN SOA dns.winderickx.me. root.winderickx.me. (
+ 2011071001 ;Serial
+ 3600 ;Refresh
+ 1800 ;Retry
+ 604800 ;Expire
+ 86400 ;Minimum TTL
+)
+@ IN NS dns.winderickx.me.
+@ IN A 192.168.124.99
+dns IN A 192.168.124.115
+ IN A
+```
+
+`reverse.winderickx.me`
+```
+$TTL 86400
+@ IN SOA dns.winderickx.me. root.winderickx.me. (
+ 2011071001 ;Serial
+ 3600 ;Refresh
+ 1800 ;Retry
+ 604800 ;Expire
+ 86400 ;Minimum TTL
+)
+@ IN NS dns.winderickx.me.
+@ IN PTR winderickx.me.
+dns IN A 192.168.1.115
+115 IN PTR dns.winderickx.me.
+ IN PTR .
+```
+
+Zorg er voor dat de named groep rechten heeft op het bestand.
+
+```bash
+sudo chgrp named -R /var/named
+```
+
+> Vergeet niet de firewall aan te passen!
+
+```bash
+sudo firewall-cmd --add-service=dns --permanent
+sudo firewall-cmd --reload
+```
+
+Controleer nu de configuratie.
+```bash
+sudo named-checkconf /etc/named.conf
+sudo named-checkzone /var/named/forward.winderickx.me
+sudo named-checkzone /var/named/reverse.winderickx.me
+```
+
+Als daar geen fouten uitkomen, kan je nu de service starten.
+
+```bash
+sudo systemctl restart named
+```
+
+## Client configuratie
+We gaan er even van uit dat je gebruik maakt van `NetworkManager` voor jouw netwerk configuratie. Dit kan je dan gebruiken om jouw nieuwe DNS in te stellen op alle hosts.
+
+> Hier gebruik ik de connectie `enp1s0` om de aanpassingen op uit te voeren. Om te weten te komen welke connectie voor jou actief staat, voer dan `ip -br a` uit.
+
+```bash
+sudo nmcli c m enp1s0 ipv4.dns "192.168.124.115"
+sudo nmcli c m enp1s0 ipv4.ignore-auto-dns yes
+sudo systemctl restart NetworkManager
+```
+
+Als dat goed gelukt is, ga je dit IP-adres terugvinden in `/etc/resolv.conf`. Dit is namelijk de plaats waar Linux de DNS server verwacht. Heb je dus geen `NetworkManager`, dan kan je ook hier manueel het IP-adres aanpassen.
+
+## En nu Ansible!
+Omdat we productief lui zijn, doen we dit proces liefst zo automatisch mogelijk. Ik heb daarom dit hele proces ook in een Ansible playbook geschreven. Die kan je dus gewoon gebruiken. Mijn DNS server is een RHEL gebasseerde server. Als je een Debian gebasseerde server gebruikt, ga je mogelijk hinder ervaren. Je gaat nog steeds enkele bestanden moeten voorzien:
+- named.conf
+- Forward lookup bestand
+- reverse lookup bestand
+- resolv.conf
+
+Geef gerust een seintje via [LinkedIn](https://www.linkedin.com/in/eliwinderickx/) als je vast zit met deze bestanden.
+
+```yml
+---
+- name: Install DNS server
+ hosts: dns
+ vars:
+ packages:
+ - bind
+ - bind-utils
+ - firewalld
+ tasks:
+ - name: Install the required software
+ ansible.builtin.dnf:
+ name: "{{ item }}"
+ state: latest
+ loop: "{{ packages }}"
+
+ - name: Enable and start firewall service
+ ansible.builtin.service:
+ name: firewalld
+ state: started
+ enabled: true
+
+ - name: Allow DNS traffic on firewall
+ ansible.posix.firewalld:
+ service: dns
+ state: enabled
+ permanent: true
+ immediate: true
+
+ - name: Configure the BIND service
+ ansible.builtin.copy:
+ src: named.conf
+ dest: /etc/named.conf
+ owner: root
+ group: named
+ mode: 0640
+ notify: restart bind service
+
+ - name: Prepare DNS zone files
+ ansible.builtin.copy:
+ src: "{{ item }}"
+ dest: "/var/named/{{ item }}"
+ owner: root
+ group: named
+ mode: 0644
+ loop:
+ - forward.winderickx.me
+ - reverse.winderickx.me
+ notify: restart bind service
+ handlers:
+ - name: restart bind service
+ ansible.builtin.service:
+ name: named
+ state: restarted
+- name: Configure DNS for hosts
+ hosts: all
+ vars:
+ dns4: 192.168.124.115
+ conn_name: enp1s0
+ tasks:
+ - name: Configure the correct DNS for the server
+ community.general.nmcli:
+ conn_name: "{{ conn_name }}"
+ type: ethernet
+ dns4: "{{ dns4 }}"
+ dns4_ignore_auto: true
+ state: present
+ when: ansible_facts['distribution'] != "Debian"
+ notify: reload NetworkManager
+
+ - name: Configure the correct DNS for debian
+ ansible.builtin.template:
+ src: resolv.conf.j2
+ dest: /etc/resolv.conf
+ owner: root
+ group: root
+ mode: 0644
+ when: ansible_facts['distribution'] == "Debian"
+ handlers:
+ - name: reload NetworkManager
+ ansible.builtin.service:
+ name: NetworkManager
+ state: restarted
+```
+
+## Bonus
+Wil je wel Ansible gebruiken maar geen eigen DNS server? Dan heb je hier een andere playbook die de inventory van jouw Ansible gebruikt om `/etc/hosts` op te vullen. Dit is een heel pak simplistischer dan heel de opzet hierboven maar we moeten bij iedere aanpassing wel deze playbook uitvoeren op ALLE servers in onze inventory en die inventory wordt ineens de `Single Source of Truth`. Hou daar dus zeker rekening mee als je toch voor deze optie gaat!
+
+`dns.yml`
+```yml
+- name: /etc/hosts is up to date
+ hosts: all
+ gather_facts: yes
+ tasks:
+ - name: Deploy /etc/hosts
+ ansible.builtin.template:
+ src: templates/hosts.j2
+ dest: /etc/hosts
+```
+
+`hosts.j2`
+```j2
+{% for host in groups['all'] %}
+{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
+{% endfor %}
+```
\ No newline at end of file
diff --git a/posts/1Aug-Documentatie.md b/posts/1Aug-Documentatie.md
new file mode 100644
index 0000000..e57a062
--- /dev/null
+++ b/posts/1Aug-Documentatie.md
@@ -0,0 +1,60 @@
+---
+title: "Documentatie"
+excerpt: "Documentatie is niet de meest sexy bezigheid maar helpt ons wel om efficient en vlot problemen op te lossen. Waar en hoe je opgaat daarmee bepaalt hoe goed jij je job kan doen."
+date: "2023-08-01T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Documentation_Cover.png
+category: Documentatie,RPM,Linux
+---
+## Problemen?
+Een van de basis eigenschappen van een goede systeembeheerder is veel kennis hebben. Kennis over de systemen waarmee je werkt alsook de software die je wilt gebruiken om problemen te troubleshooten. Het is echter heel moeilijk om alles 100% van buiten te kennen. Beter kan je dus weten waar je bepaalde zaken kan terugvinden. Dat moet natuurlijk vlot gebeuren. Je moet goed vertrouwd zijn met je bronnen om zo snel Problemen te kunnen tackelen. Een Zoekmachine helpt je al goed op weg maar als je onderstaande tools kan gebruiken, zal je veel efficiënter worden in je job.
+
+## `Man`-pages
+De meest gekende documentatie op het toestel zelf, zijn de `man`-pages. Vol met duidelijke informatie over wat een tool doet en welke opties beschikbaar zijn. Bepaalde pagina's zullen ook uitstekende voorbeelden hebben. Die voorbeelden zijn belangrijk om een beter besef te krijgen van wat er gaande is.
+
+Moest je toch nog niet doorhebben je kan man pages uitvoeren met `man` gevolgd door het topic. Een interessante pagina om zo te bekijken is `man selinux`.
+
+### `Apropos`
+Een mooie aanvulling op de `man`-pages is `apropos`. Hiermee kan je eenvoudig zoeken naar inhoud binnen de `man`-pages. Als je dus `apropos selinux` zou ingeven, krijg je alle `man`-pages te zien die te maken hebben met `SELinux`. Handig, toch?
+
+## `Info`
+`Info` is ook een krachtige en misschien minder gekende tool. Wat `info` interessanter maakt is dat de `info` linken binnen pagina's kan volgen als hyperlinks. Verplaats de cursor met de pijltjes en druk op `` om naar de nieuwe pagina te gaan. Je kan die links makkelijk herkennen doordat ze onderlijnd zijn met een cijfer tussen haakjes. Probeer gerust `info selinux` om te vergelijken met de `man`-pages.
+
+## RPM
+Een andere minder gekende manier om documentatie terug te vinden is RPM. RPM heeft een interne database die alle informatie bijhoudt van de pakketten die geïnstalleerd worden. Uiteraard weet RPM welke bestanden waar staan en welke rechten deze bestanden moeten hebben. Maar naast de uitvoerbare bestanden en libraries, wordt er vaak ook documentatie geïnstalleerd. We weten nu ondertussen al dat we documentatie kunnen lezen met `man` en `info`. Als je niets van een bepaalde software kent, kan de volgende truc je op weg helpen om die documentatie uit te spitten.
+
+```bash
+# Zoek met een commando
+rpm -qd
+# zoek met een bestand
+rpm -qdf
+# Als je het pad naar een executable niet weet
+rpm -qdf $(which )
+```
+
+### Waarom met RPM werken?
+Als je met een volledig nieuwe software werkt, is het niet altijd even duidelijk hoe je daaraan moet beginnen of tot waar je best leest om een software te leren kennen. Als je rpm gebruikt om de `man`-pages te zoeken, krijg je in één zicht al een beter beeld over de software. Meestal kan je dan ook meteen kapstokken krijgen met de verschillende bestanden (lees: onderdelen van de software) om jou de juiste kennis en inzicht te geven.
+
+## Markdown
+Het beste wat je echter kan doen is zelf ook documentatie schrijven. Op die manier train je opnieuw de kennis van de verschillende bronnen en kan je zelf de kennis neerschrijven op een manier die je zelf goed begrijpt. Hiervoor is een eenvoudige markup taal bedacht die zelfs als platte tekst goed leesbaar is. Deze blog wordt ook gemaakt met pagina's geschreven in markdown.
+
+```markdown
+---
+metadata:aanwezig
+---
+
+# Titel
+## Eerste hoofdding
+> opmerking
+
+### oplijsting
+- item 1
+- item 2
+
+Deze tekst is **vet**. [Dit is een link](http://hyperlink)
+
+
+| tabel hoofd |
+| --- |
+| data |
+```
\ No newline at end of file
diff --git a/posts/1Jul-SELinuxMetZabbix.md b/posts/1Jul-SELinuxMetZabbix.md
new file mode 100644
index 0000000..e02363e
--- /dev/null
+++ b/posts/1Jul-SELinuxMetZabbix.md
@@ -0,0 +1,66 @@
+---
+title: "SELinux beleid voor Zabbix maken"
+excerpt: 'Standaard is er een SELinux beleid voor de Zabbix server en agent. Bij de Proxy loopt dat soms mis en moeten we zelf een beleid genereren.'
+date: '2023-07-01T18:00:00.000Z'
+author: Eli Winderickx
+hero_image: /SELinuxZabbix_Cover.png
+category: SELinux,Linux,Zabbix,Security
+---
+## Controleren of SELinux blokkeert
+
+SELinux zorgt voor een extra beveiliging op Linux servers. Die beveiliging werkt in bepaalde gevallen beter dan het moet. Het is in die scenario's niet duidelijk of SELinux een blokkerend element is. Hiervoor kan je snel SELinux even op een toegankelijkere stand zetten. Het grote voordeel hiervan is dat er naast het ontbreken van blokkades, er wel wordt bijgehouden wat er geblokkeerd zou worden.
+
+````bash
+# Zet SELinux tijdelijk op permissive
+sudo setenforce 0
+````
+
+Nu kan je in het audit-log controleren welke hits er gemaakt werden:
+
+````bash
+# Audit2why maakt de soms grote blob tekst beter leesbaar.
+sudo cat /var/log/audit/audit.log | audit2why
+````
+
+## Een beleid aanmaken en activeren
+
+Als SELinux ongewenst iets blokkeert, kunnen we daar een module voor aanmaken en soms in heel simpele gevallen, kunnen we een standaard module simpelweg activeren. Deze standaard modules komen mee met de installaties van het softwarepakket.
+
+### Standaard beleid activeren
+
+Als uit het auditlog iets vergelijkbaars met hieronder komt, kan je de lijn die daar vermeldt wordt, simpelweg uitvoeren en dan ben je klaar. Best kan je deze setting dan ook opnemen in een configuratiesysteem om ervoor te zorgen dat als je een gelijkaardige server opzet, dit meteen goed staat.
+
+In onderstaand voorbeeld voeren we dan dit commando uit:
+
+```bash
+sudo setsebool -P zabbix_can_network 1
+```
+
+
+
+### Zelf een beleid maken
+
+In het geval dat er geen standaard beleid beschikbaar is voor het probleem dat je ervaart, gaat je geen oneliner terugkrijgen van SELinux en moet je zelf een beleid genereren. Dat kan je zelf met een aantal stappen. In het audit log kan dan verschillende rechten terugvinden voor bepaalde processen.
+
+
+
+Hier zie je dat ``zabbix_agent_t`` een blokkade krijgt. Dat is niet wenselijk. De eerste stap om hier nu een correct beleid van te maken, is via onderstaand commando waar we alle entries verzamelen die te maken hebben met ``zabbix_agent_t``. Dit wordt dan opgeslagen in ``zabbix_agent.te`` in een heel leesbare vorm. Je zal in het bestand verschillende unieke overeenkomsten terugvinden.
+
+```bash
+sudo ausearch --raw | grep zabbix_agent_t | audit2allow -M zabbix_agent
+```
+
+Als we het ``zabbix_agent.te`` bestand hebben uit het voorgaande proces,kunnen we van het ``.te-bestand`` een ``.mod-bestand`` maken en daarna ook een ``.pp-bestand`` die SELinux kan gebruiken voor de policy te gebruiken. Dat doen we zo:
+
+````bash
+# Eerst het .mod bestand aanmaken
+checkmodule -M -m -o zabbix_agent.mod zabbix_agent.te
+# Daarna het .pp. Dit is de effectieve policy
+semodule_package -o zabbix_agent.pp -m zabbix_agent.mod
+```
+
+Nu staat de policy in het ``.pp-bestand`` en kan je die toepassen zodat deze actief wordt in SELinux.
+
+```bash
+sudo semodule -i zabbix_agent.pp
+```
\ No newline at end of file
diff --git a/posts/21Jul-OpenSSH.md b/posts/21Jul-OpenSSH.md
new file mode 100644
index 0000000..52c6d20
--- /dev/null
+++ b/posts/21Jul-OpenSSH.md
@@ -0,0 +1,89 @@
+---
+title: "Werken met OpenSSH"
+excerpt: 'Verbinden met een Server? Natuurlijk is dat via SSH maar kende je deze trucs al?'
+date: '2023-07-21T21:00:00.000Z'
+author: Eli Winderickx
+hero_image: /SSH_cover.png
+category: OpenSSH,Wish I knew sooner,Configuratie,Expert Tip
+---
+## Waar beginnen we?
+Bij het begin uiteraard! OpenSSH is een fantastische software om op een veilige manier te verbinden met servers. Deze software is vaak beschikbaar op client met Linux, MacOS en zelfs Windows!
+
+> Iedereen die nog Putty gebruikt, let goed op!
+
+Onder `Services.msc` kan je de service OpenSSH openen en aanpassen naar `Automatisch`. Standaard staat deze service uit waardoor het lijkt alsof OpenSSH niet standaard in Windows zit. Als die op automatisch staat, kan je het toestel herstarten en start OpenSSH vanzelf op maar het is logischer om hier gewoon even op `Start` te drukken.
+
+## De configuratie
+OpenSSH gaat altijd configuratie volgen in `~/.ssh/config`. Dat werkt grotendeels hetzelfde voor Linux, MacOS en Windows. Voordat we hier servers in gaan definiëren, kunnen we even stilstaan met naar welke toestellen we gaan verbinden. SSH maakt namelijk ook nog steeds gebruik van DNS. We kunnen dus bijvoorbeeld naar zn1.winderickx.me verbinden door simpelweg `ssh zn1` uit te voeren. Hiervoor moet je wel met een lokale DNS kunnen praten die de vertaling voor jou kan maken. Dat spaart ook weer lijnen uit in onze configuratie. Ofwel kan je in Linux en MacOS een entry aanmaken in `/etc/hosts`. Dit overruled DNS-servers die jouw toestel kent. Ga hier dus voorzichtig mee om!
+
+> In Windows vindt je een `/etc/hosts` achtig bestand onder `C:\Windows\System32\drivers\etc`.
+
+### De basis
+Het is heel simpel om configuratie op te bouwen. Onderstaand voorbeeld verbindt zo naar een server met een bepaalde gebruiker. Het aanmelden specifiek gebeurt met een SSH-key die we hier meegeven.
+
+De private key wordt dankzij `ForwardAgent` ook doorgegeven aan de server. Als je dan naar een nieuwe server verbindt, zal je gebruik kunnen maken van jouw private key zonder dat die op de server komt te staan.
+
+De `AddKeysToAgent` zorgt er verder voor dat je de key niet apart moet toevoegen met `ssh-add` en gaat de key voor een standaard termijn in de agent houden.
+
+Een laatste handige tip is `RemoteForward`. Hiermee kan je bijvoorbeeld ook jouw GPG-key doorsluizen over jouw SSH verbinding. Je gaat dan eerst de `remote socket` meegeven en vervolgens de `local socket`. Voor GPG vind je die configuratie met: `gpgconf --list-dirs agent-socket`
+
+```
+Host zn1
+ Hostname zn1.winderickx.me
+ User ew
+ AddKeysToAgent yes
+ ForwardAgent yes
+ IdentityFile ~/.ssh/id_personal
+ RemoteForward /run/user/1001/gnupg/S.gpg-agent /run/user/1001/gnupg/S.gpg-agent
+```
+
+### Nu wordt het interessant!
+Het is een heel werk als je meer dan 100 servers moet beheren. Je gaat die niet één voor één willen toevoegen aan je SSH configuratie. De meeste van die servers gaan wel een aantal configuratie hebben die overeen zal komen met andere servers. Probeer daar de grootste gemene deler te vinden en maar daar een aparte entry van. Nu gaan we een wildcard gebruiken om een aantal zaken automatisch te laten invullen voor ons. Met onderstaande configuratie kan ik zowel naar zn1.winderickx.me verbinden alsook naar R4nd0ms3rvrr.amazon.com.
+
+```
+Host *
+ User ew
+ AddKeysToAgent yes
+ ForwardAgent yes
+ IdentityFile ~/.ssh/id_personal
+```
+
+Dat werkt goed tot je in meerder omgevingen komt en dus meerdere soorten servers moet verbinden. Het kan zijn dat je per omgeving een andere gebruiker hebt of een andere SSH-key. Zoek opnieuw naar de grootste gemene deler! Hieronder gebruiken we ook de `ProxyJump` configuratie. We gebruiken `srv-jump` als stepping stone voor servers beginnend met `srv-`.
+
+```
+Host *
+ AddKeysToAgent yes
+ ForwardAgent yes
+Host jumpserver
+ Hostname srv-jmp-001
+ User JumpUser
+ IdentityFile ~/.ssh/id_jump
+Host srv-*
+ User admin
+ IdentityFile ~/.ssh/id_admin
+ ProxyJump jumpserver
+Host *.winderickx.me
+ User ew
+ IdentityFile ~/.ssh/id_personal
+```
+
+### Expert tip!
+Zoals met vele zaken kan je die wildcard in de configuratie heel ver gebruiken. Om het dan leesbaar te houden, kunnen we best ook met negaties werken. Zo komen de wildcards pas echt tot hun recht!
+
+```
+Host *
+ AddKeysToAgent yes
+ ForwardAgent yes
+Host !srv-jmp srv*
+ User admin
+ IdentityFile ~/.ssh/id_admin
+ ProxyJump srv-jmp-001
+Host srv-jmp-001
+ user JumpUser
+Host *.winderickx.me
+ User ew
+ IdentityFile ~/.ssh/id_personal
+
+```
+
+Controleer zeker ook `man ssh_config` voor nog meer SSH configuratie goodness!
\ No newline at end of file
diff --git a/posts/22Jul-Permissions.md b/posts/22Jul-Permissions.md
new file mode 100644
index 0000000..ca44b56
--- /dev/null
+++ b/posts/22Jul-Permissions.md
@@ -0,0 +1,78 @@
+---
+title: "Bestands- en mappenrechten"
+excerpt: "Wat eerst begint als een simpel gegeven, verbergt toch een aantal zaken die een zekere complexiteit meebrengen. Sticky bit, SUID, GUID en Umask verklaren we hier."
+date: "2023-07-22T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_permissions.png
+category: Security,Permissies,Expert Tip
+---
+## De basis
+Rechten binnen Linux worden gemakkelijk als een numerieke waarde voorgesteld en werken met een groepering van drie verzamelingen aan rechten. Die drie zijn:
+- Eigenaar (Owner)
+- Groep (Group)
+- Anderen (Other)
+
+Een voorbeeld van die rechten is dan `0775`. De eerste `0` overlopen we later. Daarna volgt het cijfer voor Eigenaar, Groep en tot slot Anderen. Ook de vertaling van die drie laatste cijfers is vrij eenvoudig te vertalen als we het cijfer omzetten naar bit waarde. Voor het cijfer `7` is dat `111`
+
+1 = 4 -> Lezen (Read)\
+1 = 2 -> Aanpassen (Write)\
+1 = 1 -> Uitvoeren (Execute)
+
+## Standaard rechten
+In Linux worden er standaard rechten voorzien. Voor mappen is `777` en bestanden `666`. Die Uitvoeren-rechten zijn nodig op mappen om te kunnen zien wat de inhoud is van die map. Voor bestanden is het niet veilig om standaard uitvoer-rechten te geven.
+
+Als jij nu een nieuw bestand aanmaakt met `touch bestand` of je maakt een nieuwe map aan met `mkdir map` en je controleert de rechten met `ls -l`, `stat map` of `stat bestand`, zal je merken dat deze niet de standaard rechten krijgt. De reden daarvoor is dat er bovenop de standaard rechten nog een extra systeem zit die rechten afneemt; `umask`
+
+### Umask
+Het `umask` commando komt standaard met de shell meegeleverd zoals `cd`, `export` of `history`. Als je een `man umask` uitvoert in verschillende shells, krijg je dan ook verschillende pagina's te zien. In mijn mening is de `man`-pagina over umask binnen bash niet duidelijk maar als je binnen `fish` de `man`-pagina opvraagt, krijg je veel duidelijkere uitleg. Hier overlopen we het even.
+
+Je kan `umask` zonder extra parameters uitvoeren om de ingestelde waarde terug te krijgen. In mijn geval is dat `0022`. Deze cijfers worden bit-gewijs afgetrokken van de standaard rechten. Voor mappen wordt dat dan `0755` en voor bestanden `0644`. Wil je dit leesbaarder zien kan je de `-S` flag meegeven en dan krijg je te zien welke rechten maximaal bewaard worden.
+```
+u=rwx,g=rx,o=rx
+```
+
+We kunnen dit niveau verhoren of verlagen door ofwel in cijfer of letter waarde het rechten niveau mee te geven aan het `umask`-commando. Hieronder geven we aan dat de standaard rechten mogen gebruikt worden.
+
+```
+umask 0000
+# Ofwel
+umask u=rwx,g=rwx,o=rwx
+```
+
+## Het eerste cijfer
+Vooraan de rechten zie je vaak een `0` terugkomen. Dit is niet per ongeluk. Deze gaat een extra instelling bewaren voor ons, namelijk of we een `Set User ID`, `Set Group ID` of een `Sticky bit` hebben ingesteld. Ook dit cijfer kan binair opgebouwd worden;
+1 = 4 -> SUID\
+1 = 2 -> SGID\
+1 = 1 -> Sticky bit
+
+> Een ander ezelbruggetje voor de `s` is speciaal
+
+### Set User ID
+Deze waarde is enkel relevant als je dit toepast op een bestand en specifiek een uitvoerbaar bestand. Hiermee gaat het namelijk lijken alsof de eigenaar het bestand uitvoert, ook al doet een andere gebruiker dat. Dit vooral handig voor commando's zoals `passwd` waar iedereen `/etc/shadow` moet kunnen manipuleren op een veilige manier. Dit kan je toepassen door:
+```
+chmod 4774 script.sh # In cijfers moeten we de volledige rechtenreeks steeds meegeven
+# Ofwel
+chmod u+s script.sh
+```
+
+### Set Group ID
+De `SGID` kan je instellen op zowel mappen als bestanden. Toegepast op een map krijgen nieuwe items onder die map automatisch de groep van de parent map mee. Bijvoorbeeld hebben we de map `accounting` waar ook een groep `accounting` is ingesteld. Hier kunnen we de `SGID` instellen met:
+```
+chmod 2775 accounting
+# Ofwel
+chmod g+s accounting
+```
+
+Als gebruiker `milly` hieronder een nieuwe map aanmaken, gaat deze ook de group `accounting` krijgen en niet `milly` wat standaard het geval is. Zo kan iedereen binnen de `accounting` group genieten van `milly`'s nieuwe map.
+
+Daarnaast kunnen we de `SGID` ook instellen op een bestand. Wordt dat bestand uitgevoerd, dan zal dat met de rechten van die groep gedaan worden. Gelijkaardig aan de `SUID` instelling
+
+### Sticky bit
+Nog zo'n vreemde vogel is de `Sticky bit`. Als we deze instellen op een map kunnen nieuwe items daaronder enkel verwijderd of aangepast worden door de eigenaar of root. Is een andere gebruiker lid van eenzelfde groep die ingesteld is op zo'n item onder die map, dan kan die dat niet aanpassen of verwijderen.
+
+In te stellen met:
+```
+chmod 1775 map
+# Ofwel
+chmod o+t map
+```
\ No newline at end of file
diff --git a/posts/23Aug-Git_masterclass.md b/posts/23Aug-Git_masterclass.md
new file mode 100644
index 0000000..02973e9
--- /dev/null
+++ b/posts/23Aug-Git_masterclass.md
@@ -0,0 +1,220 @@
+---
+title: "Git: Masterclass"
+excerpt: "Ben je een ontwikkelaar of werk je als systeembeheerder in de IT? Iedereen komt tegenwoordig in contact met git. Zorg dus dat jij goed git kan!"
+date: "2023-08-23T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Git_Masterclass_Cover.png
+category: Git,Linux
+---
+## Wat is `git`?
+### Waarom werken met `git`?
+Git is een versiecontrole systeem uitgevonden door [Linus Torvalds](https://linuxtorvalds.com/). Hij had een betere manier nodig waarmee er samen gewerkt kon worden aan een project. Zo'n samenwerking gaat vaak heel goed tot het misloopt en dan draait het helemaal de soep in. Vooral in ontwikkeling waar ontwikkelaars elkaar zelden in het echt zien en iedereen aan eigen stukjes code werkt. Soms overlappen die aanpassingen en doen die andere wijzigingen te niet. Dergelijke conflicten kunnen met git elegant opgelost worden.
+
+Daarnaast wordt er van alles een checksum bijgehouden. Een cryptografische berekening van ieder bestand die altijd hetzelfde moet zijn. Dit biedt als voordeel dat `git` steeds de integriteit van de bestanden kan garanderen.
+
+Tot slot werkt `git` volledig op jouw toestel. Je kan alles op jouw toestel aanpassen, opslaan en dan "comitten". Ben jij klaar met werken of wil je een tussentijdse backup maken, kan je jouw opgeslagen wijzigingen meteen "pushen" naar een andere `repository`. Dat kan een service zijn zoals [Gitlab](https://gitlab.com) maar ook gerust een andere computer, server en dergelijke.
+
+### Wat met tools Gitlab, Github en Bitbucket?
+Deze webapplicaties werken onderliggend met `git`. Ze bieden eigenlijk een `repository` aan waar individuen, groepen of organisaties hun code op een stukje van de server beschikbaar kunnen maken aan iedereen die zij zelf kiezen. Daarrond hebben ze dan een grafische omgeving gebouwd waar je tegenwoordig ook extra features kan genieten. De meeste tools bieden ook een issue tracking aan of mijlpalen om vooruitgang in een project bij te houden. Sommige tools bieden ook tools aan om applicaties automatisch uit te rollen zodat ontwikkeling, testing en tot slot uitrol naar productie heel vlot kan gebeuren. Waar het echt gek wordt is als je een volledige Web IDE kan gebruiken om vanop ieder toestel aanpassingen te kunnen doen aan jouw code.
+
+## De basis
+### Hoe werk je met `git`?
+Als `git` geïnstalleerd is op jouw toestel kan je meteen van start gaan. Anders moet je het nog even installeren. Op `RedHat`, `Fedora` en aanverwanten, kan je `git` installeren door middel van dnf (`dnf install git`). Voor Windows kan je best [een installer downloaden](https://git-scm.com/download/win) en op MacOS gebruik je best [Homebrew](https://brew.sh/) (`brew install git`).
+
+Met `git` in jouw `PATH` na installatie (Dat gebeurt normaal automatisch), kan je een nieuwe repo starten door in de terminal naar een map te gaan en daar volgende in te typen:
+```bash
+git init
+```
+
+Er is nu een map aangemaakt in jouw map genaamd `.git`. Deze zal alle wijzigingen bijhouden. Verwijder deze niet en best doe je ook geen aanpassingen in deze map. Daarvoor gaan we commando's gebruiken.
+
+`Git` werkt met branches. Standaard start je met de `master`-branch. Die naam is niet altijd interessant dus die gaan we meteen hernoemen naar iets passelijker en inclusiever; `main`
+
+```bash
+git branch -m main
+```
+
+### Configuratie
+Voor we echt wijzigingen gaan doen is het goed om even stil te staan bij de configuratie. `Git` is zo'n sterke tool omdat je duidelijk kan maken wie welke wijzigingen gemaakt heeft. Dit zorgt voor een betere opvolging en kan dus ook zorgen voor een betere projectwerking. Om aan te geven wie jij bent, kan je dat meegeven aan git.
+
+```bash
+# Geef jouw Naam en e-mailadres op.
+# Dit moet je maar eenmalig doen door de --global flag
+git config --global user.name "Jouw Naam"
+git config --global user.email "jouw@email-adr.es"
+```
+
+> Je kan jouw code ook automatisch laten `signen` met GPG. Door zo'n digitale handtekening weet iedereen zeker dat deze wijziging effectief van jou komt en niet iemand anders dat in jouw naam gedaan heeft. Dit kan je zo activeren:
+
+```bash
+# Maak een GPG-key aan als je deze nog niet hebt.
+# Na onderstaand commando moet je een paar vragen beantwoorden.
+gpg --gen-key
+# Zoek dan de key id. Die staat op de pub regel
+# achter de eerste /
+gpg --list-keys
+# Daarna kan je jouw key doorgeven aan git
+git config --global user.signingkey
+# In plaats van --global kan je ook enkel voor dit project signing gebruiken
+git config --local commit.gpgsign true
+```
+
+### Sla je werk op!
+Nu moeten we een eerste bestand toevoegen vooraleer we echt met `git` kunnen werken. Kies hier voor een `README`-bestand. Dit wordt door `git` en vooral de `git`-tools automatisch opgepikt zodat je hier eenvoudig een korte omschrijving van jouw project kan geven. Vaak wordt hier ook instructies gelaten over hoe het project gebruikt moet worden of hoe een installatie werkt. Als we het bestand hebben aangemaakt en aangevuld, kunnen we het toevoegen aan `git` en kunnen we onze eerste `commit` maken om zo ons `git`-avontuur echt te starten. Met de `add` brengen we het bestand in de radar van `git` en met de `commit` maken we de checksum aan. Git kan nu perfect zien welke bestanden aangepast zijn. Probeer met de commit altijd kort en bondig aan te geven welke wijzigingen je gemaakt hebt door middel van de `-m` flag. Dat helpt achteraf met problemen oplossen.
+
+```bash
+# Maak eerst het bestand aan.
+touch README
+# Vul dat nu met gegevens dmv onze favoriete editor
+# Denk eraan dat je met :wq er uit kan door op te slaan
+nvim README
+# Nu voegen we het bestand toe aan git.
+git add README
+# En tot slot een commit
+git commit -m "Eerste commit met README"
+```
+
+> Als er bestanden of mappne zijn die niet opgenomen mogen worden in git, kan je die best zo vroeg mogelijk uit git houden. Dit doe je door het pad of bestandsnaam in `.gitignore` toe te voegen. Dit bestand ga je uiteraard wel toevoegen aan jouw git repo.
+
+Het is de bedoeling dat productie gegevens steeds in de `main`-branch zullen zitten. Niemand zou rechstreeks aanpassingen hierin mogen doen buiten de initiële `commit`. In de plaats daarvan maakt iedereen een eigen branch aan. Hierin kan je dan aanpassingen doorvoeren, testen en als het goed bevonden is voeren we daarna de wijzigingen door naar de main branch. Dat gaat als volgt:
+```bash
+# Maak een nieuwe branch aan
+git branch newfeature
+# Maak een nieuw bestand aan en vul aan.
+nvim myWebApp.js
+# Nu voegen we het bestand toe aan git...
+git add myWebApp.js
+# en committen we de wijziging.
+git commit -m "myWebApp.js toegevoegd"
+```
+
+### Nog enkele belangrijke bestanden
+Naast het `README` bestand, zijn er nog enkele speciale bestanden waarvan je best op de hoogte bent. Niet alle projecten doen alle bestanden. Velen hebben meteen alle informatie in hun `README` staan. Hieronder vind je de meest belangrijke bestanden.
+- README: De basis info van een project. Vaak ook hoe je het project kan gebruiken of in gebruik kan nemen. Online tools gaan de `Markdown` in deze bestanden automatisch tonen.
+- LICENSE: Dit gaat over de rechten, ristricties en juridische fancy talk betreffende het project.
+- CHANGELOG: Optioneel kan je hier in grote versienummers bijhouden welke grote veranderingen er zijn gebeurt.
+- AUTHORS: De belangrijkste mensen die meewerken aan jouw project kan je hier extra in de kijker zetten. Vaak worden hier de medewerkers in loondienst ook toegevoegd.
+- SUPPORT: Als iemand een issue in Gitlab of Github wilt aanmaken, kan je hier instructies meegeven over waar ze zeker rekening moeten houden alvorens hun issue in te sturen.
+- SECURITY: Voornamelijk als er een kwetsbaarheid gevonden wordt, geef je hier aan hoe gebruikers dat best aan jou doorgeven. Daarnaast kan je ook versies van verschillende onderdelen hier uitschrijven.
+- CODE_OF_CONDUCT: In de laatste jaren is dat vooral populair geworden. Je moet namelijk niet alleen samenwerken maar ook op een respectvolle manier. Maak in dit document duidelijk wat dat voor jouw project betekent.
+- CONTRIBUTING: Als iemand nieuw wilt starten aan jouw project, vindt die hier hoe die kan helpen.
+- ACKNOWLEDGEMENTS: Refereer hierin naar andere projecten die relevant zijn voor jouw project om die ook even extra in de kijker te zetten.
+- CODEOWNERS: Wie heeft eigendom over de code
+- FUNDING.yml: Hoe kunnen gebruikers jou financieel steunen
+- ISSUE_TEMPLATE: Een template om een issue aan te maken.
+- PULL_REQUEST_TEMPLATE: Een template om een `merge` aan te vragen
+
+### Hoe krijg ik mijn project nu gedeeld?
+Als je een project aanmaakt in een online tool zoals Gitlab of Github, krijg je de vraag om ook het project te initialiseren. Doe dat enkel als je nog geen lokaal project hebt. Anders hou je het project best leeg. Hierna ga je ongetwijfeld ook de instructies van die site krijgen over hoe je jouw wijzigingen online krijgt. In grote lijnen is dat meestal zo:
+```bash
+# Je gaat de externe locatie definiëren
+git remote add origin git@gitlab.com:eliwinderickx/backuptest.git
+# Bij iedere eerste push per branch ga je misschien
+# moeten meegeven naar waar de push moet gebeuren
+git push --set-upstream origin main
+# Daarna kan je na iedere commit een push doen
+# om de commit ook online beschikbaar te maken.
+git push
+```
+
+### Wat ben ik nu aan het doen?
+Je kan op ieder moment de status opvragen om zo te zien welke bestanden je hebt toegevoegd aan `git`, welke je hebt aangepast of misschien zelfs verwijderd. Als je `commit` hebt, kan je ook zien dat je op een propere branch aan het werken bent. Dat wil zeggen dat binnen jouw lokale `git`-repo alles veilig opgeslagen is.
+
+> Commit wilt niet zeggen dat je wijzigingen opgeslagen zijn in een externe `git`-repo zoals Gitlab of Github.
+
+De status vraag je zo op:
+```bash
+git status
+```
+
+Naast de status van de huidige branch, kan je ook een oplijsting vragen van alle branches die je lokaal beschikbaar hebt.
+```bash
+git branch --list
+# Wil je dat visueler zien met welke branch van waar komt?
+git log --all --graph --decorate --oneline --simplify-by-decoration
+```
+
+
+
+> Nog een leuke feature is zien wie de laatste commits in een bestand gedaan heeft `git blame `
+
+
+### Ik ben klaar, wat nu?
+Stel de feature waaraan je gewerkt hebt is klaar. Je hebt een hele reeks nieuwe aanpassingen gemaakt, alles is getest en nu wil je jouw wijzigingen naar productie brengen. Dat doe je door die wijzigingen naar de hoofd branch te brengen. In ons verhaal hierboven hebben we die `main` genoemd. Om die wijzigingen nu naar de `main`-branch te krijgen moeten we een `merge` doen. In tools zoals Github of Gitlab kunnen we een `merge request` maken. Dit nodigd dan andere gebruikers uit om de nieuwe wijzigingen te controleren en zelf ook uit te testen alvorens dit naar de productie branch gaat. Binnen de `git`-applicatie kunnen we ook verscheidene soorten `merge`'s doen. Hier houden we het voorlopig nog even simpel.
+
+```bash
+# Eerst gaan we naar de branch die de wijzigingen moet ontvangen
+git checkout main
+# Daarna kunnen we de wijzigingen binnenhalen.
+git merge newfeature
+```
+
+De wijzigingen zitten nu zowel in de `main` als in de `newfeature` branch. Afhankelijk van hoe je met het project omgaat, ga je misschien nu de `newfeature` branch willen verwijderen. In sommige projecten moet er per unieke feature een aparte branch gemaakt worden. Deze wordt dan na succesvol toevoegen van die feature verwijderd. Grotere projecten kunnen ervoor kiezen om onder de `main` branch ook nog type wijzigingen als branch te vertegenwoordigen; Taal, GUI en gelijkaardige grotere branches zullen niet verwijderd worden na de merge. Hierbinnen wordt verder gewerkt aan de volgende features.
+
+```bash
+# Om een branch te verwijderen, kan je zo doen
+git branch -d newFeature
+```
+
+## Samenwerken is niet zonder problemen
+### Iemand anders brengt wijzigingen naar productie
+Jij bent nog aan het werken aan features in jouw eigen branch maar ondertussen heeft iemand anders al wijzigingen gemerged met de `main` branch. Om problemen te vermijden, kan je nu best een `rebase` doen. Dit vertaalt bij letterlijk naar vervang de basis van waar ik gestart ben door wat er in een andere branch zit. Daarbovenop kunnen we dan onze wijzigingen doen.
+
+> Als je hier wilt meevolgen, maak dan even een nieuwe branch aangenaamt `newFeature2`. Daarna kan je in jouw `main`-branch een nieuw bestand aanmaken en een commit uitvoeren.
+
+```bash
+# Ga naar de branch die de wijzigingen moet ontvangen
+git checkout newFeature2
+# Hier ontvangen we de nieuwe basis vanuit main
+git rebase main
+```
+
+> Bovenstaande lukt enkel als de wijzigingen in andere bestanden gebeuren. Als je dezelfde bestanden wijzigd, kom je in het vaarwater van de `stash` en het `merge conflict`.
+
+### De `stash`
+Wil je een rebase doen maar ben je indezelfde bestanden aan het werken? Dan kan je een `stash` doen. Hiermee zet je jouw wijzigingen even aan de kant om de nieuwe code of wijzigingen binnen te halen. Als dat gedaan is kan je jouw wijzigingen terughalen.
+
+```bash
+# zet jouw wijzigingen even aan de kant.
+# Je draait zo even alle wijzigingen terug tot de laatste commit
+git stash
+# Nu kan je de rebase doen
+git rebase main
+# Tot slot kan je jouw wijzigingen uit stash halen
+# en opnieuw uitvoeren
+git stash apply
+```
+
+
+### Het merge conflict
+Als je bestanden aan het wijzigen was die achter jouw rug ook al gewijzigd waren, krijg je een merge conflict. `Git` kan namelijk niet in jouw plaats kiezen welke wijziging belangrijker is dan de andere. Jij gaat nu die keuze moeten maken om dit op te lossen. Voortbouwend op het scenario bij `stash` hebben we net onze stash opnieuw toegepast. We waren helaas aanpassingen aan het doen in een bestand dat in een eerdere merge in de `main` branch ook al wijzigingen kreeg. We hebben nu een `merge conflict`. Dit merken we door twee zaken:
+- de output van ons laatste commando geeft het ons mee: `CONFLICT (content): Merge conflict in ` alsook
+- in het bestand zelf. Hieronder een voorbeeld van hoe zo'n bestand eruit kan zien.
+
+```
+Oorspronkelijke code
+
+
+```
+
+
+
+
+
+De gemakkelijkste manier van werken is nu beide blokken code lezen:
+- vanaf <<<<<<< tot =======
+- vanaf ======= tot >>>>>>>
+
+Hierna kan je dan beide blokken vervangen door één blok die ofwel beide codes zal bevatten of misschien bepaalde stukken zal aanpassen. Dit zal afhangen van zowel de code die er stond alsook de code die jij aan het schrijven was.
+
+
+
+Achteraf moet je het bestand opnieuw toevoegen aan git en kan je een commit uitvoeren om de merge helemaal rond te krijgen.
+```bash
+git add
+git commit -m "Conflict opgelost!"
+```
+
+## Proficiat!
+
+Als je goed meegevolgd hebt, snap je nu hoe git werkt. Er zijn nog scenario's die we niet overlopen hebben. Die komen vaak minder voor maar kan je zeker wel terugvinden in [de officiele Git documentatie](https://git-scm.com/docs/). Lees die dus zeker na voor je problemen hebt!
diff --git a/posts/23Okt-Autofs.md b/posts/23Okt-Autofs.md
new file mode 100644
index 0000000..5b36641
--- /dev/null
+++ b/posts/23Okt-Autofs.md
@@ -0,0 +1,79 @@
+---
+title: "Automatisch NFS shares mappen"
+excerpt: 'NFS shares zijn handig en als die automatisch gemapped worden is dat nog veel handiger!'
+coverImage: '/AutoFS/cover_AutoFS.png'
+date: '2023-10-13T20:00:00.000Z'
+author: Eli Winderickx
+hero_image: /cover_AutoFS.png
+category: Linux,NFS,Configuratie,Expert Tip
+---
+## Waarom `AutoFS` gebruiken?
+Soms wil je mappen of bestanden beschikbaar maken naar meerdere toestellen. Een handige manier om dat te doen is via NFS(Network File System). Dit procotol bestaat al even en ondertussen zitten we aan versie 4 in het gebruik hiervan. In grote lijnen is het heel simpel om een NFS share te delen over het netwerk:
+- Maak een map aan die je wilt delen
+- Zorg dat NFS geïnstalleerd is (`nfs-utils`) en activeeer de service (`systemctl enable --now nfs-server`)
+- Vul de te delen map in `/etc/exports` (`/pad/naar/map ()`)
+- activeer de NFS configuratie (`exportfs -arv`)
+
+> De toegestane IP-range kan ook een IP-adres zijn maar vaak wil je meerdere toestellen toegang geven. vb 192.168.64.0/24. De opties
+
+Daarna kunnen we de map mounten. Dat proces is, net als een andere mount, vaak gebonden aan een admin gebruiker. Niet erg handig als de NFS map als home folder moet dienen. Daarnaast willen we ook niet dat als een gebruiker zich afmeld, dat de home folder (die zich op een ander toestel bevindt) nog steeds beschikbaar is.
+
+Je voelt het al aankomen maar dit zijn enkele voordelen van AutoFS. Als onze share goed opgebouwd is, kunnen we verschillende gebruikers laten aanmelden en worden hun homedrives automatisch gekoppeld aan de juiste NFS-share. Als ze afmelden, worden de verbindingen automatisch verbroken. De grote voordelen zijn dus:
+- NFS shares zijn niet permanent verbonden. Verbindingen worden automatisch verbroken.
+- AutoFS wordt geconfigureerd op de client. Op serverzijde is er niets nodig.
+- NFS shares zijn beshikbaar voor alle gebruikers, gegeven dat de rechten op de share dat toestaan.
+
+## Configuratie: direct share
+Eerst moeten we autofs installeren. In RHEL en afgeleiden kunnen we dat met:
+```bash
+sudo dnf install -y autofs
+```
+
+> Als je dit nog niet gedaan hebt, moet je op je NFS-server ook firewall regels toestaan. In principe is de `nfs` service voldoende. De anderen gaan ons vooral helpen in de verbindingen testen.
+
+```bash
+sudo firewall-cmd --add-service={nfs,mountd,rpc-bind} --permanent
+sudo firewall-cmd --reload
+```
+
+Nu kunnen we de configuratie terugvinden in `/etc/auto.master` maar wij maken onze aanpassingen in een nieuw bestand onder `/etc/auto.master.d/`. De naam van dat bestand maakt niet uit. Maak er iets beduidend van. Laat de naam verder ook eindigen op `.autofs`. Zo zal het systeem de configuratie goed oppikken.
+
+Voor we dit nu helemaal gaan opzetten, kunnen we best eerst manueel onze NFS share testen;
+```bash
+showmount -e
+sudo mount -t nfs4 :/map/naar/share /map/naar/mountpoint
+sudo umount /map/naar/mountpoint
+```
+
+In ons configuratie bestand onder `/etc/auto.master.d/` kunnen we nu de autofs configuratie gaan opzetten. Als voorbeeld neem ik het bestand `/etc/auto.master.d/temp.autofs`. Hierin zetten we het pad naar de map waarin onze share gemount zal worden. Voor de map `/home/bob` gaan we dus `/home` invullen. Als we in root willen mappen, moeten we `/-` invullen. Daarachter gaan we nu het pad naar een ander bestand opgeven waarin we onze configuratie gaan invullen. In mijn geval heb ik gekozen voor `/etc/share.misc` maar de naamgeving maakt helemaal niet uit.
+
+`/etc/auto.master.d/temp.autofs`
+```
+/home /etc/share.misc
+```
+
+`/etc/share.misc`
+```
+bob -rw,soft,intr :/map/naar/share
+```
+
+Als we nu de `autofs` service starten, kunnen we meteen naar onze map gaan en de inhoud van de share te zien krijgen. Leuk maar nog niet erg handig als we homedrives daar willen plaatsen.
+
+## Configuratie: indirect share
+Om nu variabel een share te kunnen mappen, moeten we de configuratie verder tweaken. We willen namelijk een indirect share mappen in plaats van een direct share.
+
+Op de NFS server zorgen we eerst dat er mappen zijn voor onze gebruikers.
+
+```bash
+mkdir -p /media/share/bob /media/share/
+```
+
+> Zorg dat de users op beide servers dezelfde User ID hebben. Dat maakt het rechten beheer een pak makkelijker.
+
+Nu gaan we de `/etc/share.misc` verder aanpassen. Het mountpoint `bob` vervangen we nu met een wildcard: `*`. Ook achteraan de share gaan we een `&` invullen. Hier wordt de naam van de map automatisch ingevuld. We hebben dus nog steeds de mountpoint `/home/bob` die verwijst naar `bob` map in de NFS share. Ook ga je gemerkt hebben dat we hier de opties verwijderd hebben. Als je deze laat staan, werkt het niet meer.
+
+```
+* :/map/naar/share/&
+```
+
+Weer een mysterie minder!
\ No newline at end of file
diff --git a/posts/24Jul-SyncRepo.md b/posts/24Jul-SyncRepo.md
new file mode 100644
index 0000000..0d11fd7
--- /dev/null
+++ b/posts/24Jul-SyncRepo.md
@@ -0,0 +1,85 @@
+---
+title: "Synchroniseer een bestaande RPM repo"
+excerpt: "RPM repo's zorgen ervoor dat we software op RHEL gebasseerde systemen kunnen installeren. Uit veiligheidsredenen kan het interessant zijn om een volledige kopie van zo'n repo te hebben."
+coverImage: "/SyncRPM/SyncRPM-cover.png"
+date: "2023-07-24T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /SyncRPM-cover.png
+category: RPM,Repos,Expert Tip
+---
+## De basis
+RPM-bestanden bevatten alle bestanden die geïnstalleerd moeten worden alsook de permissies, eigenaren en groepen die op alle bestanden toegepast worden. Daarnaast ook welke vereisten de software heeft maar ook welke conflicterende pakketten eventueel bestaan. Dit is jarenlang een heel eenvoudige manier geweest om pakketten te installeren. Een grote tekortkoming aan RPM is dat het niet automatisch vereisten en updates kan doen. Dat moet dan manueel door andere RPM-bestanden te downloaden en die dan eerst te installeren. Als die dan opnieuw vereisten hebben, voel je al aankomen dat dit niet praktisch is.
+
+DNF (oftewel `DaNdiFied Yellowdog Updater Modified`) is een repo-gebasseerde packagemanager. Deze kan wel doen wat we ontbreken in RPM. Door middel van repo's gedefinieerd in `/etc/yum.repos.d/` weet DNF waar software beschikbaar is voor ons toestel en welke versie van die software geïnstalleerd moet worden. Zo'n repo bevat simpelweg een oplijsting met alle beschikbare RPM-bestanden en daarnaast de metadata van die pakketten. Als we zo'n repo willen gebruiken, kunnen we een repo-bestand aanmaken in `/etc/yum.repos.d`. Hieronder een bestaand voorbeeld:
+
+```
+[satellite-client-6-for-rhel-9-x86_64-eus-rpms]
+name = Red Hat Satellite Client 6 for RHEL 9 x86_64 - Extended Update Support (RPMs)
+baseurl = https://cdn.redhat.com/content/eus/rhel9/$releasever/x86_64/sat-client/6/os
+enabled = 0
+gpgcheck = 1
+gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
+sslverify = 1
+sslcacert = /etc/rhsm/ca/redhat-uep.pem
+sslclientkey = /etc/pki/entitlement/6563172807305005622-key.pem
+sslclientcert = /etc/pki/entitlement/6563172807305005622.pem
+sslverifystatus = 1
+metadata_expire = 86400
+enabled_metadata = 0
+```
+
+Hierin staat de naam, waar de software beschikbaar is, of we de repo willen gebruiken en verschillende manieren om de integriteit van het pakket te vrijwaren. Vooral de baseurl is hier interessant. We kunnen hier in principe alles opgeven wat we willen; een webadres, FTP-locatie of zelfs een simpele map op de server.
+
+### Een repo aanmaken
+Een volgende stap zou nu kunnen zijn dat we RPM-pakketten downloaden, in een map zetten en onze eigen repo opzetten. Dat gaat heel eenvoudig
+```
+sudo dnf install -y createrepo
+mkdir -p /var/tmp/repos/
+curl https://link/to/software.rpm -o /var/tmp/repos//.rpm
+createrepo /var/tmp/repos/
+```
+
+Vanaf nu kunnen we een extra repo bestand aanmaken waar de baseurl naar een map verwijst.
+> Probeer ook steeds de GPG-key beschikbaar te stellen. Deze gaat meestal naast het RPM-bestand te downloaden zijn. Dit zal er voor zorgen dat de integriteit van het pakket correct blijft.
+
+```
+[local-slack-repo]
+name=Local Slack Repository
+baseurl=file:///var/tmp/repos/slack
+enabled=1
+gpgcheck=1
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-SLACK
+```
+
+Als we dan info opvragen van de software, zien we alle relevante informatie maar ook dat deze van onze lokale repo afkomstig is. Hier heb je zo'n voorbeeld van:
+
+
+Handig om te weten maar opnieuw niet handig als we honderden softwarepakketten hebben. Gelukkig kunnen we bestaande repo's ook volledig synchroniseren.
+
+### Synchroniseren van bestaande repo's
+Zorg er eerst voor dat je alleen de repo's activeert die je nodig hebt. Alle andere deactiveer je best. Ofwel door `enabled=0` te zetten in het repo bestand ofwel met `sudo subscription-manager repos --disable="*"` uit te voeren. Met `sudo dnf repolist` kan je dan controleren of je een juiste subset hebt.
+
+Als `dnf-utils` op het toestel staat, kan je meteen verder anders even installeren:
+
+```
+sudo dnf install yum-utils
+# Ofwel
+sudo dnf install dnf-utils
+```
+
+Daarna kunnen we met `reposync` een kopie maken van alle beschikbare software pakketten. Met onderstaand commando downloaden we alleen de laatste versie. Daarnaast downloaden we de metadata. Doen we dat niet moeten we zelf een `createrepo` op de map uitvoeren. Tot slot slaan we de bestanden op in een logische map. In dit geval `/var/tmp/repos`.
+```
+reposync --newest-only --download-metadata --destdir /var/tmp/repos
+```
+
+Dit commando kan je gerust in een cronjob of Systemd timer zetten om regelmatig uit te voeren. Zo blijven jouw pakketten ook up to date en kan je telkens de laatste versie aanbieden.
+
+Om nu deze pakketten beschikbaar te maken naar andere servers, kan je best een webserver opzetten. Dit gaat de eenvoudigste methode zijn en kan je verder ook eenvoudig beveiligen met een SSL verbinding. Dat is een handleiding op zichzelf maar de korte versie is:
+- Installeer nginx (of httpd)
+- Maak een entry aan voor de website in `/etc/nginx/conf.d/`
+- Pas de document root aan naar `/var/tmp/repos` of de andere map die je gekozen hebt.
+- Zorg dat de nginx user en groep ingesteld staat voor de repo-map
+- Geef SELinux aan dat HTTP-verkeer ok is (`sudo chcon -R -t httpd_sys_content_t /var/www/html/local_repo`)
+- Beveilig de 'site' met SSL
+
+Veel succes!
\ No newline at end of file
diff --git a/posts/24Jun-zabbix-prom.md b/posts/24Jun-zabbix-prom.md
new file mode 100644
index 0000000..9f843b9
--- /dev/null
+++ b/posts/24Jun-zabbix-prom.md
@@ -0,0 +1,78 @@
+---
+title: "Prometheus en Zabbix"
+excerpt: 'Leer Prometheus data op te halen vanuit de Zabbix server.'
+coverImage: '/ZabbixProm/ZabbixProm1.png'
+date: '2023-06-24T18:00:00.000Z'
+author: Eli Winderickx
+hero_image: /ZabbixProm1.png
+category: Prometheus,Zabbix,Node exporter,Low-level Discovery
+---
+
+Zabbix kan heel veel, ook verbinden met de Prometheus clients; `node_exporter` en `blackbox_exporter`. Beide clients bieden namelijk via TCP-poort data aan die Prometheus kan "scrapen" (`node_exporter`: 9100 en blackbox_exporter: 9115). Zabbix kan dan via `HTTP-item` de metrics ophalen. Hiervoor moeten we eerst een Host aanmaken. Deze dient als placeholder en moet buiten een beduidende naam, geen relevante informatie bevatten.
+
+## Het master-item
+Het belangrijkste zit in de master-item. Deze gaat namelijk via een `HTTP-item` de pull doen naar de `node_exporter` host. Net als bij de Prometheus server krijgen we ineens alle data binnen van de host. Zabbix kan daarna extra `Dependant items` maken op basis van verschillende entries in het `master`-item. Geef het adres van de host in onder URL en vervolledig met `:9100/metrics`. Voor testdoeleinden kan het interessant zijn om even geschiedenis bij te houden maar daarnaast is dit heel veel data die we niet moeten bijhouden en dus kunnen we onder `history storage period` 0 zetten. Let daarnaast dat `Type of information` Text is.
+
+
+
+## Dependant item
+Nu het `master`-item aangevuld wordt, kunnen we een nieuw item aanmaken en die van het type `Dependant item` maken. De naam en key moeten zoals steeds uniek zijn en onder `master`-item kunnen we het item van zonet hier aanvullen.
+
+
+
+Onder het tab `Preprocessing` gebeurt nu het interessante en gaan we aangeven welke waarde we uit ons Master-item willen halen. In deze context kunnen we enkel gebruik maken van `keys` en `values` en hebben we dus echt enkel de specifieke metrix die we ophalen.
+
+
+
+## Low-level Discovery
+Via LLD kunnen we iets gemakkelijker verschillende items op een geautomatiseerde manier ophalen. We hebben nog steeds ons `master`-item nodig als vertrekpunt. Hierna kunnen we enkele leuke zaken definiëren. Nadat we Naam, key en `master`-item hebben opgegeven, kunnen we naar `Preprocessing` gaan en daar `Prometheus to JSON` selecteren. Als Parameter kunnen we nu een `Prometheus pattern` ingeven alsook wat regex om enkele zaken variabel te laten opvullen.
+
+
+
+Hieronder een voorbeeld van zo’n JSON verwerking
+````JSON
+[
+ {
+ "name": "wmi_logical_disk_free_bytes",
+ "help": "Free space in bytes (LogicalDisk.PercentFreeSpace)",
+ "type": "gauge",
+ "labels": {
+ "volume": "C:"
+ },
+ "value": "3.5180249088e+11",
+ "line_raw": "wmi_logical_disk_free_bytes{volume=\"C:\"} 3.5180249088e+11"
+ },
+ {
+ "name": "wmi_logical_disk_free_bytes",
+ "help": "Free space in bytes (LogicalDisk.PercentFreeSpace)",
+ "type": "gauge",
+ "labels": {
+ "volume": "D:"
+ },
+ "value": "2.627731456e+09",
+ "line_raw": "wmi_logical_disk_free_bytes{volume=\"D:\"} 2.627731456e+09"
+ },
+ {
+ "name": "wmi_logical_disk_free_bytes",
+ "help": "Free space in bytes (LogicalDisk.PercentFreeSpace)",
+ "type": "gauge",
+ "labels": {
+ "volume": "HarddiskVolume4"
+ },
+ "value": "4.59276288e+08",
+ "line_raw": "wmi_logical_disk_free_bytes{volume=\"HarddiskVolume4\"} 4.59276288e+08"
+ }
+]
+````
+
+In bovenstaand voorbeeld kunnen we enkele waarden terugvinden zoals `name`, `help` en `labels`. Onder `line_raw` zien we de effectieve lijn die Zabbix heeft ontvangen uit de `node_exporter`. Afhankelijk van welke data we willen opvragen, gaan we ook andere Macro’s willen aanmaken. In bovenstaand voorbeeld zal dat {#METRIC}, {#HELP} en {#VOLUME} zijn.
+{#VOLUME}=$.labels['volume']
+{#METRIC}=$['name']
+{#HELP}=$['help']
+
+
+
+Tot slot kunnen we nu een `prototype item` aanmaken. Door de LLD Macro’s, kunnen we nu eenvoudig unieke waardes genereren. Onder Preprocessing, kunnen we dan opnieuw die Macro’s gebruiken om de juiste waarde te selecteren.
+
+
+
\ No newline at end of file
diff --git a/posts/25Okt-RPM.md b/posts/25Okt-RPM.md
new file mode 100644
index 0000000..82da44e
--- /dev/null
+++ b/posts/25Okt-RPM.md
@@ -0,0 +1,90 @@
+---
+title: "Handige tips met RPM"
+excerpt: "Velen gebruiken uitsluitend YUM of DNF als het neerkomt op softwarebeheer maar RPM heeft ook nog altijd een paar handige trukken om te leren!"
+coverImage: "/RPM/RPM.png"
+date: "2023-10-25T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /RPM.png
+category: RPM,Linux
+---
+## RPM vs YUM/DNF
+In der oude tijde gebruikte iedereen RPM op RHEL gebasseerde systemen. Met deze tool kan je RPM pakketten installeren, verwijderen, updaten en informatie vergaren. Dat werkt heel goed met lokale RPM-bestanden. Helaas zijn zo'n bestanden niet altijd eenvoudig beschikbaar. De evolutie naar een repository systeem was dan logisch. Eerst was er `YUM` (`Yellowdog Updater Modified` afkomstig van `Yellowdog Linux`) maar sinds enkele jaren wordt er gebruik gemaakt van `DNF` (`DaNdiFied yum`). Beide van deze systemen kunnen naar netwerklocaties verbinden (vaak over http of https) om dan software beschikbaar te krijgen. Inhoudelijk zijn dat nog steeds RPM-bestanden en wordt alles nog steeds in een RPM database opgeslagen. Dat zorgt er dus voor dat we lokaal een schat aan informatie ter beschikking hebben.
+
+## RPM raadplegen
+Het zal geen groot mysterie zijn waarom de query optie in `RPM`, `-q` is. Van hieruit kunnen we de RPM database raadplegen. Veelal gebeurt dat met twee soorten opties:
+- selectie opties (Waarover willen we inforwatie)
+- query opties (welke informatie willen we)
+
+### Selectie opties
+De meest eenvoudige query die we kunnen maken is met de `-a` flag. Deze geeft ons ineens alle pakketten weer. Dat lijkt op eerste zicht maar een saaie representatie maar dit kan je ook combineren met `--qf` om het overzicht op te maken. Hieronder geven we zo een overzicht van alle pakketten met de Vendor op iedere lijn:
+
+```bash
+rpm -qa --qf '%{NAME} %{VENDOR}'
+```
+
+> Met de `Query format` kan je ook andere informatie bekomen zoals installatiedatum, versie, ... alle opties kan je bekomen door `rpm --querytags` uit te voeren zonder extra opties.
+
+Sommige software pakketten zijn ook in een groep opgedeeld. Ook dit kunnen we gebruiken om te filteren en details op te zoeken:
+
+```bash
+rpm -qa --qf '%{NAME}\t%{GROUP}' | grep -v 'Unspecified'
+# Hier komt vb Public Keys uit als group
+# Daar kunnen we ook nog een selectie van vragen
+rpm -qg 'Public Keys'
+```
+
+Als we een RPM bestand zelf hebben, kunnen we daarop specifiek ook manipulaties doen. Dat kunnen we met de `-p` flag doen:
+```bash
+# de uitkomst van onderstaand commando geeft de naam van het pakket; openssh-server alsook welke versie het is.
+rpm -qp openssh-server-9.0p1-17.fc38.x86_64.rpm
+```
+
+> Als je ook een RPM bestand snel wilt downloaden kan je dat met DNF; `dnf download openssh-server`
+
+
+Handiger is misschien vanuit selectie standpunt in kunnen opzoeken tot welk pakket een specifiek bestand hoort.
+```bash
+# Hiermee komen we opnieuw bij onze openssh-server uit
+rpm -qf /etc/ssh/sshd_config
+```
+
+### Query opties
+Nu we weten welke pakketten we hebben, kunnen we ook gaan proberen om naar de inhoud te gaan kijken van die pakketten. Dit is natuurlijk iets meer waardevollere informatie dan enkel de pakketnaam. Zo kunnen we met `-l` een lijst krijgen van alle bestanden en mappen die geïnstalleerd zullen worden.
+
+```bash
+rpm -qpl openssh-server-9.0p1-17.fc38.x86_64.rpm
+```
+
+We kunnen met de `-i` ook meer meta informatie krijgen van een bepaald pakket:
+```bash
+rpm -qfi /etc/ssh/sshd_config
+```
+
+Als je verder wilt weten welke documentatie er beschikbaar is voor een specifiek pakket, kan je dat ook opvragen met de `-d` flag.
+```bash
+rpm -qd openssh-server
+```
+
+Een stapje verder? Ok! Stel je hebt per ongeluk een configuratie te veel aangepast en je wilt terug het originele bestand in de plaats brengen:
+
+```bash
+# Eerst zoeken we tot welk pakket dit bestand behoort
+rpm -qf /etc/ssh/sshd_config
+# Daarna kunnen we het RPM bestand downloaden
+dnf download openssh-server
+# Controleer of het gewenste bestand aanwezig is
+rpm -qcp openssh-server-9.0p1-17.fc38.x86_64.rpm
+# Nu kunnnen we het RPM bestand uitpakken en de nodige files daaruit kopieren.
+rpm2cpio openssh-server-9.0p1-17.fc38.x86_64.rpm | cpio -id "*/etc/ssh/sshd_config"
+```
+
+> Het `rpm2cpio` commando is ook geweldig om te weten te komen welke rechten of eigenaar/group ingesteld staat op de bestanden:
+```bash
+rpm2cpio openssh-server-9.0p1-17.fc38.x86_64.rpm | cpio -tv
+```
+
+Een laatste weetje dat ik je wil meegeven is hoe de software geïnstalleerd wordt. Dat gebeurt met een script. Zowel de installatie, upgrade of het verwijderen van een pakket gebeurt door een script. Deze kan je voor een pakket ook opvragen. Meestal dienen die scripts ook voor gebruikers aan te maken of om bepaalde migraties te doen.
+
+```bash
+rpm -q --scripts openssh-server
+```
\ No newline at end of file
diff --git a/posts/26Okt-Journald.md b/posts/26Okt-Journald.md
new file mode 100644
index 0000000..d0dba0f
--- /dev/null
+++ b/posts/26Okt-Journald.md
@@ -0,0 +1,98 @@
+---
+title: "Problemen oplossen door logs in te stellen"
+excerpt: "De oorzaak van een probleem is niet altijd ver te zoeken. Begin daarom bij het begin; Instellen van jouw logs!"
+coverImage: "/Logging/Logging.png"
+date: "2023-10-26T12:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Logging.png
+category: Journald,Logging,Linux
+---
+## Syslog
+De eenvoudigste en meest gebruikte log methode is door middel van de `rsyslog` service. De configuratie zit volledig in `/etc/rsyslog.conf` en `/etc/rsyslog.d/`. Hierin kan je eenvoudig zeggen welke soort meldingen, met specifieke prioriteiten naar een bepaalde log locatie gaan.
+
+### De verschillende logs
+
+Faciliteiten
+| Code | Faciliteit | Omschrijving |
+| ---- | ---------- | ------------ |
+| 0 | kern | Kernel berichten |
+| 1 | user | User-level berichten |
+| 2 | mail | Mail systeem berichten |
+| 3 | daemon | System daemon messages |
+| 4 | auth | Authenticatie en beveiliging |
+| 5 | syslog | Interne syslog berichten |
+| 6 | lpr | Printer berichten |
+| 7 | news | Netwerk berichten |
+| 8 | UUCP | UUCP protocol berichten |
+| 9 | cron | Berichten rond Cron |
+| 10 | authpriv | Non-systeem authorizatie berichten |
+| 11 | ftp | FTP protocol berichten |
+| 16-23 | local0 - local7 | Aangepaste lokale berichten |
+
+Prioriteiten
+> Deze prioriteiten kan je ook gebruiken in Journald
+
+| Code | Prioriteit | Omschrijving |
+| ---- | ---------- | ------------ |
+| 0 | emerg | Het systeem is onbruikbaar |
+| 1 | alert | Dringend actie vereist |
+| 2 | crit | Kritieke toestand |
+| 3 | err | Niet-kritieke toestand |
+| 4 | warning | Waarschuwing |
+| 5 | notice | Melding |
+| 6 | info | Informatief |
+| 7 | debug | Debugging informatie |
+
+Door middel van een combinatie van zowel de Faciliteiten en de Prioriteiten, kunnen we een entry aanmaken in de `rsyslog` configuratie gevolgd door de locatie van een logbestand. Deze zal dan uitsluitend informatie over die specifieke faciliteit en die prioriteit en hoger dan je invult. Ook kan je een `*` gebruiken om ineens alle faciliteiten of prioriteiten te viseren. Als je dit combineert met andere faciliteiten (door middel van een `;` symbool) kan je ook `none` als prioriteit ingeven om specifieke faciliteiten te filteren.
+
+/etc/rsyslog.d/local_info
+```
+local0.info /var/log/local_info
+```
+
+> vergeet niet de `rsyslog` service te herstarten na de aanpassing!
+
+### Zoeken in rsyslog
+We kunnen onze configuratie nu testen door middel van logger. Hiermee kunnen we een specifieke faciliteit en prioriteit meegeven om er voor te zorgen dat we een entry kunnen testen.
+
+```bash
+logger -p local0.info "Dit was een test"
+```
+
+Hierna kunnen we zoeken in `/var/log/local_info` met allerhande tools. Gebruik `tail -f` om de actuele entries te verzamelen of `grep ` om echt in het bestand te zoeken naar een specifieke entry.
+
+## Journald
+Dezelfde prioriteiten als bij rsyslog kunnen gebruikt worden. Veelal is de informatie in deze logs beperkt tot de services die door systemd beheert worden. Wat uiteindelijk wel een sterk groeiende lijst is. Een groot verschil met `rsyslog` is dat journald standaard geen logs bijhoudt op de harde schijf maar in het geheugen. Herstart de computer? Dan zijn de logs weg.
+
+> Entries in `rsyslog` worden ook in journald gelogged!
+
+Je kan dit wel eenvoudig aanpassen in `/etc/systemd/journald.conf`. Hier is namelijk een optie genaamd `Storage`. Als deze op `auto` staat, wat de standaard is, gaat journald kijken of /var/log/journal bestaat. Als dat niet het geval is, schrijft Journald alle info naar /run/log. Deze locatie bestaat dus enkel in het geheugen. De `Storage` optie kan je ook aanpassen naar `persistent`. Hiermee wordt door journald de juiste map aangemaakt. Vul je `volatile` in, gaat journald sowieso naar het geheugen schrijven.
+
+### Zoeken in Journald
+Ook hier kan je eenvoudig testen met een 'identifier' en 'prioriteit':
+```bash
+echo "Dit is mijn unieke error" | systemd-cat -t "My_Unique_identifier" -p info
+```
+
+Er zijn een aantal flags die je gaan helpen om de data te filteren. Standaard wordt er namelijk wel wat informatie gelogged in journald.
+
+```bash
+# Toon alle informatie
+journalctl
+# Toon info van sshd service
+journalctl -u sshd.service
+# Toon enkel Kritieke meldingen
+journalctl -p crit
+# Toon alle actuele entries
+journalctl -f
+# Toon info over de laatste opstart
+# Werkt enkel als journald persistent werkt
+journalctl -b1
+# Toon enkel berichten van gisteren tot 4 uur geleden
+journalctl -S "yesterday" -U "-4hours"
+# Toon berichten met een specifieke rsyslog facility
+journalctl --facility=user
+# Zoek naar een specifieke tekst
+journalctl -g "NetworkManager"
+```
+
diff --git a/posts/27Sept-GitlabUpgrade.md b/posts/27Sept-GitlabUpgrade.md
new file mode 100644
index 0000000..8946fad
--- /dev/null
+++ b/posts/27Sept-GitlabUpgrade.md
@@ -0,0 +1,78 @@
+---
+title: "Gitlab upgrade"
+excerpt: "Git staat centraal in vele organisaties en Gitlab maakt heel wat zaken gemakkelijk. Met een zekere regelmaat komen hier echter veiligheidslekken naar boven en upgrades zijn niet altijd eenvoudig."
+coverImage: "/Git/cover_GitlabUpgrade.png"
+date: "2023-09-06T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_GitlabUpgrade.png
+category: Gitlab,DNF,Linux
+---
+## We doen een update en klaar is kees!
+Helaas pindakaas! Als we niet het juiste pad volgen, brengen we onze Gitlab installatie in gevaar. Het proces van upgraden is niet moeilijk maar je moet weten wat je aan het doen bent. Hierbij komen ook een paar goede pointers die je bij de upgrade van alle belangrijke software zal helpen:
+
+### Maak snapshots!
+Servers zijn vaak gevirtualiseerd. Iedere productiewaardige virtualisatiesoftware biedt snapshots aan en ook hier wil je daar gebruik van maken. Vóór iedere upgrade maak je best een snapshot en dan kan je met een gerust hart er in vliegen.
+
+
+
+### Lees de documentatie
+Gitlab maakt goed tijd vrij om duidelijk te maken aan gebruikers wat er verandert in de verschillende versies. Daar ga je ook terugvinden wat er achterliggend zou verandert zijn, waar jij op moet letten of waarom je na een succesvolle upgrade niet meteen aan de volgende mag beginnen.
+
+
+
+### Communiceer!
+Gebruikers die actief zijn op jouw Gitlab instantie moeten weten dat je de upgrade gaat doen. Dat betekent dat ze tijdelijk niet op hun Gitlab kunnen rekenen. Eventuele automatische installaties zullen dus ook even niet lukken.
+
+> Een upgrade doe je dus best niet als er deadlines te halen zijn voor je gebruikers.
+
+## Wat eerst dan?
+Als je gebruik maakt van een RHEL gebasseerde server en je hebt Gitlab met de repo's geïnstalleerd, zou je DNF kunnen gebruiken om allereerst al wat informatie te verzamelen over de upgrade. Uit onderstaand commando ga je eenvoudig kunnen zien in welke versie je momenteel werkt en welke versies beschikbaar zijn als upgrade.
+
+```bash
+sudo dnf list gitlab-ee --showduplicates
+```
+
+
+
+In mijn voorbeeld, dat expres verouderd is, zit ik op versie 15.10.2. Alles wat daarboven staat zijn de oude versies en alles eronder de nieuwe.
+
+## Ik heb geen tijd voor documentatie
+Gitlab maakt in hun documentatie duidelijk welke [`upgrade stops`](https://docs.gitlab.com/ee/update/#required-upgrade-stops) je zeker moet maken. Als je daarvoor geen tijd hebt, kan je ook volgens dit principe werken. Upgrade per minor tot het einde en daarna kan je naar de eerst volgende major gaan.
+
+```bash
+# In mijn voorbeeld dus eerst
+sudo dnf upgrade gitlab-ee-15.10.8
+```
+
+> Nadat de installatie klaar is, gaat jouw Gitlab misschien nog niet online zijn. Wacht tot je terug aan jouw Gitlab kunt voordat je deze gaat updaten.
+
+
+
+```bash
+# Daarna is 15.11.0 de eerst volgende versie voor mij
+sudo dnf upgrade gitlab-ee-15.11.0
+```
+Volgens de documentatie hadden we deze versie moeten overslaan en rechtstreeks naar 15.11.13 moeten gaan. Als je de documentatie niet gelezen had, heb je nu een probleem. Neem nu dus zeker de tijd om de [documentatie](https://docs.gitlab.com/ee/update/versions/gitlab_16_changes.html#undefined-column-error-upgrading-to-162-or-later
+) wel door te nemen.
+
+
+```bash
+# We gaan dus best naar 15.11.13
+sudo dnf upgrade gitlab-ee-15.11.13
+# Nu kunnen we naar 16.0.0. Deze upgrade stop is vooral
+# belangrijk voor organisaties met veel gebruikers
+sudo dnf upgrade gitlab-ee-16.0.0
+# In 16.1 zijn ook grote aanpassingen gebeurt
+sudo dnf upgrade gitlab-ee-16.1.0
+# De voorlaatste halte is nu 16.3
+sudo dnf upgrade gitlab-ee-16.3.4
+# Waarna we de laatste upgrade kunnen uitvoeren.
+sudo dnf upgrade gitlab-ee-16.4.0
+```
+
+
+
+## Voor je gaat...
+Het was een heel werkje om Gitlab vanaf een oudere versie up-to-date te brengen. De beste raad die ik je dan kan meegeven is de upgrades zo regelmatig mogelijk uit te voeren. Volg in Gitlab de officiële versies en voer een update uit zo snel als het past. Opnieuw lees de documentatie voor je die uitvoert om zo tranen te vermijden.
+
+Veel succes en veel plezier! 👋😊
\ No newline at end of file
diff --git a/posts/28Jul-SystemdApps.md b/posts/28Jul-SystemdApps.md
new file mode 100644
index 0000000..45b9b6f
--- /dev/null
+++ b/posts/28Jul-SystemdApps.md
@@ -0,0 +1,160 @@
+---
+title: "Systemd ctl-applicaties"
+excerpt: "Systemd is een fantastisch grote tool en biedt heel wat tooling. Daarbij ook verschillende ctl-applicaties die helpen bij de dagdagelijkse taken."
+coverImage: "/Systemd/cover_systemd.png"
+date: "2023-07-28T23:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_systemd.png
+category: Systemd,Linux,Expert Tip
+---
+## Systemd
+Systemd is al even oud en heeft al veel negatieve commentaar moeten lijden onder de Linux gemeenschappen. Voornamelijk omdat systemd zich diep in het systeem nestelt en in héél veel onderdelen betrokken is. Ik zet hier graag een aantal tools op een rij!
+
+## Systemctl
+Dit moet de bekendste tool zijn. Ongetwijfeld is dit ook de meestgebruikte tool. Voornamelijk is dit de tool die systemd gebruikt om bij opstart er voor te zorgen dat de juiste target bereikt wordt.
+
+### Targets
+Die targets zijn vergelijkbaar met de init-niveau's maar bieden ook wat extra mogelijkheden. Hier enkele belangrijke om te onthouden:
+- graphical: (default) Deze zal een grafisch login venster laten zien
+- multi-user: Alles behalve de grafische interface wordt geladen
+- emergency: Dit is een heel beperkte omgeving waar niet veel ingeladen wordt; zelfs geen systemd!
+- rescue: Vergelijkbaar met emergency maar hier laten we wel al systemd in
+
+Je kan het eenvoudigste naar deze modus gaan via het GRUB opstart menu. Druk hier op `e` om een geselecteerde kernel tijdelijk te wijzigen. Op de `Linux` regel ga je helemaal achteraan nog een beetje toevoegen; `systemd.unit=.target`
+
+### Services
+De targets zoals we hierboven al vermeldde zijn afhankelijk van services en sockets die een bepaalde status bereiken. De Services worden in een systeembeheerder rol vaak gebruikt. Hier nog enkele interessante opties om jouw kennis te verbreden:
+```bash
+# Lijst all unit files op
+systemctl list-unit-fils -at service
+# Bekijk het service bestand
+systemctl cat
+# Krijg in 1 woord terug of een service actief of enabled is
+systemctl is-active
+systemctl is-enabled
+# Vraag alle services op die degraded zijn
+systemctl status --state=degraded
+```
+
+### Mount
+Jawel, ook mounts kunnen gebeuren met systemd. Alles staat omschreven in `/etc/fstab` maar dat wordt allemaal vertaalt door systemd naar mount files om dan door systemd ook gemount te worden. Het kan dus interessant zijn om ook te weten hoe dat in z'n werk gaat. Zoals je hieronder merkt, ga je exact dezelfde items terugvinden als in `/etc/fstab`. Naast het `.mount` bestand is er ook een `.automount` nodig als die map automatisch gemount moet worden.
+
+Hier een `voorbeeld.mount`
+```
+[Unit]
+Description=Test map (/tmp_dir)
+DefaultDependencies=no
+Conflicts=umount.target
+Before=local-fs.target umount.target
+After=swap.target
+
+[Mount]
+What=/dev/disk/by-uuid/
+Where=/tmp_dir
+Type=ext4
+Options=defaults
+
+[Install]
+WantedBy=multi-user.target
+```
+
+Met bijhorende `voorbeeld.automount`
+```
+[Unit]
+Description=Voorbeeld automount partition
+ConditionPathExists=/tmp_dir
+
+[Automount]
+Where=/tmp_dir
+TimeoutIdleSec=10
+
+[Install]
+WantedBy=multi-user.target
+```
+
+### Timers
+Alhoewel Cron heel goed werkt, biedt Systemd ook timers aan. Deze brengen een kleine leercurve mee maar daarnaast werken deze ook wel degelijk en kunnen deze per timer eenvoudig gedeactiveerd worden. Een ander groot voordeel is dat je een timer afhankelijk kan maken van andere timers of services en zo een complexere setup kan bereiken.
+
+De grote vereiste is dat er een service file met dezelfde naam als de timer moet bestaan om aan te spreken.{lees: uit te voeren} Daarnaast kan je dan een `.timer`-bestand aanmaken in `/etc/systemd/system/` op systeem niveau ofwel in `$HOME/.config/systemd/user/`.
+
+Voorbeeld service file; `foo.service`
+```
+[Unit]
+Description=Dummy service foo die een script uitvoert om een programma in de achtergrond uit te voeren.
+
+[Service]
+ExecStart=/opt/foo/start.sh
+
+[Install]
+WantedBy=graphical.target
+```
+
+Voorbeeld timer file; `foo.timer`
+```
+[Unit]
+Description=Voer wekelijks uit EN meteen na boot
+
+[Timer]
+OnBootSec=15min
+OnUnitActiveSec=1w
+
+[Install]
+WantedBy=timers.target
+```
+
+In de plaats van hier de service manueel te starten en te activeren, gaan we dat nu voor de timer doen. Die heeft namelijk de info wat en wanneer uitgevoerd moet worden.
+
+```
+systemctl enable --now foo.timer
+```
+
+### Nog veel meer
+Er zijn nog zaken die Systemd beheert en ook hiervoor bestaan unit files. Hier lijst ik ze even kort op.
+- Socket: Inter proces communicatie socket
+- Device: Toestellen die herkend worden door de kernel
+- Scope: Processen die extern aangemaakt zijn geweest
+- Slice: Een hiërarchische groepering van units die systeemprocessen beheren
+- Path: Een pad naar een bestand of map in het filesysteem
+- Swap: Unit file voor een swap device
+
+
+## Hostnamectl
+Verschillende Linux gebruikers passen hun hostnaam aan via `/etc/hostname`. Dat werkt maar vereist steeds een reboot om volledig door te voeren. Alhoewel een reboot zeker altijd aan te raden is, kan je met deze tool je hostnaam veranderen zonder die reboot.
+```bash
+# Geef hostname weer
+hostnamectl
+# Stel een nieuwe hostname in
+hostnamectl hostname
+# Stel een locatie is. Dit heeft niets met timedate te maken
+hostnamectl location
+```
+
+## Timedatectl
+Nog een minder gekende tools is `timedatectl`. Deze, je raadt het nooit, kan je helpen om tijd, datum en tijdzone in te stellen. Hiernaast kan je ook NTP servers instellen. Deze is eenvoudig in werking en leuk om te weten.
+```bash
+# Vraag alle beschikbare tijdzones op
+timedatectl list-timezones
+# Stel daarna de juiste in
+timedatectl set-timezone
+# Datum en tijd instellen
+timedatectl set-time 'YYYY-MM-DD hh:mm:ss'
+# Stel een NTP-server in
+timedatectl ntp-servers
+# Activeer NTP service
+timedatectl set-ntp true
+```
+
+## Localectl
+Een laatste tool is `localectl`. Toch wel een onmisbare tool als je niet de standaard locale of keyboard settings gebruikt. Hier een paar voorbeelden voor mijn voorkeuren.
+```bash
+# Lijst alle beschikbare locales op
+localectl list-locales
+# Stel de gewenste locale in
+localectl set-locale en-US.UTF8
+# lijst beschikbare keyboard layouts op
+localectl list-keymaps
+# Stel de gewenste keymap in
+localectl set-keymap dvorak-intl
+```
+
+> Als je trouwens een locale ontbreekt kan je die installeren via DNF. Hiermee haal je een lijst op van de beschikbare locales; `dnf search glibc-langpack-*`
diff --git a/posts/30Aug-ZabbixBackup.md b/posts/30Aug-ZabbixBackup.md
new file mode 100644
index 0000000..f60fe72
--- /dev/null
+++ b/posts/30Aug-ZabbixBackup.md
@@ -0,0 +1,159 @@
+---
+title: "Een Zabbix backup nemen"
+excerpt: "Een goede backup strategie is even belangrijk al een goed lopend systeem. Ook voor Zabbix is het belangrijk een een goede backup te nemen. Al dan niet geautomatiseerd."
+coverImage: "/ZabbixBackup/ZabbixBackup_Cover.png"
+date: "2023-08-30T08:00:00.000Z"
+author: Eli Winderickx
+hero_image: /ZabbixBackup_Cover.png
+category: Backup,Expert Tip,Zabbix
+---
+## Wat kunnen we allemaal updaten?
+Zabbix bestaat uit verschillende onderdelen. Sommigen belangrijker dan anderen maar steeds de moeite waard om een backup te nemen. Hier gaan we even uit van de meest simpele opstelling; één Zabbix server met een database en webserver geïnstalleerd. In feite kan dit scenario ook uiteengetrokken worden in de vorm van een HA-cluster op de verschillende niveau's. De essentie zal steeds dezelfde blijven
+
+De belangrijke onderdelen die we willen veilig stellen zijn:
+- Zabbix server configuratie
+- Zabbix Frontend data
+- Zabbix database
+- Webserver configuratie
+
+We behandelen ze één voor één; opbouwend naar complexiteit
+
+## Zabbix server configuratie
+Dit bestand bevindt zich steeds in `/etc/zabbix/zabbix-server.conf`. Deze configuratie bevat voor velen niet gek veel aanpassingen. Iedere aanpassing kan het resultaat geweest zijn van uren zoeken naar een probleem of een broodnodige tweak. Dit is dan ook het eerste bestand dat we gaan veiligstellen.
+
+```bash
+#!/bin/bash
+# Zabbix BackupScript
+
+# Eerst maken we een map aan om alle data vast te houden.
+datum=$(date +'%F')
+backupFolder=/opt/backup/zabbix/$datum
+mkdir -p $backupFolder
+
+# Eerst de Zabbix configuratie en scripts veiligstellen met de juiste rechten
+cp -dR --preserve=all /etc/zabbix/ $backupFolder/configuratie
+cp -dR --preserve=all /usr/lib/zabbix $backupFolder/scripts
+```
+
+### Frontend
+We kunnen ook gegevens uit de frontend halen door middel van de Zabbix API. Hiervoor kunnen we gebruik maken van bijvoorbeeld `curl` om die data uit te lezen. De belangrijke vereiste is dat je een gebruiker hebt die API-toegang heeft. Met sterke voorkeur is dat geen gebruiker die frontend toegang heeft tot Zabbix.
+
+Vooraleer we informatie uit Zabbix mogen halen, moeten we authenticeren met onze API-gebruiker. Dat kunnen we ook met Curl doen:
+
+> Spring heel voorzichtig om met wachtwoorden in een script. Die zijn clear text en iedereen die aan het bestand kan, kan dat lezen. Beter gebruik je een soort wachtwoord manager of wachtwoord kluis om dit net op tijd door te geven aan het script.
+
+```bash
+response=$(curl --header "Content-Type: application/json" \
+ --request POST \
+ --data '{"jsonrpc": "2.0","method": "user.login", "params": {"user": "", "password": ""},"id": 1 }' \
+ https://zabbix.url/api_jsonrpc.php)
+```
+
+Daar zouden we een JSON antwoord van moeten terugkrijgen met een authenticatie token. Deze token moeten we nu bij iedere verzoek meegeven om te bewijzen dat we correct aangemeld zijn. zo kunnen we de data bekijken en exporteren. Deze token uit het JSON object krijgen lijkt moeilijk maar is goed haalbaar met `jq`, `awk` of `grep`. Hier gebruik ik grep met `PCRE`-regex om een opeenvolging van 32 karakters te vinden.
+
+```bash
+authcode=$(echo $response | grep -oP '[a-z0-9]{32}')
+```
+
+Nu we dat hebben, kunnen we effectief de data opvragen en veilig opslaan in onze backup map.
+
+```bash
+curl --header "Content-Type: application/json" \
+ --request POST \
+ --data '{"jsonrpc": "2.0","method": "hostgroup.get", "params": {"output": "extend", "sortfield": "name"},"id": 1, "auth":"'$authcode'" }' \
+ https://zabbix.url/api_jsonrpc.php >> $backupFolder/groups.json
+```
+
+Haal zo verschillende zaken uit Zabbix om je backup nog vollediger te maken. Naast Host groups, zijn de Hosts en Templates ook waardevol om op te nemen in je backup. Controleer zeker de [Documentatie]{https://www.zabbix.com/documentation/current/en/manual/api} om inspiratie op te doen van wat jij wilt opslaan.
+
+## Webserver Configuratie
+Zabbix ondersteunt momenteel Apache en Nginx als webserver. Alhoewel jij jouw voorkeur naar de ene of de andere hebt, moet dat niet relevant zijn voor jouw Zabbix backup. Iedereen moet namelijk een goede backup kunnen maken. Hieronder controleer ik dan welke geïnstalleerd is. Er zijn verschillende manieren om dat aan te pakken: controleer op de processen die lopende zijn, controleer het netverkeer van een bepaalde gebruiker. Omdat ik ervan uitga dat je Systemd gebruikt, kan het ook als volgt.
+
+```bash
+# We kijken welke service automatisch opstart
+if [[ $(systemctl is-enabled httpd 2> /dev/null) = "enabled" ]]; then
+ service="httpd"
+elif [[ $(systemctl is-enabled nginx 2> /dev/null) = "enabled" ]]; then
+ service="nginx"
+fi
+
+cp -dR --preserve=all /etc/$service $backupFolder
+```
+
+## Database backup
+Hier begint het wat moeilijker te worden. Je kan namelijk niet gewoon database bestanden verplaatsen. Zabbix ondersteunt voor de server namelijk enkel MySQL/MariaDB en PostgreSQL. Beide zijn relationele SQL database systemen en hebben hun eigen manier om een database dump te maken.
+
+> Opnieuw moeten we hier een wachtwoord in clear text ingeven. Probeer dat met sterke voorkeur te vemijden in voorkeu van een wachtwoordmanager of kluis
+
+```bash
+# Afhankelijk van welke database service, kunnen we het ene of het andere commando uitvoeren.
+if [[ $(systemctl is-enabled mysqld 2> /dev/null) = "enabled" ]]; then
+ $(which mysqldump) --single-transaction -p --tab $backupFolder -uzabbix -p zabbix
+else
+ $(which pg_dump) zabbix > $backupFolder\zabbix_db
+fi
+```
+
+## Comprimeren
+Een goede backup is achteraf ook mooi opgeruimd en neemt niet meer ruimte in dan nodig. We kunnen daarom onze backup in een tarbal steken en die dan ook comprimeren.
+
+```bash
+#Ga naar een bovenliggende map
+cd $backupFolder/..
+tar -czf zabbix_$datum.tar.gz $datum/
+```
+
+## Nu allemaal samen
+Alhoewel ik het sterk afraad dit script in productie te gebruiken, kan dit wel een goed startpunt zijn om een goede backupstrategie uit te bouwen. Je merkt hierboven dat op verschillende momenten authenticatie nodig is. Dit kan je wegwerken door gebruik te maken van een wachtwoord vault en dan die wachtwoorden `Just in time` te laten invullen. Alhoewel zeker interessant, valt dat een beetje buiten de scope van deze handleiding. Hieronder heb ik nog enkele extra stappen toegevoegd zoals de backup van eventuele rebranding als je dat ook gedaan hebt.
+
+```bash
+#!/bin/bash
+# Zabbix BackupScript
+
+# Eerst maken we een map aan om alle data vast te houden.
+datum=$(date +'%F')
+backupFolder=/opt/backup/zabbix/$datum
+mkdir -p $backupFolder
+
+# We kijken welke webservice automatisch opstart
+if [[ $(systemctl is-enabled httpd 2> /dev/null) = "enabled" ]]; then
+ service="httpd"
+elif [[ $(systemctl is-enabled nginx 2> /dev/null) = "enabled" ]]; then
+ service="nginx"
+fi
+
+# Info uit Zabbix frontend
+response=$(curl --header "Content-Type: application/json" \
+ --request POST \
+ --data '{"jsonrpc": "2.0","method": "user.login", "params": {"user": "", "password": ""},"id": 1 }' \
+ https://zabbix.url/api_jsonrpc.php)
+
+authcode=$(echo $response | grep -oP '[a-z0-9]{32}')
+
+curl --header "Content-Type: application/json" \
+ --request POST \
+ --data '{"jsonrpc": "2.0","method": "hostgroup.get", "params": {"output": "extend", "sortfield": "name"},"id": 1, "auth":"'$authcode'" }' \
+ https://zabbix.url/api_jsonrpc.php >> $backupFolder/groups.json
+
+#### Andere exports toe te voegen ###
+
+# Zabbix + Webservice configuratie
+cp -dR --preserve=all /etc/zabbix/ $backupFolder/configuratie
+cp -dR --preserve=all /usr/lib/zabbix $backupFolder/scripts
+cp -dR --preserve=all /etc/$service $backupFolder
+
+# Zabbix rebranding
+cp -dR --preserve=all /usr/share/zabbix/my_images $backupFolder/logos
+cp -dR --preserve=all /usr/share/zabbix/local/conf/brand.conf.php $backupFolder
+cp -dR --preserve=all /usr/share/zabbix/assets/styles $backupFolder
+
+# Database backup
+if [[ $(systemctl is-enabled mysqld 2> /dev/null) = "enabled" ]]; then
+ $(which mysqldump) --single-transaction -p --tab $backupFolder -uzabbix -p zabbix
+else
+ $(which pg_dump) zabbix > $backupFolder\zabbix_db
+fi
+
+cd $backupFolder/..
+tar -czf zabbix_$datum.tar.gz $datum/
+```
\ No newline at end of file
diff --git a/posts/31Jul-SELinux.md b/posts/31Jul-SELinux.md
new file mode 100644
index 0000000..5316842
--- /dev/null
+++ b/posts/31Jul-SELinux.md
@@ -0,0 +1,135 @@
+---
+title: "De mysteries achter SELinux"
+excerpt: 'Voor velen is SELinux nog een groot mystery. Jammer want het biedt veel voordelen en maakt je systeem ineens een pak veiliger'
+coverImage: '/SELinux/SELinux_cover.png'
+date: '2023-07-31T20:00:00.000Z'
+author: Eli Winderickx
+hero_image: /SELinux_cover.png
+category: SELinux,Wish I knew sooner,Configuratie,Expert Tip
+---
+## De basis
+Zoals altijd beginnen we bij het begin. SELinux of Security Enhanced Linux is een extra laag bovenop de `Discretionary Access Control`, genaamd `Mandatory Access Control`. Voordat `SELinux` dus "vervelend" kan doen, moeten dus onder andere de rechten al goed staan. eigenaar en groep op de map, gebruiker lid van de groep, bestand- en mappenrechten,... Pas daarna, als die hordes overbrugt zijn, zal SELinux een additionele controle doen. Daarnaast is het ook handig om te weten is dat `SELinux` `Access Vector Cache` gebruikt. Dat wil zeggen dat:
+- Je gaat meldingen van blokkades kunnen terugvinden in:
+ - `/var/log/audit/audit.log`,
+ - alsook in de `Systemd Journal` (`journalctl -xe`)
+- Het maakt gebruik van cache dus het kan zijn dat wijzigingen niet altijd meteen actief worden.
+
+## Hoe kan ik zien waar `SELinux` actief is?
+Zowel bestanden als processen vallen altijd onder een SELinux beleid als deze actief is. Maar eerst even SELinux zelf. Je kan het proces opvragen via `sestatus`. Deze geeft je dan de `Type` alsook de `Mode` mee. Standaard gaat dat staan op `Targeted` en `Enforcing`. maar er zijn nog andere types en modi.
+Type:
+- `Targeted`: Default: Controleert welke processen aan welke bestanden mogen.
+- `mls`: Multi-level security. Naast `Targeted` mode, zal het ook nagaan of de gebruiker effectief naar die bestanden mag gaan. Root mag bijvoorbeeld een bestand bewerken maar als je als `sudoer` het bestand opent, zou dat niet mogen lukken. Daar zorgt deze policy voor.
+- `minimun`: Hierbij gaan slechts bepaalde processen gecontroleerd worden.
+
+Mode:
+- `Enforcing`: SELinux controleert en houdt alles tegen wat niet mag
+- `Permissive`: SELinux controleert maar houdt niets tegen. Alles wordt standaard wel gedocumenteerd.
+- `Disabled`: Deze mode gaan we niet gebruiken want dit schakelt SELinux uit.
+
+### De bestanden en processen
+Om de configuratie van bestanden te controleren, kan je het list commando uitvoeren met de `-Z` flag. Datzelfde kunnen we doen voor processen.
+```bash
+ls -alZ /root
+# ... unconfined_u:object_r:admin_home:s0:...
+ps auZ
+# ...unconfined_u:unconfined_u:unconfined_u:s0-s0:
+```
+
+
+
+De `SELinux` context kan opgedeeld worden door middel van het `:` teken. Het eerste deel slaagt op de `user mapping`, vervolgens `role`, dan `type` en het laatste gedeelte is het level. Dit level is relevant in de `multi-level security` policy.
+
+
+## Hoe verander ik dat nu?
+De configuratie van `SELinux` is terug te vinden in `/etc/selinux/config`. Dit is steeds de permanentere config waar we willen zijn. Dit bestand gaan we niet te vaak aanpassen. Veel eerder kunnen we met `setenforce` de mode aanpassen naar een tijdelijk gewenste mode.
+
+```bash
+sudo setenforce permissive
+# Daarna kunnen we controleren
+sudo getenforce
+```
+
+Ook tijdens de boot van een machine kunnen we in GRUB extra opties toevoegen door op `e` te drukken nadat we een gewenste kernel hebben geselecteerd. Achteraan de `Linux` lijn, kunnen we dan ofwel `selinux=0` zetten om `SELinux` voor 1 boot volledig uit te schakelen of `enforcing=0` om SELinux tijdelijk op permissive te zetten.
+
+> Dit kan je ook permanenter doorvoeren. Best doe je dat in de SELinux config maar via `grubby` gaat dat zo: `grubby --update-kernel$(grubby --default-kernel) --args enforcing=0`
+
+Je begrijpt misschien al dat je best `SELinux` op `Permissive` zet. Hiermee wordt er niets geblokkeerd maar als de `Policy` op `Targeted` of `mls` staat, kunnen we gemakkelijk achterhalen of `SELinux` effectief in de weg stond.
+
+### Security context veranderen
+#### Bestanden en mappen
+Als je een bestaand bestand verplaatst van ene map naar de andere gaat de security context onveranderd blijven in tegenstelling tot nieuwe bestanden die meteen de correcte context van de parent map krijgen. In geval van onder andere een webserver kan dit vervelende scenario's veroorzaken. Gelukkig is dit snel recht te zetten;
+```bash
+# -v voor verbose en -R voor Recursief
+restorecon -vR /pad/naar/parent/folder
+```
+
+Als dit niet klopt, kan je in analogie van `chmod` of `chown` ook `chcon` gebruiken om de security context aan te passen.
+```bash
+# Neem security context over van een ander bestand
+chcon --reference bestand
+# Of stel het manueel in
+chcon -t httpd_sys_content_t bestand
+```
+
+In verschillende gevallen staat in `/var/log/audit/audit.log` ook duidelijke informatie over welk bestand of map verkeerd staat en wat er ingesteld moet worden. Als je dat graag wat leesbaarder wilt, kan de inhoud doorsturen naar `audit2why` om een leesbaarder formaat terug te krijgen.
+```
+cat /var/log/audit/audit.log | audit2why
+```
+
+#### Booleans
+Soms staat hier een boolean in die je meteen kan uitvoeren zoals hieronder. Die zorgen er dan voor dat je eenvoudig een policy kan activeren of deactiveren zonder grote wijzigingen in SELinux of zonder dat je je eigen modules moet schrijven.
+```
+semanage -P zabbix_can_network 1
+```
+
+#### Modules
+In andere gevallen moet je soms zelf een module maken. Ook hier moet je zelf het warm water niet opnieuw uitvinden. Je kan die module laten genereren, controleren en vervolgens toepassen.
+```bash
+# Maakt een .te en .pp bestand aan in huidige map.
+ausearch -C '' --raw | audit2allow -M
+# Daarna kan je die module installeren
+semodule -i .pp
+```
+
+## Een praktisch voorbeeld
+Ik heb `Nginx` geïnstalleerd met `dnf install nginx` en heb in de configuratie gekozen om een andere document root te gebruiken, namelijk `/srv/www/public_html`. Minder populair dan `/var/www/` maar nog steeds een map waar een website hoort te staan.
+
+```conf
+# /etc/nginx/nginx.conf
+# ...
+server {
+ root /srv/www/public_html;
+# ...
+```
+
+Als we nu de website proberen te benaderen krijgen we nu een error in het audit log. Ik heb zelf die map aangemaakt en deze heeft nog niet de juiste security context. Dat kunnen we aanpassen!
+
+
+
+```bash
+# We kennen de juiste security context toe aan de map
+chcon -R -t httpd_sys_content_t /srv/
+```
+
+Omdat we heel Agile werken, heb ik nieuwe bestanden geüpload naar mijn persoonlijke map voor deze website en van daaruit verplaats ik die met `mv`. Opnieuw krijgen we nu een probleem met SELinux. Geen probleem voor ons want we weten hoe we dat moeten aanpakken! Alhoewel het audit log ons zal voorstellen om een module te maken die `Nginx` toegang zal geven aan mijn publieke map, zijn wij slimmer en gebruiken wij `restorecon` om de security context in de map te herstellen.
+
+```
+mv ~/myNewIndex.html /srv/www/public_html/index.html
+```
+
+
+```
+restorecon -R /srv/www/public_html/
+```
+
+De website gaat nu goed werken!
+
+## Enkele aandachtspunten
+### Voer niet gewoon alles uit in het `audit.log`
+Stel je werkt als root op een server (wat sowieso af te raden is) en je verplaatst een bestand naar de document root van een webserver, dan gaat die security context mogelijk staan als `admin_home`. Het `audit.log` kan dan voorstellen om `httpd` toegang te geven tot `admin_home`. Dat is helemaal niet wenselijk. Zo kunnen we de webserver toegang verschaffen naar de `/root` map.
+
+### Maak je aanpassingen wanneer SELinux uitgeschakeld staat
+Dat kan je! Vooral in noodgevallen wanneer je naar een emergency target opstart, ga je aanpassingen doen aan jouw systeem terwijl SELinux volledig uitstaat. Let wel op als je achteraf het toestel herstart. Als je dat niet goed aanpakt, kan je mogelijk ongewenste blokkades tegenkomen. De oplossing is simpel. je moet gewoon een bestand aanmaken en SELinux controleert en herstelt alles.
+```bash
+touch /.autorelabel
+```
\ No newline at end of file
diff --git a/posts/4Okt-HashicorpVault.md b/posts/4Okt-HashicorpVault.md
new file mode 100644
index 0000000..aed112b
--- /dev/null
+++ b/posts/4Okt-HashicorpVault.md
@@ -0,0 +1,110 @@
+---
+title: "Hashicorp Vault"
+excerpt: "Wachtwoorden op een veilige manier gebruiken met Hashicorp Vault. Een wachtwoordmanager die met API's en thirdparty tools kan werken!"
+date: "2023-10-04T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /Vault_cover.png
+category: Wachtwoord manager, Linux, Beveiliging
+---
+## Hoe beginnen we hieraan?
+Een wachtwoord manager is tegenwoordig geen overbodige luxe om te hebben. Containers vormen vaak een basis van ontwikkelingen en die moeten automatisch en op een veilige manier hun configuratie krijgen. Het is dan niet veilig als je dan een wachtwoord als `clear text` in een bestand laat staan. Iedereen met toegang tot de configuratie, kan dan meteen het wachtwoord uitlezen. Veel beter is dan een wachtwoordmanager zoals Vault van Hashicorp. Dit soort wachtwoordmanager is niet bedoelt voor jouw dagdagelijks gebruik zoals een Bitwarden in jouw browser of smartphone. Deze is ontworpen zodat andere computers, API's en dergelijke, hier gemakkelijk gebruik van kunnen maken. Hoe dat gebeurt, lees je hieronder. Eerst hebben we en paar zaken nodig voor we van start gaan.
+
+### Repo
+Om te beginnen, moeten we de repo van Hashicorp toevoegen. Hun software zit namelijk niet in de standaard repo's van Red Hat of Fedora. Toevoegen van die repo's is eenvoudig werk. Je vindt hun repo ook vrij snel op hun website. Hier toch even de stappen voor jouw gemak. 😉
+
+```bash
+wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
+mv hashicorp.repo /etc/yum.repos.d/
+sudo dnf update
+sudo dnf -y install vault
+```
+
+
+
+### Certificaat
+Om een beveiligde verbinding te kunnen maken met onze server, moeten we ook een certificaat hebben. In het veld wil je steeds één van de volgende opties gebruiken:
+- Een certificaat ondertekend door een interne Certificate Authority (CA).
+- Een certificaat van een erkende CA.
+- Een geldig certificaat via [`Let's encrypt`](https://letsencrypt.org/).
+
+> Bekijk [mijn blog post over Let's Encrypt](https://blog.winderickx.me/posts/8Okt-Certbot) om na te gaan hoe je `certbot` op jouw toestel zet. Daarmee kunnnen we nu een geldig certificaat genereren.
+
+Als je het certificaat rechtstreeks op de server genereert, kan je het `Let's Encrypt` certificaat terugvinden in `/etc/letsencrypt/live/domeinnaam/fuulchain.pem` en de key in dezelfde map maar dan `privkey.pem`. Deze ga je in de volgende stap willen invullen.
+
+## Configure Vault
+We hebben nu ons certificaat en Vault is geïnstalleerd. We zijn er bijna, toch? Neen toch niet maar hou dat enthousiasme vast! In de configuratie ga je nu een verwijzing willen maken naar jouw certificaat. Die configuratie vind je in: `/etc/vault.d/vault.hcl`.
+
+```
+#HTTPS listener
+...
+listener "tcp" {
+ address = "0.0.0.0:8200"
+
+ tls_cert_file = "/opt/vault/tls/domain.crt"
+ tls_key_file = "/opt/vault/tls/domain.key"
+...
+}
+```
+
+Nu dat klaar is, moeten we Vault daar ook toegang tot geven. Een elegante oplossing is een extra group aanmaken en de `vault` gebruiker daar lid van te maken. Deze groep kunnen we dan de nodige rechten geven op de map met ons certificaat. We moeten ook zeker zijn dat als de host naar ons domeinnaam wilt, die naar de lokale server verwijst. Dat kunnen we doen door ons domeinnaam aan `/etc/hosts` toe te voegen.
+
+> Je kan deze stap overslaan als je Let's Encrypt niet op deze server hebt uitgevoerd. Dan moet het certificaat enkel de juiste rechten hebben. Dat kan dan `vault` als eigenaar en groep van de bestanden.
+
+```bash
+sudo groupadd pki
+sudo chgrp -R pki /opt/vault/tls/
+sudo chmod -R g+rx /opt/vault/tls/
+sudo usermod -a -G pki vault
+echo 127.0.0.1 | sudo tee -a /etc/hosts
+```
+
+Start en initialiseer vervolgens Vault. Bij het initialiseren, geven we een paar opties mee. `Key shares` verwijst naar het aantal tokens dat we gaan maken om onze kluis te ontgrendelen en `key threshold` is het aantal tokens die nodig zijn om de kluis effectief te ontgrendelen.
+
+> krijg je hieronder een fout dat er geen route naar host is, kan je jouw domeinnaam nog toevoegen aan `/etc/hosts`
+
+```bash
+# Start service
+sudo systemctl enable --now vault.service
+# Geef aan hoe de vault bereitk wordt
+export VAULT_ADDR=https://:8200
+# Initialeseer de kluis
+vault operator init -key-shares=3 -key-threshold=2
+```
+
+> Let op dat je de Root EN Unseal Tokens goed noteert. Deze gaan niet meer opnieuw getoond worden en zijn de enigste manier om in jouw kluis te komen.
+
+## Werken met de vault
+
+Onze kluis is aangemaakt en standaard is die meteen vergrendeld. Voordat we nu dus kunnen werken met onze kluis, moeten we die dus eerst ontgrendelen. Omdat we `key threshold` op twee gezet hebben, moeten we twee `Unseal Tokens` ingeven. Dat kunnen we door onderstaand commando tweemaal uit te voeren. Je kan dan iedere keer een andere token ingeven.
+
+```bash
+vault operator unseal
+```
+
+Nu onze kluis ontgendeld is, kunnen we aan het echte werk beginnen. We kunnen een key vault activeren, geheimen daar in steken en die ook oplijsten of ophalen.
+
+```bash
+root_token=your_root_token_here
+VAULT_TOKEN=$root_token vault secrets enable kv
+# Lijst secrets
+VAULT_TOKEN=$root_token vault secrets list
+# schijf secret
+VAULT_TOKEN=$root_token vault write kv/message value=mypassword
+# Lees secrit
+VAULT_TOKEN=$root_token vault read kv/message
+```
+
+### Policies maken
+Dit is voorlopig nog niet erg handig. We hebben namelijk maar één manier om de kluis te openen en dan staan de deur ineens open voor alles. Dit kan beter. Dit kunnen we compartmentaliseren. Via een `policy` kunnen we een API of externe tool toch gegevens laten uitwisselen. Belangrijk is dat we dan eerst goed aangeven wat er exact mag. Onze applicatie mag bijvoorbeeld enkel gegevens uitlezen vanuit `kv/message`. Om dat te realiseren steken we dat in een bestand zoals bijvoorbeeld: `policy.hcl`
+
+```
+path "kv/message" {
+ capabilities = ["read"]
+}
+```
+
+Dit bestand kunnen we nu inlezen om er daarna een `App token` van te maken. Deze token, kunnen we dan gebruiken in onze externe tool of API.
+```bash
+VAULT_TOKEN=$root_token vault policy write message-readonly policy.hcl
+VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
+```
diff --git a/posts/6Sept-Kickstart.md b/posts/6Sept-Kickstart.md
new file mode 100644
index 0000000..9f8d1d2
--- /dev/null
+++ b/posts/6Sept-Kickstart.md
@@ -0,0 +1,173 @@
+---
+title: "Kickstart installatie"
+excerpt: "Installeren van een Linux server is niet moeilijk maar neemt vaak onnodig tijd in beslag. Je zou met een template kunnen werken maar daar zitten niet altijd de laatste updates en is dus ook geen oplossing. Wat doen we dan? Een Kickstart installatie natuurlijk!"
+date: "2023-09-06T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_kickstart.png
+category: Kickstart,Linux,Expert Tip
+---
+## Wat doen we?
+Installeren van een Linux server is niet moeilijk maar neemt vaak onnodig tijd in beslag. Je zou met een template kunnen werken maar daar zitten niet altijd de laatste updates en is dus ook geen oplossing. Wat doen we dan? Een Kickstart installatie natuurlijk! Hiermee kunnen we in een bestand noteren hoe de installatie moet verlopen en kunnen we die installatie volledig automatisch laten verlopen. Handig en dan hebben wij tijd om aan iets anders te werken!
+
+## Hoe beginnen we?
+We doen eerst een manuele installatie. Ja, inderdaad. Het lijkt een beetje vreemd maar dit gaat ons helpen om een eerste draft van het kickstart bestand aan te maken. Zo maken we zelf minder typ-fouten en hebben we meteen een versie waar het meeste al goed staat. In die installatie, ga je alle instellingen proberen steken die je op de nieuwe servers of toestellen ook wilt. Dat houdt dan vooral in; de schijf opdeling, het wachtwoord van de root-gebruiker en eventueel andere gebruikers die je ook wilt.
+
+> Alhoewel je hier het effectieve wachtwoord al gerust kan insteken, kan het interessant zijn om achteraf in het kickstart bestand het wachtwoord toch aan te passen.
+
+Als die installatie klaar is, kan je het kickstart bestand verzamelen in `/root` genaamd `anaconda-ks.cfg`. Breng deze naar jouw werkstation om verder aan te passen. Hieronder vind je een voorbeeld van mijn installatie. Je gaat merken dat ik `graphical` in commentaar heb gezet en eronder `text` heb gezet. Alhoewel je via de grafische interface ook een automatische installatie kan doen, oogt dit in mijn persoonlijke voorkeur leuker. Onder `Network Information` kunnen we ook al een hostnaam opgegeven.
+
+> De ISO die ik gebruik is de `Red Hat Enterprise Linux 9.2 Binary DVD x86_64`. Het principe werkt op alle RHEL gebasseerde distro's maar je moet misschien wel een paar specifieke zaken aanpassen.
+
+```
+# Generated by Anaconda 34.25.2.10
+# Generated by pykickstart v3.32
+#version=RHEL9
+# Use graphical install
+# graphical
+text
+repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream
+
+%addon com_redhat_kdump --enable --reserve-mb='auto'
+
+%end
+
+# Keyboard layouts
+keyboard --xlayouts='us (dvorak-intl)'
+# System language
+lang en_US.UTF-8
+
+# Network information
+network --bootproto=dhcp --device=enp1s0 --ipv6=auto --activate
+network --hostname=.winderickx.me
+
+# Use CDROM installation media
+cdrom
+
+%packages
+@^server-product-environment
+
+%end
+
+# Run the Setup Agent on first boot
+firstboot --enable
+
+# Generated using Blivet version 3.6.0
+ignoredisk --only-use=vda
+autopart
+# Partition clearing information
+clearpart --none --initlabel
+
+# System timezone
+timezone Europe/Brussels --utc
+
+# Root password
+rootpw --iscrypted
+user --groups=wheel --name=test --password= --iscrypted --gecos="test"
+```
+
+## Hoe maken we dit nu beschikbaar
+Het moeilijkste in dit proces is het correct beschikbaar stellen van het kickstart bestand. In organisaties ga je vaak een web of ander serveradres beschikbaar krijgen. In een labo omgeving is dat misschien niet zo eenvoudig om snel op te zetten. Hier gaan we er dan van uit dat je een USB of een ISO gaat gebruiken.
+
+## Een ISO maken
+Dit moet ongetwijfeld de eenvoudigste methode zijn om een volledig geautomatiseerde installatie te doen. Het uiteindelijke bestand kan je gebruiken in een gevirtualiseerde omgeving, op een DVD branden of op een ISO zetten. Zorg nu eerst dat je de inhoud van een bestaande ISO inlaad en uitleest. De inhoud zet je best in een map waar je makkelijk aankan.
+
+```bash
+# We gaan de ISO mounten in een lege map.
+# In de GUI interface kan je ook dubbelklikken op de ISO om die te mounten.
+sudo mount -o loop ~/ISOs/Rhel9.iso /run/media/$(whoami)/Lege_map
+mkdir -p ~/Documenten/Project/kickstart
+# Kopieer de inhoud van de ISO naar de werkmap die we hierboven aangemaakt hebben.
+cp -r /run/media/$(whoami)/Lege_map/* ~/Documenten/Project/kickstart
+# Als we de bestanden hebben, hebben we de ISO niet meer nodig. We gaan er zelf een maken!
+sudo umount /run/media/$(whoami)
+```
+
+### Het Kickstart bestand
+In onze werkmap kunnen we nu het kickstart bestand plaatsen. Noem deze `ks.cfg`. Dit is geen harde vereiste maar handig om even de handleiding te volgen. Eventueel andere bestanden op mappen die automatisch op het toestel moeten komen, kan je ook al toevoegen aan de werkmap. Het moelijke is nu de juiste inhoud in het kickstart bestand krijgen. Als je een gratis ontwikkelaar account (of betalende licentie) bij RedHat hebt, kan je [hier](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/sect-kickstart-syntax) de documentatie bekijken. Anders zijn hier alvast een paar voorbeelden om je te inspireren.
+
+
+```bash
+# Wis de harde schijf volledig.
+zerombr
+clearpart --none --initlabel --all
+
+# kopieer bestanden van de root van de ISO naar een map
+# We houden ook een log bij van deze stappen
+%post --nochroot --log=/mnt/sysimage/root/ks-post-no-chroot.log
+cd /path/to/folder
+cp -Rv run/install/repo/Important_Folder /mnt/sysimage/path/to/folder
+%end
+
+# We kunnen ook in de Chroot omgeving al wat applicaties installeren.
+%post --log=/root/ks-post.log
+dnf -y install git vim
+%end
+
+# We kunnen zelf een gehashte wachtwoord string meegeven.
+rootpw --iscrypted
+```
+
+> Je kan achteraf een nieuw wachtwoord in de ISO steken door een nieuwe string te generenen. In moderne systemen kan dat met `openssl passwd -6` om vervolgens het wachtwoord in te geven. Oudere systemen kunnen Python gebruiken: `python3 -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass()))'`
+
+### GRUB aanpassen
+Om er nu voor te zorgen dat tijdens het opstarten van de ISO het kickstart bestand goed wordt ingelezen, moeten we dat ook aangeven aan GRUB. Deze wijziging moeten we op twee plaatsen doen;
+- EFI/BOOT/grub.cfg
+- isolinux/isolinux.cfg
+
+> het pad `cdrom:/ks.cfg` gaat ervan uit dat je de ISO op schijfmedia gaat plaatsen. Als je de ISO rechtstreeks op een USB gaat zetten, gebruik je best `hd:LABEL=:/` ipv `cdrom:/`. Doe je dat toch, kan je doormiddel van een tool zoals Ventoy daarmee toch nog verder. Later in de handleiding meer daarover.
+
+Pas hier niet te veel in aan want dan werkt het mogelijk niet meer. Als je vast zit, kan je altijd een kopie terugvinden in de originele ISO. In het isolinux.cfg bestand is vooral achteraan de `append initrd` belangrijk dat je het kickstart bestand meegeeft.
+
+```cfg
+# grub.cfg
+
+menuentry ...
+ linuxefi /images/pxeboot/vmlinuz ... quiet inst.ks=cdrom:/ks.cfg
+```
+
+
+```cfg
+# isolinux.cfg
+
+# Zoek naar onderstaande lijn of gelijkwaardig equivalent
+menu label ^Install Red Hat Enterprise Linux ..
+# Hier kan je onderstaande toevoegen om dit de default boot optie te maken.
+menu default
+# Achteraan onderstaande lijn ga je inst.ks=cdrom:/ks.cfg toevoegen
+# Hier moet de naam van het kickstart bestand en het pad daarnaar kloppen
+append initrd=initrd.img inst.stage2=hd:LABEL=RHEL... quiet inst.ks=cdrom:/ks.cfg
+```
+
+
+### De ISO genereren
+Zorg dat je in de map zit met de inhoud van de ISO, jouw kickstart bestand en eventueel andere bestanden en mappen die je wilt gebruiken. Daarna controleer je best of je voldende tools op jouw toestel hebt staan; `genisoimage`, `isohybrid` en `implantisomd5`.
+
+Om de correcte naam van de ISO te vinden kan je de waarde overnemen in EFI/BOOT/grub.cfg in de ISO. Hier staat de naam achter de `LABEL` waarde.
+
+> Als je niet zeker weet welk pakket je moet installeren. Gebruik dan `sudo dnf provides ` om dat uit te vinden.
+
+
+```bash
+# Genereer de ISO.
+sudo genisoimage -U -r -v -T -J -joliet-long -V "" -volset "" -A "" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -o ../.iso .
+# Zorg ervoor dat we de ISO ook in UEFI kunnen gebruiken.
+sudo isohybrid --uefi ../.iso
+# Met de MD5 Hash kunnen we de integriteit van onze image garanderen.
+sudo implantisomd5 rhel8_6_ks.iso
+```
+
+> Vergeet het puntje op het einde van het `genisoimage` commando niet!
+
+## De ISO via USB
+In principe zijn we klaar. Als je de stappen goed gevolgd hebt, zou je ISO goed moeten werken en is jouw installatie nu volledig geautomatiseerd. Tenzij je met virtualisatiesoftware zoals vSphere of XenCenter werkt, ben je misschien niets met enkel een ISO. Een schijf media zoals een DVD is ook niet meer zo alledaags en een USB is vaak handiger om mee aan de slag te gaan. Als je in de `cfg` bestanden gekozen hebt om met de `HD` entry te werken, kan je de ISO op je USB-stick zetten met een tool zoals `BalenaEtcher`, `Rufus` (Windows), `Fedora Image Writer` of `dd`. Heb je gekozen voor de `cdrom`-notatie? Niet gevreest! Je kan door middel van `Ventoy` toch nog de ISO gebruiken.
+
+### Ventoy
+Dit is een super project dat iedereen zou moeten kennen. Hiermee kan je namelijk een USB-stick nemen, een programmaatje uitvoeren en dan ISO in de juiste map zetten. Daarna kan je al die ISO gebruiken om te booten zonder dat je per ISO een aparte stick moet voorzien.
+
+Download de laatste versie van hun [Github pagina](https://github.com/ventoy/Ventoy/releases) en pak die uit op jouw toestel. Voer de Exe uit op Windows of de `VentoyGUI.x86_64` voor Linux. Selecteer dan jouw USB-stick in het lijstje. Kies onder opties dan `Secure Boot` en `GPT` onder partitioning en tot slot klik je op Install. Zo zal Ventoy voor de meeste tosetellen werken.
+
+
+
+Je hebt dan twee partities. Alleen de `Ventoy` partitie heb je nodig. De andere kan je gerust negeren. Sleep hier de ISO's in en klaar ben je voor de installatie!
+
+> Als je een boot image gebruikt van RedHat in combinatie met Ventoy merk ik dat dit niet goed geautomatiseerd werkt. Je moet dan nog steeds een paar kliks uitvoeren. Best pas je dan in `EFI/BOOT/grub.cfg` en `isolinux/isolinux.cfg` de `cdrom:/ks.cfg` aan naar `hd:LABEL=:/ks.cfg`.
\ No newline at end of file
diff --git a/posts/8Okt-Certbot.md b/posts/8Okt-Certbot.md
new file mode 100644
index 0000000..133e315
--- /dev/null
+++ b/posts/8Okt-Certbot.md
@@ -0,0 +1,88 @@
+---
+title: "Beveilig jouw websites met SSL!"
+excerpt: "Let's encrypt is een fantastische tool, volledig gratis, open-source,... Moet ik dit echt verkopen?"
+date: "2023-10-08T06:00:00.000Z"
+author: Eli Winderickx
+hero_image: /cover_LetsEncrypt.png
+category: Linux,Nginx,Websites,Reverse Proxy
+---
+## Wat doen we vandaag?
+Om zeker te zijn dat de verbinding met onze website op een beveiligde manier gebeurt, gebruiken we een SSL certificaat. Hiermee kunnen we namelijk een HTTPS verbinding opzetten. Dit versleutelt de verbinding op een cryptografische manier. Dat houdt in dat het verkeer van en naar jouw server beveiligd is als een soor tunnel over het internet. Iemand die de lijn afluisterd, gaat dus alleen geencrypteerde brabbel terugvinden. Ik moet je dan ook niet uitleggen waarom een geëncrypeerde verbinding belangrijk is. Wachtwoorden of andere gevoelige informatie die je over het internet stuurt, zal nu niet als leesbare tekst te zien zijn.
+
+Omdat dit zo belangrijk is, heeft de [EFF (Electronic Frontier Foundation)](https://www.eff.org/) daarom beslist om de drempel naar zo'n certificaat zo laag mogelijk te maken. In de plaats van een certificaat aan te kopen bij een gekende CA (Certificate Authority) (duur) of zelf een Self-signed certificaat aan te maken (Niet extern vertrouwd en een kleine leercurve), kan je een tool downloaden genaamd Certbot om niet alleen gratis een geldig certificaat aan te maken. Ook de configuratie en vernieuwing kan eenvoudig geautomatiseerd worden.
+
+> Dit houdt hackers niet tegen om jouw website aan te vallen. Enkel hebben we nu een aanval vector minder; de verbinding tussen het toestel van de gebruiker en jouw server.
+
+## Certbot
+### Vereisten
+[`Let's encrypt!`](https://letsencrypt.org/) Zo is de tool gekend bij de grote meerderheid. Deze tool van de EFF is niet voor niets een hele populaire tool. Meer dan 300 miljoen websites maken er gebruik van. En daar is een goede reden voor. Om hiermee van start te kunnen gaan, moeten we eerst de nodige tools installeren:
+
+```bash
+sudo dnf install certbot python3-certbot-nginx
+```
+
+> Jouw website moet op het internet bereikbaar zijn. Als het internet niet naar jouw server kan of mag verbinden, ga je Let's encrypt niet kunnen gebruiken. Ook huis en tuin routers ondersteunen portforwarding. Controleer even bij jouw ISP hoe je dat opzet.
+
+Daarnaast hebben we een basis configuratie nodig. Ik ben fan van NGINX dus ik dat gebruik ik hieronder. De configuratie om via poort 80 naar poort 443 te verbinden en zo HTTPS te introduceren. Als je de onderste blok goed kan vertalen zie je dat deze configuratie voor een reverse proxy is en dat de verbinding naar een interne virtuele machine wordt doorgestuurd.
+
+```conf
+server {
+ listen 80;
+ server_name myweb.winderickx.me;
+ access_log /var/log/nginx/myweb.winderickx.me.log;
+ error_log /var/log/nginx/myweb.winderickx.me.error.log;
+ return 301 https://myweb.winderickx.me$request_uri;
+
+
+}
+server {
+ listen 443 ssl;
+ server_name myweb.winderickx.me;
+
+ access_log /var/log/nginx/myweb.winderickx.me.log;
+ error_log /var/log/nginx/myweb.winderickx.me.error.log;
+
+ ssl_prefer_server_ciphers on;
+
+ location / {
+ proxy_pass https://192.168.124.204:443;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+}
+```
+
+Wijzig de `myweb.winderickx.me` naar jouw webadres en pas de `proxy_pass` aan naar jouw intern IP-adres. Daarna kan je `sudo nginx -t` uitvoeren om jouw configuratie te controleren. Als alles goed gaat, krijg je onderstaande boodschap terug. Anders gaat NGINX je normaal wel vertellen waar het misloopt. Gaat het goed herlaad dan nog even NGINX met `sudo systemctl reload nginx`.
+
+```
+nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
+nginx: configuration file /etc/nginx/nginx.conf test is successful
+
+```
+
+> Als jouw firewall nog niet open staat voor http en https verkeer, is dit het moment om dat even recht te zetten.
+
+```bash
+sudo firewall-cmd --add-service=http --add-service=https --permanent
+sudo firewall-cmd --reload
+```
+
+## Let's Encrypt!
+Laten we er nu helemaal invliegen! Je kan `certbot` nu uitvoeren met de `--nginx` vlag om automatisch de configuratie aan te passen. Hoe weet `certbot` welke configuratie? Dat kan die via de `-d` flag waarachter je jouw domein gaat zetten. Als je meerdere subdomeinen aan jouw website wilt koppelen, kan je gewoon extra `-d` flags toevoegen.
+
+De eerste keer dat je Let's encrypt gebruikt, ga je de gebruiksovereenkomst moeten lezen en accepteren en krijg je ook de vraag om jouw e-mailadres aan de [EFF](https://www.eff.org/) te delen. Ik ben een fervente fan van hun werk en kan hen ook enkel toejuichen. Moest het mogelijk zijn voor jou, overweeg dan ook om hen financieel te steunen.
+
+```bash
+sudo certbot --nginx -d myweb.winderickx.me
+```
+
+Als het goed gelopen is, heb je nu een website die met een HTTPS beveiliging veilig gemaakt is. Goed gedaan! Het internet is nu weer een klein beetje veiliger geworden!
+
+```
+Deploying certificate
+Successfully deployed certificate for myweb.winderickx.me to /etc/nginx/conf.d/myweb.winderickx.me.conf
+Congratulations! You have successfully enabled HTTPS on https://myweb.winderickx.me
+```
\ No newline at end of file
diff --git a/posts/9Jul-zabbix-ha-cluster.md b/posts/9Jul-zabbix-ha-cluster.md
new file mode 100644
index 0000000..01d9428
--- /dev/null
+++ b/posts/9Jul-zabbix-ha-cluster.md
@@ -0,0 +1,55 @@
+---
+title: "High Available Zabbix cluster"
+excerpt: 'Naast een robuust en performant product als Zabbix server, kunnen we deze nog robuuster maken door meerdere servers in een HA cluster op te zetten.'
+date: '2023-07-09T18:00:00.000Z'
+author: Eli Winderickx
+hero_image: /ZabbixHACluster_cover.png
+category: High Available,Zabbix
+---
+## Vertrekpunt
+Vermoedelijk heb je al een Zabbix server draaiende. Op die server draait mogelijk zowel de Zabbix server software, als de database en ook de webserver. Een eenvoudige uitbreiding hierop kan zijn om een Zabbix server HA cluster op te zetten. Dit is ondersteund in Zabbix vanaf versie 6.
+
+## De Zabbix nodes
+Best maak je hiervoor twee extra servers aan. (Je kan er ook meerdere aanmaken maar twee nodes zijn veelal voldoende voor zo'n HA opstelling). Om het simpel te houden noem ik die ZN1 (Zabbix Node 1) en ZN2 (Zabbix Node 2).
+
+Installeer zoals gewoonlijk de Zabbix server en pas de configuratie aan.
+````bash
+sudo dnf install zabbix-server-mysql zabbix-selinux-policy zabbix-agent
+sudo vim /etc/zabbix/zabbix_server.conf
+````
+
+Vooral de ``DBHost``, ``DBName``, ``DBUser``, ``DBPassword`` en ``DBPort`` zullen ervoor zorgen dat je naar je originele database kan verbinden en dus vrij simpel verder kan. Daarnaast ga je per server ``HANodeName`` en ``NodeAddress`` instellen om de cluster High available te maken.
+
+````
+HANodeName=zn1.winderickx.me
+NodeAddress=192.168.124.186
+````
+
+Herstart beide servers en controleer de log op eventuele fouten in je configuratie. Het ``systemctl status zabbix-server`` commando gaat je niet genoeg info tonen!
+
+````bash
+sudo tail -f /var/log/zabbix/zabbix_server.log
+````
+## De clients
+Deze moeten uiteraard ook op de hoogte gebracht worden van de cluster. Hiervoor kunnen we simpelweg beide servers toevoegen aan de configuratie. werk je met proces? Dan moet de client uiteraard met de Proxy verbinden en moet de Proxy beide servers kennen.
+
+```
+...
+ServerName=zn1.winderickx.me,zn2.winderickx.me
+ServerActive=zn1.winderickx.me,zn2.winderickx.me
+...
+```
+
+## Niet vergeten!
+Omdat we naar een andere server verbinden moeten we de firewall en SELinux aanpassen om verbindingen toe te staan:
+
+> Als je niet goed weet hoe ik op de SELinux policy ben gekomen, zet SELinux dan op Permissive met ``sudo setenforce 0`` en neem een kijkje in de audit log: ``sudo tail -100 /var/log/audit/audit.log | audit2why | less``
+
+````bash
+# Firewall regels voor Zabbix
+sudo firewall-cmd --add-port=10050/tcp --permanent
+sudo firewall-cmd --add-port=10051/tcp --permanent
+sudo firewall-cmd --reload
+# SELinux policy voor Zabbix
+sudo setsebool -P zabbix_can_network 1
+````
\ No newline at end of file
diff --git a/posts/bali.md b/posts/bali.md
deleted file mode 100644
index a589ffc..0000000
--- a/posts/bali.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-author: Siddhartha Mukherjee
-date: '2019-07-10T07:00:00.000Z'
-hero_image: /alfons-taekema-bali.jpg
-title: 'Bali —body, mind & soul'
----
-
-The term **bristlecone pine** covers three [species](https://en.wikipedia.org/wiki/Species 'Species') of [pine](https://en.wikipedia.org/wiki/Pine 'Pine') tree (family [Pinaceae](https://en.wikipedia.org/wiki/Pinaceae 'Pinaceae'), genus [_Pinus_](https://en.wikipedia.org/wiki/Pinus 'Pinus'), subsection _Balfourianae_). All three species are long-lived and highly resilient to harsh weather and bad soils. One of the three species, _Pinus longaeva_, is among the longest-lived life forms on Earth. The oldest _Pinus longaeva_ is more than 5,000 years old,[\[1\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-oldest-1) making it the oldest known individual of any species.
-
-
-
-Despite their potential age and low reproductive rate, bristlecone pines, particularly _Pinus longaeva_, are usually a [first-succession](https://en.wikipedia.org/wiki/Primary_succession 'Primary succession') species, tending to occupy new open ground.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2) They generally compete poorly in less-than-harsh environments, making them hard to cultivate.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2) In gardens, they succumb quickly to root rot.[\[3\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-3) They do very well, however, where most other plants cannot even grow, such as in rocky [dolomitic]( 'Dolomite (mineral)') soils in areas with virtually no rainfall.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2)
-
-Bristlecone pines grow in scattered [subalpine](https://en.wikipedia.org/wiki/Subalpine 'Subalpine') groves at high altitude in arid regions of the [Western United States](https://en.wikipedia.org/wiki/Western_United_States 'Western United States'). Bristlecones, along with all related species in class Pinopsida, are [cone-bearing](https://en.wikipedia.org/wiki/Conifer_cone 'Conifer cone') [seed plants](https://en.wikipedia.org/wiki/Seed_plant 'Seed plant') commonly known as [conifers](https://en.wikipedia.org/wiki/Conifer 'Conifer'); the name comes from the prickles on the female cones.[\[4\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-ARKive-4)
diff --git a/posts/iceland.md b/posts/iceland.md
deleted file mode 100644
index 10f6f90..0000000
--- a/posts/iceland.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: A trip to Iceland
-author: 'Watson & Crick '
-date: '2019-07-10T16:04:44.000Z'
-hero_image: /norris-niman-iceland.jpg
----
-Pseudotsuga menziesii is an evergreen conifer species in the pine family, Pinaceae. It is native to western North America and is known as Douglas fir,Douglas-fir,Oregon pine,and Columbian pine. There are two varieties: coast Douglas-fir (P. menziesii var. menziesii), and Rocky Mountain Douglas-fir (P. menziesii var. glauca).
-
-Chicharrones kinfolk tumblr narwhal venmo. Iceland cloud bread 8-bit, hashtag single-origin coffee keffiyeh drinking vinegar cray banjo four dollar toast bespoke tbh live-edge celiac. YOLO dreamcatcher hot chicken selvage portland XOXO, single-origin coffee sustainable mustache thundercats fixie pour-over hexagon irony deep v. Farm-to-table ennui mixtape marfa raw denim austin hell of keffiyeh chia prism ethical. Polaroid biodiesel everyday carry VHS hot chicken chartreuse typewriter messenger bag. Cloud bread truffaut street art jean shorts chia.
\ No newline at end of file
diff --git a/posts/joshua-tree.md b/posts/joshua-tree.md
deleted file mode 100644
index e94c71b..0000000
--- a/posts/joshua-tree.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-author: Grace Hopper
-date: '2019-07-09T16:04:44.000Z'
-hero_image: /johannes-andersson-joshua-tree.jpg
-title: An otherworldly desert
----
-The Joshua tree is also called _izote de desierto_ (Spanish, "desert dagger").[\[6\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-ITIS-6) It was first formally described in the botanical literature as _Yucca brevifolia_ by [George Engelmann](https://en.m.wikipedia.org/wiki/George_Engelmann "George Engelmann") in 1871 as part of the Geological Exploration of the 100th meridian (or "[Wheeler Survey](https://en.m.wikipedia.org/wiki/Wheeler_Survey "Wheeler Survey")").[\[7\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-IPNI-7)
-
-The name "Joshua tree" is commonly said to have been given by a group of [Mormon](https://en.m.wikipedia.org/wiki/Mormon "Mormon") settlers crossing the Mojave Desert in the mid-19th century: The tree's role in guiding them through the desert combined with its unique shape reminded them of [a biblical story](https://en.m.wikipedia.org/wiki/Conquest_of_Ai "Conquest of Ai") in which [Joshua](https://en.m.wikipedia.org/wiki/Joshua "Joshua") keeps his hands reached out for an extended period of time to guide the Israelites in their conquest of Canaan ([Joshua 8:18–26](https://en.wikisource.org/wiki/Bible_(King_James)/Joshua#8:18 "s:Bible (King James)/Joshua")).[\[8\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-jtnp-8)[\[9\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-9)[\[10\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-10) However, no direct or contemporary attestation of this origin exists, and the name Joshua tree is not recorded until after Mormon contact;[\[8\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-jtnp-8)[\[11\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-11) moreover, the physical appearance of the Joshua tree more closely resembles [a similar story](https://en.m.wikipedia.org/wiki/Rephidim "Rephidim") told of [Moses](https://en.m.wikipedia.org/wiki/Moses "Moses").[\[12\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-12)
-
-Ranchers and miners who were contemporary with the Mormon immigrants used the trunks and branches as fencing and for fuel for ore-processing steam engines. They referred to these fallen or collapsed Joshua trees as _tevis_ stumps.\[_[citation needed](https://en.m.wikipedia.org/wiki/Wikipedia:Citation_needed "Wikipedia:Citation needed")_\]
-
-In addition to the [autonymic](https://en.m.wikipedia.org/wiki/Autonym_(botany) "Autonym (botany)") [subspecies](https://en.m.wikipedia.org/wiki/Subspecies "Subspecies") _Yucca brevifolia_ subsp. _brevifolia_, two other subspecies have been described:[\[13\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-13) _Y. b._ subsp. _jaegeriana_ (the Jaeger Joshua tree or Jaeger's Joshua tree or pygmae yucca) and _Y. b._ subsp. _herbertii_ (Webber's yucca or Herbert Joshua tree), though both are sometimes treated as varieties[\[6\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-ITIS-6)[\[14\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-Grandtner2005-14)[\[15\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-15) or forms.[\[16\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-Egglid2001-16)
-
-##
\ No newline at end of file
diff --git a/posts/mauritius.md b/posts/mauritius.md
deleted file mode 100644
index e320424..0000000
--- a/posts/mauritius.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: The hidden paradise
-author: Father John Misty
-date: '2019-07-08T16:05:29.000Z'
-hero_image: /john-o-nolan-mauritius.jpg
----
-**Juniperus scopulorum**, the Rocky Mountain juniper, is a species of juniper native to western North America, in Canada in British Columbia and southwest Alberta, in the United States from Washington east to North Dakota, south to Arizona and also locally western Texas, and northernmost Mexico from Sonora east to Coahuila. It grows at altitudes of 500–2,700 metres (1,600–8,900 ft) on dry soils, often together with other juniper species. "Scopulorum" means "of the mountains.
-
-
-
-Chicharrones kinfolk tumblr narwhal venmo. Iceland cloud bread 8-bit, hashtag single-origin coffee keffiyeh drinking vinegar cray banjo four dollar toast bespoke tbh live-edge celiac. YOLO dreamcatcher hot chicken selvage portland XOXO, single-origin coffee sustainable mustache thundercats fixie pour-over hexagon irony deep v. Farm-to-table ennui mixtape marfa raw denim austin hell of keffiyeh chia prism ethical. Polaroid biodiesel everyday carry VHS hot chicken chartreuse typewriter messenger bag. Cloud bread truffaut street art jean shorts chia.
\ No newline at end of file
diff --git a/public/Bind_Cover.png b/public/Bind_Cover.png
new file mode 100644
index 0000000..2e61477
Binary files /dev/null and b/public/Bind_Cover.png differ
diff --git a/public/Documentation_Cover.png b/public/Documentation_Cover.png
new file mode 100644
index 0000000..4d5d283
Binary files /dev/null and b/public/Documentation_Cover.png differ
diff --git a/public/GitBranchGraph.png b/public/GitBranchGraph.png
new file mode 100644
index 0000000..1623baa
Binary files /dev/null and b/public/GitBranchGraph.png differ
diff --git a/public/GitConflictSolved.png b/public/GitConflictSolved.png
new file mode 100644
index 0000000..f0b7839
Binary files /dev/null and b/public/GitConflictSolved.png differ
diff --git a/public/GitMergeConflict.png b/public/GitMergeConflict.png
new file mode 100644
index 0000000..751bfeb
Binary files /dev/null and b/public/GitMergeConflict.png differ
diff --git a/public/GitStashRebase.png b/public/GitStashRebase.png
new file mode 100644
index 0000000..9e91cd1
Binary files /dev/null and b/public/GitStashRebase.png differ
diff --git a/public/Git_Masterclass_Cover.png b/public/Git_Masterclass_Cover.png
new file mode 100644
index 0000000..22ed51c
Binary files /dev/null and b/public/Git_Masterclass_Cover.png differ
diff --git a/public/GitlabDuplicates.png b/public/GitlabDuplicates.png
new file mode 100644
index 0000000..e3f7780
Binary files /dev/null and b/public/GitlabDuplicates.png differ
diff --git a/public/GitlabSnapshots.png b/public/GitlabSnapshots.png
new file mode 100644
index 0000000..7695a89
Binary files /dev/null and b/public/GitlabSnapshots.png differ
diff --git a/public/GitlabUpToDate.png b/public/GitlabUpToDate.png
new file mode 100644
index 0000000..60d159c
Binary files /dev/null and b/public/GitlabUpToDate.png differ
diff --git a/public/GitlabUpgradeDocumentation.png b/public/GitlabUpgradeDocumentation.png
new file mode 100644
index 0000000..77ee19c
Binary files /dev/null and b/public/GitlabUpgradeDocumentation.png differ
diff --git a/public/GitlabUpgradePaths.png b/public/GitlabUpgradePaths.png
new file mode 100644
index 0000000..e10f061
Binary files /dev/null and b/public/GitlabUpgradePaths.png differ
diff --git a/public/GitlabUpgrading.png b/public/GitlabUpgrading.png
new file mode 100644
index 0000000..b2557b4
Binary files /dev/null and b/public/GitlabUpgrading.png differ
diff --git a/public/Logging.png b/public/Logging.png
new file mode 100644
index 0000000..be56bbe
Binary files /dev/null and b/public/Logging.png differ
diff --git a/public/RPM.png b/public/RPM.png
new file mode 100644
index 0000000..331750c
Binary files /dev/null and b/public/RPM.png differ
diff --git a/public/SELinuxPrecess.png b/public/SELinuxPrecess.png
new file mode 100644
index 0000000..4464d01
Binary files /dev/null and b/public/SELinuxPrecess.png differ
diff --git a/public/SELinuxProcess.png b/public/SELinuxProcess.png
new file mode 100644
index 0000000..8b80070
Binary files /dev/null and b/public/SELinuxProcess.png differ
diff --git a/public/SELinuxZabbix1.png b/public/SELinuxZabbix1.png
new file mode 100644
index 0000000..27fe687
Binary files /dev/null and b/public/SELinuxZabbix1.png differ
diff --git a/public/SELinuxZabbix2.png b/public/SELinuxZabbix2.png
new file mode 100644
index 0000000..e9ad186
Binary files /dev/null and b/public/SELinuxZabbix2.png differ
diff --git a/public/SELinuxZabbix_Cover.png b/public/SELinuxZabbix_Cover.png
new file mode 100644
index 0000000..b138e73
Binary files /dev/null and b/public/SELinuxZabbix_Cover.png differ
diff --git a/public/SELinux_AuditLog.png b/public/SELinux_AuditLog.png
new file mode 100644
index 0000000..ddb0010
Binary files /dev/null and b/public/SELinux_AuditLog.png differ
diff --git a/public/SELinux_FoutieveSecurityContext.png b/public/SELinux_FoutieveSecurityContext.png
new file mode 100644
index 0000000..1b88397
Binary files /dev/null and b/public/SELinux_FoutieveSecurityContext.png differ
diff --git a/public/SELinux_cover.png b/public/SELinux_cover.png
new file mode 100644
index 0000000..db16977
Binary files /dev/null and b/public/SELinux_cover.png differ
diff --git a/public/SSH_cover.png b/public/SSH_cover.png
new file mode 100644
index 0000000..8de0092
Binary files /dev/null and b/public/SSH_cover.png differ
diff --git a/public/SyncRPM-Slack.png b/public/SyncRPM-Slack.png
new file mode 100644
index 0000000..13728c8
Binary files /dev/null and b/public/SyncRPM-Slack.png differ
diff --git a/public/SyncRPM-cover.png b/public/SyncRPM-cover.png
new file mode 100644
index 0000000..6a4bbfb
Binary files /dev/null and b/public/SyncRPM-cover.png differ
diff --git a/public/Vault_cover.png b/public/Vault_cover.png
new file mode 100644
index 0000000..0007c4a
Binary files /dev/null and b/public/Vault_cover.png differ
diff --git a/public/ZabbixBackup_Cover.png b/public/ZabbixBackup_Cover.png
new file mode 100644
index 0000000..651bb94
Binary files /dev/null and b/public/ZabbixBackup_Cover.png differ
diff --git a/public/ZabbixHACluster_cover.png b/public/ZabbixHACluster_cover.png
new file mode 100644
index 0000000..c71999d
Binary files /dev/null and b/public/ZabbixHACluster_cover.png differ
diff --git a/public/ZabbixProm1.png b/public/ZabbixProm1.png
new file mode 100644
index 0000000..d74d4a5
Binary files /dev/null and b/public/ZabbixProm1.png differ
diff --git a/public/ZabbixProm2.png b/public/ZabbixProm2.png
new file mode 100644
index 0000000..44a297d
Binary files /dev/null and b/public/ZabbixProm2.png differ
diff --git a/public/ZabbixProm3.png b/public/ZabbixProm3.png
new file mode 100644
index 0000000..0f7aa25
Binary files /dev/null and b/public/ZabbixProm3.png differ
diff --git a/public/ZabbixProm4.png b/public/ZabbixProm4.png
new file mode 100644
index 0000000..3daa9a1
Binary files /dev/null and b/public/ZabbixProm4.png differ
diff --git a/public/ZabbixProm5.png b/public/ZabbixProm5.png
new file mode 100644
index 0000000..b8815c2
Binary files /dev/null and b/public/ZabbixProm5.png differ
diff --git a/public/ZabbixProm6.png b/public/ZabbixProm6.png
new file mode 100644
index 0000000..1fbe45c
Binary files /dev/null and b/public/ZabbixProm6.png differ
diff --git a/public/ZabbixRebranding_cover.png b/public/ZabbixRebranding_cover.png
new file mode 100644
index 0000000..1fb299f
Binary files /dev/null and b/public/ZabbixRebranding_cover.png differ
diff --git a/public/awk.png b/public/awk.png
new file mode 100644
index 0000000..ba7909c
Binary files /dev/null and b/public/awk.png differ
diff --git a/public/champagne.gif b/public/champagne.gif
new file mode 100644
index 0000000..72cd7bf
Binary files /dev/null and b/public/champagne.gif differ
diff --git a/public/cover_ACL.png b/public/cover_ACL.png
new file mode 100644
index 0000000..5e30071
Binary files /dev/null and b/public/cover_ACL.png differ
diff --git a/public/cover_AutoFS.png b/public/cover_AutoFS.png
new file mode 100644
index 0000000..490a00e
Binary files /dev/null and b/public/cover_AutoFS.png differ
diff --git a/public/cover_GitlabUpgrade.png b/public/cover_GitlabUpgrade.png
new file mode 100644
index 0000000..a70a89f
Binary files /dev/null and b/public/cover_GitlabUpgrade.png differ
diff --git a/public/cover_LetsEncrypt.png b/public/cover_LetsEncrypt.png
new file mode 100644
index 0000000..ec5b9d4
Binary files /dev/null and b/public/cover_LetsEncrypt.png differ
diff --git a/public/cover_kickstart.png b/public/cover_kickstart.png
new file mode 100644
index 0000000..528ae40
Binary files /dev/null and b/public/cover_kickstart.png differ
diff --git a/public/cover_permissions.png b/public/cover_permissions.png
new file mode 100644
index 0000000..ebd8852
Binary files /dev/null and b/public/cover_permissions.png differ
diff --git a/public/cover_systemd.png b/public/cover_systemd.png
new file mode 100644
index 0000000..374770e
Binary files /dev/null and b/public/cover_systemd.png differ
diff --git a/public/eli.jpg b/public/eli.jpg
new file mode 100644
index 0000000..6e63588
Binary files /dev/null and b/public/eli.jpg differ
diff --git a/public/grep_cover.png b/public/grep_cover.png
new file mode 100644
index 0000000..d7f9d77
Binary files /dev/null and b/public/grep_cover.png differ
diff --git a/public/ventoy2disk_en.png b/public/ventoy2disk_en.png
new file mode 100644
index 0000000..7d5d004
Binary files /dev/null and b/public/ventoy2disk_en.png differ