Categoriearchief: linux

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.

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.

resultaat script afvangen

Bij het schrijven van bash script gebruik je uiteraard weer andere scripts in je eigen script (je kopieert toch niet elke keer dat zelfde stukje code??).
Om te beoordelen of een “sub”script goed is uitgevoerd moet je naar de exitcode van het script kijken, dit kan door gebruik te maken van de variabele $?.

ls -l
if [ $? -gt 0 ]
then
    # exit code is groter dan 0, dus een fout trad op
else
    # exit code is 0, alles ok
fi

Wat je precies met het resultaat doet is natuurlijk afhankelijk van je script.
Let wel op dat bij elk volgend uitgevoerd commando de variabele opnieuw ingesteld wordt. Ook wordt de uitvoer van het commando niet afgevangen. Dat kan je eventueel ondervangen door hetvolgende te doen:

output=`ls -l`
resultcode=$?

Je hebt nu 2 variabelen. $output bevat de output van het commando, $resultcode bevat de errorcode.

linux bash script interactief of niet?

Scripts onder linux bash kunnen op verschillende manieren gestart worden. De gebruiker kan handmatig het script starten met een druk op de knop. Maar wat vaker gebeurd is dat een script gestart wordt door linux zelf zonder tussenkomst van de gebruiker. Dit zal meestal een geplande cronjob zijn.
Groot verschil hierin is of de gebruiker input kan geven, bij afwezigheid van een gebruiker kan je in een script lang wachten op antwoord. Ook is het soms handiger om minder output te geven in een niet-interactief script. Hoewel foutmeldingen wel prettig zijn is “algemene voortgang” minder relevant, er zit immers niemand naar te kijken.

Uitvinden of het script interactief is is heel simpel:

if [ -z $PS1 ]
then
    # interactief
else
    # niet interactief
fi

wat is de huidige gebruiker in een linux bash script?

Soms heb je een bash script wat uitgevoerd moet worden door root, of juist door een andere specifieke gebruiker. Elke keer opletten of je met de juiste user het script start is iets wat snel misgaat. Dus controleren in het script wordt uitgevoerd met de juiste user is geen overbodige luxe.

Er zijn meerdere manieren om te bepalen wie de huidige user is, het meerst voor de hand ligt het commando `id`:

# toon lijst met informatie
id
### >> uid=0(root) gid=0(root) groups=0(root)

Maar dat is niet echt prettig om te verwerken, gelukkig zijn er parameters.

# toon user id
id -u
### >> 0

# toon primaire group id
id -g
### >> 0

# toon de id's van alle groepen waar de user lid van is
id -G
### >> 0

Als extra parameter kan -n worden meegegeven waarmee niet het id, maar de naam wordt getoond.

Bij het controleren of de huidige user root is is het niet verstandig om te kijken naar de username “root”. De username zou gewijzigd kunnen zijn. Verstandiger is om te kijken naar het userid 0.

Er zijn ook nog alternatieven.
Het commando `whoami` is ook een optie, maar die is beperkter en komt feitelijk neer op het commando `id -un`.