root email afleveren op een remote email adres

Met regelmaat wordt er op linux servers een mail gestuurd aan “root”. Deze wordt dan gepoogd af te leveren in een mailbox, maar meestal eindigt deze lokaal.
Niet heel erg handig. Meestal is het prettiger als deze email op een externe server of emailadres afgeleverd wordt die ook daadwerkelijk gemonitord wordt.

Hiervoor is wel enige nodige configuratie nodig en zijn een aantal dingen van elkaar afhankelijk.

Deze uitleg gaat er vanuit dat je gebruik maakt van postfix als versturende mailserver op de server. Hij gaat er ook vanuit dat postfix op zichzelf al in staat is email te versturen naar externe emailadressen. Het gaat dus enkel om de configuratie om lokale email aan lokale gebruikers (zoals root) af te leveren op een extern adres.

Allereerst bepaald linux bij het versturen van email waar deze heen gestuurd moet worden.

#/etc/mailname
mijn-server-naam

Geef hier een logische naam op, maar niet het domein waar de email uiteindelijk afgeleverd moet worden. Het kan ook localhost zijn.

Om onduidelijke redenen (voor mij althans), wordt soms ook een hostname gevist van een andere locatie, het is dus ook verstandig om deze schoon te houden:

#/etc/hosts
127.0.0.1 localhost
127.0.0.1 mijn-server-naam mijn-server-naam.mijn-domein.tld

Localhost lijkt meestal genegeerd te worden, maar andere waarden niet.

Als dit is aangepast weet je dat email aan de user root wordt verstuurd aan “root@mijn-server-naam”. Nu moeten we nog zorgen dat de mailserver weet dat dit lokaal verwerkt moet worden.

# /etc/postfix/main.cf ; selectieve regels
myhostname = localhost
mydestination = localhost, mijn-server-naam, mijn-server-naam.mijn-domein.tld

Dit zorgt ervoor dat postfix deze email lokaal gaat proberen af te leveren.

Maar we wilden deze email toch helemaal niet lokaal hebben? De email moest naar een extern emailadres afgeleverd worden.
Hier komen aliases in beeld. Deze zorgen ervoor dat lokale email doorgestuurd wordt. Dit kan zowel lokaal als naar een extern emailadres.

# /etc/aliases
postmaster:    ik
root:          ik
ik:            ik@mijn-domein.tld

Deze configuratie zorgt ervoor dat email aan de gebruikers “postmaster” en “root” afgeleverd worden bij de lokale gebruiker “ik”. Email aan de gebruiker “ik” wordt weer doorgestuurd naar een extern emailadres.

Na het aanpassen moet je de aanpassingen nog actief maken:

$ newaliases
$ service postfix restart

Zorg er natuurlijk wel voor dat postfix in staat is om email op een extern emailadres af te leveren.

git undo commit, soft style

Wat te doen als je een commit ongedaan wil maken, maar toch de wijzigingen wil behouden?

Gebruik simpelweg hetvolgende commando:

$ git reset --soft HEAD~1

Hiermee zet je de huidige branch 1 commit terug, maar de wijzigingen blijven in de index staan. Zou je direct weer een commit doen, dan krijg je exact dezelfde commit (afgezien dan van het tijdstip en de commit message).

Dit kan vooral handig zijn als je aanpassingen tijdelijk hebt opgeslagen in een commit, ipv een stash.
Hoewel je ook een amend commit kan doen, is het soms makkelijker te zien welke aanpassingen je allemaal hebt gedaan. Dan komt dit heel mooi uit.

git revert commit

Is een bepaalde commit perongeluk in de master branch terecht gekomen? Of wil je simpelweg de wijzigingen uit 1 specifieke commit ongedaan maken?
Dat kan vrij simpel met hetvolgende commando:

$ git revert -n <commit hash>

Hiermee worden de wijzigingen uit de opgegeven commit ongedaan gemaakt. Je moet de revert nog wel commmitten.

git push en tracking remote branch

Vervelend soms als je een nieuwe git branch naar een remote repository pusht, maar hij niet gelijk tracking wordt. Hierdoor is git pull ineens lastig te gebruiken omdat je de juiste parameters moet gaan opgeven.

De oplossing is vrij simpel, bij het initieel pushen de parameter -u toevoegen.

$ git push -u origin mycoolbranch

Hiermee wordt direct de tracking informatie ingesteld waarmee een pull later wordt vereenvoudigd.

Welke harde schijf zit waar aangesloten?

Soms moet je een fysieke schijf wisselen in een computer, maar heb je geen flauw idee welke schijf het nu precies is. Zeker als je veel schijven hebt en ze niet van buiten gemarkeerd hebt kan dat lastig zijn.
Onder linux is dat echter vrij simpel te achterhalen. Installeer hiervoor het pakket smartmontools.

user@system# apt-get install smartmontools

Daarna kan je met hetvolgende commando het serienummer van de schijf ophalen.

user@system# smartctl -d ata -a /dev/sdb | grep Serial
Serial Number:    WD-WCAZAxxxxxxx

Dit geeft het serienummer van je schijf. Dit staat altijd op de buitenkant van de schijf vermeld.

wanneer je de grep weglaat krijg je nog meer informatie over de schijf, mogelijk is dat ook al genoeg informatie wanneer je allemaal verschillende type schijven hebt.

Linux software RAID herstellen onder Ubuntu

RAID is ideaal om ervoor te zorgen dat je server blijft draaien. Bij de installatie van Ubuntu is RAID supersimpel om in te stellen.
Maar wat nu precies te doen bij uitval van een harde schijf? Helaas is er dan geen mooie wizard, maar ingewikkeld is het niet.

Je kan de volgende stappen gebruiken om een schijf te vervangen door een nieuwe.

  1. Maak een backup van de structuur van de schijf, deze structuur kan je gebruiken om te zorgen voor een exacte kopie.
    user@system# sfdisk -d /dev/sdb >~/raid.diskformat.backup

    eventueel kan je een kopie maken van een nog werkende schijf mocht je schijf echt de geest gegeven hebben.

  2. Zorg dat de defecte schijf uit de raid configuratie gehaald wordt.
    user@system# mdadm --manage /dev/md0 --fail /dev/sdb1
    user@system# mdadm --manage /dev/md0 --remove /dev/sdb1
  3. Verwijder de defecte schijf en plaats de nieuwe schijf in het systeem.
  4. Bereid de nieuwe partities voor op de nieuwe schijf. (dit kan eventueel op een andere computer).
    user@system# sfdisk /dev/sdb < ~/raid.diskformat.backup

    Controleer of het inderdaad weer /dev/sdb is, dit kan anders zijn.
    Het is niet noodzakelijk dat de schijf exact hetzelfde formaat heeft. De partities die in de raid configuratie gezet worden uiteraard wel.

  5. Voeg de partitie toe aan de raid configuratie.
    user@system# mdadm --manage /dev/md0 --add /dev/sdb1
    mdadm: added /dev/sdb1
  6. Je kan de voortgang van het de recovery naar de nieuwe schijf volgen:
    user@system# cat /proc/mdstat 
    Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] 
    md0 : active raid1 sdb1[2] sda1[0]
          488280000 blocks [2/1] [U_]
          [>....................]  recovery =  4.6% (22806912/488280000) finish=109.4min speed=70905K/sec
          
    unused devices: <none>

Na verloop van tijd zal je RAID weer als voorheen functioneren.

De snelheid van herstel kan te wensen overlaten, ook daar is gelukkig wat aan te doen. Er zijn 2 instellingen die van invloed zijn op de snelheid van de recovery. Die zijn alsvolgt op te vragen.

user@system# sysctl dev.raid.speed_limit_min
dev.raid.speed_limit_min = 100000
user@system# sysctl dev.raid.speed_limit_max
dev.raid.speed_limit_max = 200000

Aanpassen van de limieten is ook mogelijk:

user@system#echo 100000 >/proc/sys/dev/raid/speed_limit_min

De aanpassing is vrijwel direct. Let er wel op dat je systeem niet overbelast raakt.

verwijderen van git branches en tags

Met regelmaat zal je een branch verwijderen in git. Lokaal is dit eenvoudig:

# verwijder een lokale branch
git branch -d <branch>

Maar remote is dat een iets complexer verhaal:
Gebruik je een versie ouder dan 1.7.0, dan is dit het antwoord:

# verwijder een remote branch, oude stijl
git push origin :<branch>

Niet echt duidelijk wat er nu gebeurd, daarom vanaf versie 1.7.0:

# verwijder een remote branch, nieuwe stijl
git push --delete origin <branch>

Voor tags is de syntax bijna hetzelfde:

# verwijder lokale tag
git tag -d <tag>

# verwijder remote tag in versie's ouder dan 1.7.0
git push origin :refs/tags/<tag>

# verwijder remote tag in versie's vanaf 1.7.0
git push --delete origin <tag>

Tenslotte worden remote branches ook wel eens door anderen verwijderd. Dit wordt niet automatisch bijgewerkt door git wanneer je pullt of fetched.
Ook hiervoor is een simpele methode om dit bij te werken:

# update de lokale database van remote branches
git remote prune origin

En daarmee staat weer een stukje van mijn geheugen online :).

git gebruiken bij het live zetten van nieuwe versies

Wanneer je regelmatig wijzigingen doet aan een applicatie die op meerdere computers draait, is het prettig dat dit makkelijk bijgewerkt kan worden. Dit kan je doen door tags te maken en bij het updaten de laatste tag op te zoeken. Groot nadeel hiervan is echter wel dat je op een gegeven moment een heleboel tags hebt die je niet meer gebruikt.

Een betere oplossing is een wandelende verwijzing naar welke versie je op dit moment wil gebruiken. Hiervoor is een branch meer geschikt. Tags zijn immers niet bedoeld om te verplaatsen.

Kortom, we maken een branch aan dit enkel gebruikt wordt om de versie aan te wijzen welke in productie gebruikt moet worden. Dit natuurlijk in je ontwikkelomgeving.

git branch production
git push -u origin production

Elke keer als je de versie wil wijzigen die in productie gebruikt moet worden wil wijzigen verplaats je de branch. Hoe je dat doet maakt niet zoveel uit, maar meestal zal het een merge zijn waarvoor fast-forward mogelijk is. Je branch production zal dus meestal achter je master aanlopen.

Op de locatie waar de code daadwerkelijk gebruikt wordt kan dan vrij simpel gecontroleerd worden of er een wijziging is:

# zorg dat de remote informatie bijgewerkt is
git fetch origin

# vind de hash van de huidige commit die actief is
commithead=`git rev-parse HEAD`

# vind de hash van de commit van de laatste versie
commitprod=`git rev-parse origin/production`

Het ophalen van de hashes maakt het in bash eenvoudig om te zien of de branch verplaatst is zonder een diff te hoeven opvragen.

Het opvragen van de verschillen kan alsvolgt:

if [ "${commithead}" != "${commitprod}" ]
then
    # toon een samenvatting van de wijzigingen
    git diff ${commithead} ${commitprod} --stat

    # toon een compleet overzicht van de wijzigingen
    git diff ${commithead} ${commitprod}

    # checkout nieuwe wijzigingen
    git checkout origin/production
fi

In een iets uitgebreider script werkt dit natuurlijk beter. Maar het idee is zo simpel als dit.