tmux cheatsheet

tmux is an awesome tool to manage terminal windows and to keep your terminal session running while you log on / off the computer. It works like GNU screen but better. Inside an tmux session you can have multiple windows or split your window into mulitple panes and switch betwee all of them.

Manage sessions from terminal

tmux new -s session-name         start named session
tmux a (-t session-name)         attach a (named) session
tmux ls                          list all sessions While running tmux: (ctrl+b)

While running tmux (ctrl+b)

Control windows

c        create window
w        list windows
n        next window
p        previous window
f        find window
,        name window
&        kill window

Control panes

%        vertical split
"        horizontal split
o        swap panes
q        show pane numbers
x        kill pane
+        break pane into window (e.g. to select text by mouse to copy)
-        restore pane from window
t        big clock

Control Sessions

s        list sessions
$        name session
:new<CR> new session
d        detach session

Self signed SSL certificaten

Ik draai al jaren een website met een self signed SSL certificaat. Op zich werkt dit perfect behalve dat Chrome op mijn Android telefoon van tijd tot tijd me weer een waarschuwing geeft. Open je de site vanaf je Homescreen als standalone web app dan blijf je ook altijd een balk zien met een rood kruis (ongeldig certificaat). Ik heb al eens eerder geprobeerd om het SSL certificaat toe te voegen aan Android zodat deze vertrouwd zou zijn echter lukte dit steeds niet.

Vandaag kwam ik er achter dat je aan Android alleen root CA certificaten kan toevoegen. Tegelijkertijd kwam ik er meer achter hoe SSL certificaten werken en wat nu een root Certificate Authority (CA) is. Voor de uitleg over root CA verwijs ik naar dit filmpje.

Zodra je dus een root certificaat toevoegd aan je browser worden automatische alle certificaten die ondertekend zijn met dit root certificaat zonder problemen geaccepteerd. Ideaal dus voor een testomgeving of wanneer je zelf meerdere domeinen host met een self signed certificaat.

Een root certificaat aanmaken

Als eerste genereren we een private key

$ openssl genrsa 8192 > rootca.key

Genereer daarna het certificaat. Pas het aantal dagen dat deze geldig is naar wens aan. Ik heb deze op 10 jaar staan.

$ openssl req -x509 -new -nodes -key rootca.key -days 3652 > rootca.pem

Tijdens het aanmaken van het certificaat worden je enkele gegevens gevraagd en daarna is het certificaat gegenereerd. Dit certificaat kun je nu zonder problemen toevoegen aan bijvoorbeeld Chrome en Firefox. Voor Android moeten we nog een extra stap doen.

Format aanpassen voor Android

Voer de onderstaande code uit om het format van het certificaat aan te passen naar DER.

$ openssl x509 -in rootca.pem -outform der -out rootca.der.crt

Dit aangepaste certificaat kun je het makkelijkst naar Android krijgen door deze op via een url beschikbaar te maken. Wanneer je dan naar de betreffende URL gaat op je telefoon zal automatisch gevraagd worden om het certificaat te installeren. Geef een naam op en druk op opslaan. Je kan dit certificaat terug vinden onder Settings -> Security -> Trusted Credentials -> User.

Android certificate install

Een certificaat maken

Opnieuw moeten we een private key genereren

openssl genrsa 4096 > mijndomein.nl.key

Hierna maken we een Certificate Signing Request (CSR)

openssl req -new -key mijndomein.nl.key > mijndomein.nl.csr

Vervolgens worden je wederom allerlei gegevens gevraagd. Het challenge password en de optional company name kun je gewoon leeg laten.

Wanneer je een certificaat wil maken voor een los domein kun je nu je certificaat genereren met het volgende commando. Wil je extra’s zoals een multi domain certificaat scroll sla deze stap dan over en ga naar extensions.

openssl x509 -req -days 3652 -CA rootca.pem -CAkey rootca.key -CAcreateserial -in mijndomein.nl.csr > mijndomein.nl.pem

Als laatste kun je nog een info bestand maken waarmee je de gegevens van het certificaat kan zien. Deze stap is echter optioneel.

openssl x509 -in mijndomein.nl.pem -text > mijndomein.nl.info

Extensions

Aangezien ik een multi domain certificaat wil hebben moeten we nog het e.a. toevoegen. Maak een bestand aan genaamd v3.ext en voeg daar de volgende opties aan toe. Pas de DNS regels aan naar je eigen wensen.

[mijndomein_ext]
basicConstraints         = critical,CA:false
keyUsage                 = critical,keyEncipherment,dataEncipherment
subjectKeyIdentifier     = hash
authorityKeyIdentifier   = keyid,issuer
subjectAltName           = @mijndomein_ext_subject

[mijndomein_ext_subject]
DNS.1 = mijndomein.nl
DNS.2 = *.mijndomein.nl

Nu kunnen we ons certificaat aan gaan maken.

openssl x509 -req -days 3652 -CA rootca.pem -CAkey rootca.key -CAcreateserial -in mijndomein.nl.csr -extfile v3.ext -extensions mijndomein_ext > mijndomein.nl.pem

Het certificaat is nu aangemaakt, deze kun je nu gebruiken is allerlei applicaties.

Beveiliging

Private keys mogen eigenlijk alleen door root gelezen worden. Dit omdat anders iedereen met toegang tot de keys deze kan lezen en dus ook nieuwe certificaten aanmaken. Voor daarom altijd een chown en een chmod uit.

chown root:root *.key
chmod 600 *.key

Certificaat gebruiken in Apache2

Om SSL te activeren binnen apache moet je het volgende toevoegen aan je virtualhost:

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/mijndomein.nl.pem
SSLCertificateKeyFile /etc/apache2/ssl/mijndomein.nl.key

Gebruikte bronnen:

Hyperion aan/uit zetten met een remote

Overdag heb je niet zo veel aan Ambilight en het leek me wel leuk als ik dit aan en uit kon zetten met mijn afstandsbediening. Mijn Rasberry Pi kan bediend worden door middel van CEC waardoor ik met de afstandsbediening van de TV direct Kodi aan kan sturen.

Als eerste moeten we een scriptje maken voor het aan / uit zetten van Hyperion. Plaats de volgende code in /storage/ledsremote.sh.

#!/bin/sh
if [ -z `pidof hyperiond` ]
then
    echo "$USER" > /storage/user.txt
    curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":1,"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"Hyperion","message":"Enabled","image":"/storage/hyperion.png"}}' http://127.0.0.1:80/jsonrpc
    LD_LIBRARY_PATH=/storage/hyperion/bin 
    /storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /dev/null 2>&1 &
else
    echo "$USER" > /storage/user.txt
    curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":1,"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"Hyperion","message":"Disabled","image":"/storage/hyperion.png"}}' http://127.0.0.1:80/jsonrpc
    killall hyperiond
fi

Maak deze vervolgens executable.

chmod +x /storage/ledsremote.sh

Door dit script aan te roepen kunnen we nu Hyperion aan en uitzetten. We moeten alleen nog zorgen dat dit gemapped word aan de afstandsbediening. Kopieer de standaard keyboard configuratie naar de kodi userdata map zodat we deze kunnen wijzigen.

cp /usr/share/kodi/system/keymaps/remote.xml /storage/.kodi/userdata/keymaps/remote.xml

Zoek vervolgens een key uit in de <global> sectie waar je de actie aan wil koppelen. In mijn geval heb ik dit met de key <red> gedaan. Pas de waarde als volgt aan:

<red>System.Exec("/storage/ledsremote.sh")</red>

Start je Raspberry Pi opnieuw op en als het goed is kun je de leds nu aan en uitzetten met je afstandsbediening!

Met dank aan deze blog.

OpenElec 1920×1080 met de TV uit

OpenElec vind het bij mij niet leuk wanneer de TV uitstaat tijdens het booten. De resolutie blijft dan hangen op 640×480. Dit is op te lossen op de volgende manier. Login op de Raspberry Pi via SSH en dan de volgende commando’s uit.

mount -o remount,rw /flash
tvservice -d /flash/edid.dat
 
# optional you can view the edid details if you want.
edidparser /flash/edid.dat

Vervolgens moeten we het /flash/config.txt bestand wijzigen en zorgen dat daar de volgende twee regels in staan:

nano /flash/config.txt
hdmi_edid_file=1 
hdmi_force_hotplug=1

DIY Ambilight m.b.v. Raspberry pi, Arduino, Openelec en Hyperion

Ik heb op het internet al vaker iets voorbij zien komen over mensen die hun eigen Ambilight maakten. Ik vond dit altijd al een tof idee maar het is er al die tijd niet van gekomen. Laatst begon het toch weer te kriebelen en heb ik besloten er zelf ook een te bouwen.

Nadat ik alle spullen binnen had ben ik begonnen met het aansturen van de Leds. Dit lukte vrij snel.  Ik kon met behulp van de FastLed library makkelijk wat simpele effecten maken op de led strip.

Mijn TV is aan de achterkant niet mooi vlak. Ik heb daarom een frame gemaakt van aluminium strips met een randje voor extra stevigheid. Het frame heb ik op maat gezaagd en toen aan elkaar gelijmd met secondelijm. Het resultaat is een mooi stevig maar toch licht frame.

Nu was het tijd om de leds op maat te knippen en de stekkertjes er aan te solderen. Omdat ik weinig soldeer ervaring had ging het eerste stukje ging wat lastig maar daarna ging het erg gemakkelijk.

Vervolgens een laagje isolatietape aangebracht op mijn frame omdat ik niet zou willen dat de leds maar op een of andere manier contact zouden maken met het aluminium. Nadat ik de horizontale strips geplaatst had heb ik bij de soldeerpunten nog een stukje tape er overheen geplakt en toen de verticale strips aangebracht.

Daarna twee gaatjes geboord in het frame en met twee M6 bouten gemonteerd aan mijn tv met een PVC koppelstukje er tussen om het frame op zijn plaats te houden. De Arduino zit links in de hoek gemonteerd met een paar tie-wraps. Vanaf die hoek worden ook de leds gevoed / aangestuurd. Inmiddels is de blauwe USB kabel vervangen door een zwarte van 1~1.5 meter. Ik heb nu dus maar twee kabels naar mijn TV lopen, de voeding van de leds en de USB voor de Arduino. De rest van alle spullen kan ik mooi 1.5e meter verder verstoppen.

Close-up van de Arduino. Ik heb nog een simpele case besteld uit China dus de Arduino gaat straks nog wat mooier weggewerkt worden.

Dit is de rest van de opstelling (voor nu). De Pi2 word gevoed door mijn 5v voeding. Mijn oude Pi1 voeding gaf te weinig power en dit is toch weer een stekker minder. Ik heb een 100watt 16A voeding maar volgens mijn energiemeter was dat toch wel overkill. Met 4 meter leds (60 leds p.m.) kwam ik op 40 watt uit (volledige sterkte wit licht, zonder Pi). Ik heb nu 3 meter leds en met de Pi + AV-grabber, etc straks zal ik ook wel weer rond de 40 watt maximaal uit komen. De dikke zwarte kabel gaat dus naar de leds toe. In de Pi zit een netwerkkabel en de USB kabel naar de Arduino.

En dit is hoe het er nu uitziet. Ik moet de kleuren wel nog wat bij stellen omdat ze niet helemaal overeenkomen met de kleuren van de TV maar het systeem werkt echt fantastisch. Ben er echt super blij mee. Ik was toch redelijk verbaast hoe goed het werkt.

Klik verder voor een installatie handleiding die ik geschreven heb mocht je zelf ook interesse gekregen hebben om zelf een Ambilight TV te knutselen. Er zijn tegenwoordig ook meer klant en klaar oplossingen zoals Ambivision en Lightberry.

Read More

Ubuntu 15.04 pam_mount

Onder Ubuntu 15.04 merkte ik dat de snelheden die ik haalde met lezen / schrijven naar mijn netwerk shares echt enorm laag waren (30 MB/s). Na van alles getest te hebben kwam ik er achter dat het waarschijnlijk ligt aan gvfs waarmee Ubuntu standaard de shares mount. Zoekende naar een oplossing kwam ik op pam_mount terecht. Nu haal ik snelheden van +/-80 MB/s.

Met behulp van pam_mount kun je tijdens het inloggen andere schijven / netwerk shares mounten met de zelfde gebruikersnaam / wachtwoord combinatie waarmee je inlogt. Het installeren van pam_mount gaat als volgt:

Installer pam_mount en cifs-utils. Die laatste is nodig als je een netwerk share wil mounten.

sudo apt-get install libpam-mount cifs-utils

Nu moeten we in het onderstaande bestand enkele wijzigingen doorvoeren.

sudo nano /etc/security/pam_mount.conf.xml

Haal de commentaar regels om de volgende regel weg.

<luserconf name=".pam_mount.conf.xml" />

Hiermee zorg je dat elke gebruiker zijn eigen configuratie bestand voor pam_mount kan maken. Indien je voor iedereen dezelfde configuratie wilt gebruiken kun je de betreffende regels ook onder aan in dit bestand kwijt.

Voor extra beveiliging kun je de opties file_mode en dir_mode toevoegen aan mntoptions

<mntoptions allow="nosuid,nodev,loop,encryption,fsck,nonempty,allow_root,allow_other,dir_mode,file_mode" />

Optioneel
Indien je home-dir encrypted is moeten we nog een extra aanpassing doen. Standaard word pam_mount namelijk uitgevoerd voordat je home-dir gedecrypt is. Hierdoor kan het configuratie bestand niet gelezen worden en word er dus ook niets gemount.

Wijzig de volgende twee bestanden.

/etc/pam.d/common-auth
/etc/pam.d/common-session

Zorg er in deze bestanden voor dat de pam_moun.so regel onder de pam_encryptfs.so regel staat.

auth    optional       pam_ecryptfs.so unwrap
auth    optional       pam_mount.so

Als laatste moeten we pam_mount vertellen wat hij precies moet gaan mounten en waar. Dit doen we met een bestandje in je home-dir. Zet hier de onderstaande xml code in en wijzig deze naar jouw eigen voorkeuren. Indien je dir_mode en file_mode in de eerdere stap toegevoegd hebt dien je die hier ook weer te gebruiken. De mode 0700 zorgt er voor dat jij de enige bent die in de gemounte share kan lezen / schrijven.

nano ~/.pam_mount.conf.xml
<?xml version="1.0" encoding="utf-8" ?>
<pam_mount>
    <volume
        options="nodev,nosuid,file_mode=0700,dir_mode=0700"
        user="*"
        mountpoint="/media/%(USER)/websites"
        server="nas"
        path="websites"
        fstype="cifs" />
</pam_mount>
  • user=”*” Geeft aan welke gebruikers de share mogen mounten. * is een wildcard voor alle gebruikers.
  • mountpoint=”” is het pad waar je schijf / share gemount wordt. Ik heb hier de variabele %(USER) gebruikt. Deze wordt gevuld met je ingevulde gebruikersnaam. In mijn geval wordt het dus /media/roy/websites
  • server=”” nas is het adres van mijn server. Hier kan ook een ip adres staan.
  • fstype=”cifs” cifs geeft aan dat het om een netwerk share gaat.

Reboot je PC en als het goed is zijn je schijven direct gemount na het inloggen. Mocht het niet zo zijn kun je de debug functie inschakelen in /etc/security/pam_mount.conf.xml . De logs worden dan geschreven naar /var/log/auth.log .

Samba performance

Er is veel te vinden over de performance van samba verbeteren. De volgende instellingen werken voor mij het beste. Plaats de volgende instellingen onder de [global] sectie van /etc/samba/smb.conf

# performance tuning
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
use sendfile = Yes
getwd cache = Yes
min receivefile size = 16384
use sendfile = true
aio read size = 16384
aio write size = 16384

CakePHP en gigabyte vs gibibyte

Iedereen kent het wel. Je koopt een harde schijf van 3 TB, je stopt hem in je PC en ineens is hij nog maar +/-2.7 TB. Wanneer fabrikanten / besturingssystemen de juiste eenheden zouden gebruiken zou dit al een stuk duidelijker zijn.  Voor meer informatie hierover zie Wikipedia.

CakePHP haalt GB en GiB helaas ook door elkaar in de CakeNumber en de NumberHelper class en ik stoorde me daaraan. De oplossing is simpel maar het werkt perfect.

In app/Lib/ van je CakePHP project maak je een nieuw bestand aan genaamd FixedCakeNumber.php. Hierin plaats je de volgende code:

<?php
App::uses('CakeNumber', 'Utility');

class FixedCakeNumber extends CakeNumber {
    
    public static function toReadableSize($size, $si = false) {
        $units = array(1 => 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y');
        
        // defaut values
        $divider = ($si) ? 1000: 1024;
        $binString = ($si) ? '' : 'i';
        
        // exception for byte(s)
        if ($size < pow($divider, $power)) {
            return __dn('cake', '%d Byte', '%d Bytes', $size, $size);
        }

        // caculate size
        $size = max($size, 0); 
        $power = floor(($size ? log($size) : 0) / log($divider)); 
        $power = min($power, count($units) - 1);
        $size = round($size / pow($divider, $power), 2);

        return __d('cake', '%s ' . $units[$power] . $binString . 'B', $size);
    }
}

Nu moeten we een nieuwe Helper aanmaken die gebruikt maakt van de bovenstaande class. Maak een nieuw bestand aan in app/View/Helper/ genaamt FixedNumberHelper.php. Plaats daar de volgende code in:

<?php
App::uses('FixedCakeNumber', 'Lib');
App::uses('NumberHelper', 'View/Helper');

class FixedNumberHelper extends NumberHelper {

    public function __construct(View $View, $settings = array()) {
        parent::__construct($View, $settings);
        $this->_engine = new FixedCakeNumber($settings);
    }
    
    public function toReadableSize($size, $si = false) {
        return $this->_engine->toReadableSize($size, $si);
    }
}

Vervolgens kun je in je controller de helper aanroepen met de volgende regel:

<?php
public $helpers = array('FixedNumber', 'Html', 'Etc');

In je view blijft niets veranderd en kun je de (Fixed)NumberHelper op de normale manier blijven gebruiken. Eventueel kun je, wanneer je dat zou willen. Gebruik maken van de SI eenheid door als tweede parameter true mee te geven.

<?php 
$size = 1000 * 1000 * 1000 * 1000; // 1 TB
echo $this->Number->toReadableSize($size); // output: 931.32 GiB
echo $this->Number->toReadableSize($size, true); // output: 1.00 TB

Automatisch SASS compilen

SASS heeft veel weg van LESS wat vooral door Twitter gebruikt wordt maar het schijnt iets beter te zijn.  Het is een manier van CSS code schrijven waarbij de CSS syntax gevolgd wordt maar waarmee je ineens toegang krijgt tot variabelen, functies en meer. Het enige nadeel is dat je SASS (.scss) bestanden wel nog moet omzetten naar CSS.  Daar is een handig programmaatje voor maar die moet je dan nog steeds elke keer dat je een aanpassing doet handmatig uitvoeren. Om dat op te lossen heb ik een klein Bash script gemaakt.

Dit script maakt gebruik van inotify en sassc en is getest onder Ubuntu 14.04. Om inotify te installeren voer je het volgende uit:

sudo apt-get install inotify-tools

sassc installeren is iets moeilijker want die moet je zelf compilen. Voor zover ik me herinner heb ik daar deze tutorial voor gevolgd.

Dit is het script wat ik gemaakt hebt. Deze kun je in principe overal neerzetten. Sla dit script op als scss2css.sh en voer een "chmod +x scss2css.sh" uit. Pas de dir= regel aan naar de map waar je sass/css code in staat.

#!/bin/bash
dir='/var/www/http_docs/'
sassc='/usr/local/bin/sassc'

inotifywait -m -r -e modify,close_write,create,moved_to,move --format %w%f $dir | while read scss_filepath; do 
    filename=$(basename "$scss_filepath")
    extension="${filename##*.}"

    if [[ "$extension" == "scss" ]]; then
        if  [[ ! $filename =~ ^_ ]]; then
            css_filepath=${scss_filepath/.scss/.css}
            $("$sassc" "$scss_filepath" "$css_filepath")
        else
            filename=${filename:1}
            filename=${filename/.scss/}
            files=$(grep -clRE --include=*.scss "import.*$filename" "$dir")

            for scss_filepath in $files; do
                css_filepath=${scss_filepath/.scss/.css}
                $("$sassc" "$scss_filepath" "$css_filepath")
            done

        fi
    fi
done

exit 0

Als laatste is het natuurlijk handig als het script tijdens het booten gestart word. Dit kan door een aanpassing in /etc/rc.local. Voeg daar deze regel aan toe:

su www-data --shell=/bin/bash -c '/var/www/scss2css.sh  > /dev/null 2>&1 &'

Backup m.b.v. rsync

Ik wilde al langer een offsite backup oplossing waarvan ik zeker kon zijn dat deze altijd zijn werk deed. Zelfs al zou er een ip adres wijzigen of de verbinding wegvallen tijdens het maken van de backup.

Op een gegeven moment vond ik BitTorrent Sync wat bijna precies deed wat ik wilde. BTSync is een volledig decentrale synchronisatie dienst. Je kan data dus zonder problemen naar verschillende devices toe synchroniseren. Het is alleen nog steeds geen echte backup oplossing omdat bestanden gewoon overschreven kunnen worden door een nieuwe versie.

Om dit toch voor elkaar te krijgen heb ik een simpel bash script gemaakt. Dit script moet twee argumenten meekrijgen. De eerste is de naam van het interval (hour, day, week, month, …) en de ander het maximum aantal kopieën die bewaard moeten blijven van dat interval. Het script word uitgevoerd via crontab en stuurt je een e-mail met de resultaten.

#!/bin/sh

# stuff to add to crontab:
# 1 1     * * 1   root    /etc/rsyncbak/rsyncbak.sh weekly 15
# 1 8     1 * *   root    /etc/rsyncbak/rsyncbak.sh monthly 24
# 1 16    2 1 *   root    /etc/rsyncbak/rsyncbak.sh yearly 100

# directory settings
BTSYNC_DIR='/mnt/backup/btsync/'
BACKUP_DIR='/mnt/backup/backups/'
PREV_LINK='/mnt/backup/backups/previous'
EXCLUDE_FILE='/etc/rsyncbak/exclude.txt'
EMAIL='youremail@domain.com'

# create vars for backup
NOW=$(date +'%Y-%m-%d_%H-%M-%S')
INTERVAL=$1
KEEP_X_COPIES=$(($2+1))
FOLDER="${BACKUP_DIR}${INTERVAL}_${NOW}"

# create backup using rsync
RSYNC_OUT=$(rsync -av --delete --link-dest="$PREV_LINK" "$BTSYNC_DIR" "$FOLDER/" --exclude-from="$EXCLUDE_FILE")
RSYNC_EC=$?

# create a new symlink
if [ -L "$PREV_LINK" ]; then
    rm "$PREV_LINK"
fi
ln -s "$FOLDER" "$PREV_LINK"

# remove obsolete backups
TO_REMOVE=$(ls -rd "${BACKUP_DIR}${INTERVAL}"_* | tail -n +"${KEEP_X_COPIES}")
for dir in $TO_REMOVE; do
    rm -rf "$dir"
done

printf "rsyncbak completed, exit code: %s\n\n%s" "$RSYNC_EC" "$RSYNC_OUT" | mail -s "rsyncbak completed" "$EMAIL"