#shell


Let's Encrypt - Comment se faciliter la vie ?

Mon serveur web est composé d'un frontend nginx et d'un backend apache. L'ensemble de mes certificats (à l'exception du wildcard deblan.org) est géré par Let's Encrypt. Mon problème jusqu'à aujourd'hui était que lors de la création ou le renouvellement d'un certificat, mon service nginx devait être coupé pour réaliser l'authentification nécessaire à la validation faite par Let's Encrypt.

Le service nginx, tel que je l'ai configuré, possède un fichier de configuration unique qui écoute sur le port 80. Ce fichier permet :

  • d'indiquer mon backend apache
  • de gérer les problématiques de cache des assets (images, css, javascripts, etc.)

Vous pouvez remarquer l'include à la ligne 20. Voici le contenu du snippet :

Il identifie un répertoire unique où seront générés les fichiers d'authentification de Let's Encrypt. Il aura fallu créer ce répertoire au préalable (sudo mkdir -p /var/www/letsencrypt/).

Reste à présent 2 scripts :

  • celui qui permet de générer un certificat
  • celui qui permet de renouveler les certificats qui vont expirer

Pour la génération d'un certificat, j'ai souhaité une ligne de commande simple : le-get-certificate monsite.com www.monsite.com foo.monsite.com. Voici son contenu :

Edit : la commande cerbot renew fait le travail tout seul. L'intérêt de mon script pourrait d'ajouter rapidement des domaines à certifier en augmentant le CSR automatiquement.

Concernant le renouvellement, le script suivant s'appuie sur un fichier de configuration que vous devrez alimenter à chaque création de certificat. Il doit être créé à cet emplacement : /etc/letsencrypt/domains.conf. Voici à quoi il ressemble chez moi et j'ai ajouté la ligne nécessaire pour l'exemple de la commande de création :

Voici à présent le script que devra être exécuté périodiquement pour le renouvellement :

J'espère que cela pourra vous être utile et si vous avez des remarques, n'hésitez pas à m'en faire part :)


Afficher une webcam sur son site (version Linux)

Il y a déjà un article pour afficher sa webcam sur une page web mais en plus d'être un peu à la rue, il ne fonctionne pas sur Linux.

Nous allons voir comment intégrer une webcam sur son site web sous Linux.

Il nous faut :

  • Un serveur web
  • Un accès SSH
  • Une webcam
  • Un ou deux logiciels en local

Note : je travail sur Debian, il faut donc transposer mes commandes pour votre distribution.

Étape 1 : les logiciels en local

Afficher/masquer le code
# aptitude update
# aptitude install openssh-client vgrabbj rsync imagemagick screen
  • openssh-client : notre client SSH
  • vgrabbj : il permettra de capturer les images de la webcam
  • rsync : il sera notre outil d'upload d'image et va s'appuyer sur SSH
  • imagemagick : pour faire un traitement sur l'image (ajouter du texte)
  • screen : pour lancer le script sans monopoliser un terminal

Étape 2 : préparation des répertoires de travail

On va créer un répertoire qui accueillera le script et la capture :

Afficher/masquer le code
# le répertoire du script
$ if [ -d "$HOME/bin" ] || mkdir "$HOME/bin"
# le répertoire de la capture
$ if [ -d "$HOME/.webcam" ] || mkdir "$HOME/.webcam"

Création du fichier :

Afficher/masquer le code
$ cd "$HOME/bin"
$ touch webcam
$ chmod +x webcam

Étape 3 : Et on édite le script

Je propose de faire ça en simple shell, donc pas de bash mais un bon vieux sh (ou dash sur Debian).

Afficher/masquer le code
#!/bin/sh

On prépare des variables de configuration :

Afficher/masquer le code
# Le login et le serveur
SSH_SERVER="simon@exemple.com"
# Des options à passer au client SSH
# -p indique le port de connexion
# -i permet de paramétrer une clé SSH
SSH_OPTIONS=" -p 22 -i $HOME/.ssh/id_dsa" 

# Chemin vers l'image que va générer la webcam
IMG_LOCAL="$HOME/.webcam/webcam.jpg"

# Le chemin de l'image sur le serveur distant
IMG_REMOTE="/services/web/www/exemple.com/public_html/ressources/webcam.jpg"

# Qualité de l'image générée (de 1 à 100 et plus c'est grand, plus c'est zoli)
IMG_QUALITY=75

# Les dimensions de l'image
# sqcif= 128x96,     qsif = 160x120,
# qcif = 176x144,    sif  = 320x240,
# cif  = 352x288,    vga  = 640x480,
# svga = 800x600,    xga  = 1024x768,
# sxga = 1280x1024,  uxga = 1600x1200
IMG_SIZE=sif

# Je vais afficher du texte sur l'image donc je paramètre sa couleur et sa position
IMG_TEXT_COLOR=black
IMG_TEXT_X=8
IMG_TEXT_Y=16

# Le périphérique webcam à utiliser
VIDEO_INPUT=/dev/video0

# Le temps entre deux captures (en secondes)
WAIT=5

# la fonction text va retourner le texte à afficher sur la webcam
text() {
	# ça donnera : login @ mm/jj/aa hh:mm:ss
	echo "$USER @ $(date +'%D %r')"
}

On ajoute une sécurité : ne pas avoir deux scripts qui tente un accès à la webcam en même temps :

Afficher/masquer le code
LOCK="$HOME/.webcam/.lock"

while [ -f "$LOCK" ]; do
	sleep 1
done

touch "$LOCK"

On termine par les commandes de capture, d'écriture du texte et d'upload :

Afficher/masquer le code
# On capture l'image
vgrabbj -i "$IMG_SIZE" -f "$IMG_LOCAL" -d "$VIDEO_INPUT" -q "$IMG_QUALITY" -a 3 -n

# On ajoute le texte
mogrify -fill "$IMG_TEXT_COLOR" -pointsize 11 -annotate +"$IMG_TEXT_X"+"$IMG_TEXT_Y" "$(text)" "$IMG_LOCAL"

# On upload 
rsync -avz -e "ssh $SSH_OPTIONS" "$IMG_LOCAL" "$SSH_SERVER":"$IMG_REMOTE"
# Note : certains seront peut-être plus à l'aise avec scp, c'est comme vous voulez

On termine par boucler tout ça :

Afficher/masquer le code
# on délock l'accès à la webcam
rm -f "$LOCK"

# On fait attendre un peu le script
sleep $WAIT

# On l'exécute lui-même 
"$0"&

# Et on arrête l'exécution courante
exit 0

Le script complet (sans commentaire) :

Afficher/masquer le code
#!/bin/sh

SSH_SERVER="simon@exemple.com"
SSH_OPTIONS=" -p 22 -i $HOME/.ssh/id_dsa" 

IMG_LOCAL="$HOME/.webcam/webcam.jpg"

IMG_REMOTE="/services/web/www/exemple.com/public_html/ressources/webcam.jpg"

IMG_QUALITY=75
IMG_SIZE=sif
IMG_TEXT_COLOR=black
IMG_TEXT_X=8
IMG_TEXT_Y=16

VIDEO_INPUT=/dev/video0

WAIT=5

text() {
	echo "$USER @ $(date +'%D %r')"
}

LOCK="$HOME/.webcam/.lock"
 
while [ -f "$LOCK" ]; do
	sleep 1
done

touch "$LOCK"

vgrabbj -i "$IMG_SIZE" -f "$IMG_LOCAL" -d "$VIDEO_INPUT" -q "$IMG_QUALITY" -a 3 -n
mogrify -fill "$IMG_TEXT_COLOR" -pointsize 11 -annotate +"$IMG_TEXT_X"+"$IMG_TEXT_Y" "$(text)" "$IMG_LOCAL"
rsync -avz -e "ssh $SSH_OPTIONS" "$IMG_LOCAL" "$SSH_SERVER":"$IMG_REMOTE"

rm -f "$LOCK"

sleep $WAIT
"$0"&
exit 0

Étape 4 : la page html

Afficher/masquer le code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ma webcam</title>
<script>
// Deux helpers pour attacher un évenement à un object et un selecteur rapide d'élement par id
var addEvent = function(object, eventName, myFunction) {
	if(object.addEventListener) {
		object.addEventListener(eventName, myFunction, false);
	} else if(object.attachEvent) {
		object.attachEvent('on'+eventName, myFunction);
	}
}
var $ = function(id) {
	return document.getElementById(id);
}

// On ne veut pas de clignottement donc entre chaque
// chargement d'image, on attend que celui-ci soit 
// terminé pour mettre à jour l'image dans la page
var image_reload = function(id, time) {
	var img = $(id);
	if(img) {
		var _img = new Image();
		var src = (img.getAttribute('src')).split('?')[0]+'?'+Math.random();
		_img.src = src;
		addEvent(_img, 'load', function() {
			img.setAttribute('src', src);
		});
		window.setTimeout(function() {
			image_reload(id, time);
		}, time);
	}
}

addEvent(window, 'load', function() {
	// id de l'image de la webcam et temps de rafraissement
	image_reload('webcam', 2000); 
});
</script>
<body>

<p><img data-dimension="destroy" id="webcam" src="/ressources/webcam.jpg" alt="" title=""/></p>

</body>

Étape 5 : lancer le script

Afficher/masquer le code
$ screen
$ ./bin/webcam

C'est terminé :)


Twidge, inverser l'odre d'affichage

Quand on passe une partie de sa journée devant un shell, on aime bien avoir accès à certaines choses sans booter un navigateurs graphique. Du coup, si on est un "twittos", on pourra installer Twidge, un client CLI pour Twitter.

Seulement, on notera deux "problèmes" : des commandes relativement longues et un ordre d'affiche non ergonomique à mon goût. En effet, il affiche les twitts du plus récent au plus ancien, mais quand on est dans un shell, ça oblige à scroller pour visualiser les nouveautés. Pour résoudre un des deux problèmes, il suffit de faire des alias. Pour l'autre, j'ai fais un script assez simple mais efficace.

Afficher/masquer le code
#!/bin/sh
TMP=/tmp/twitter


if [ -f "$TMP" ]; then
	rm "$TMP"
fi

getRecent() {
	tweets=$(twidge lsrecent | sed 's/\s\s*/ /g;s/^\s\s*//')
	echo "$tweets" | while read line; do
		if [ $(echo "$line" | cut -c 1) = "<" ]; then
			echo -n "\n$line" >> "$TMP"
		else
			echo -n " $line\`" >> "$TMP"
		fi
	done

	F=
	IFS="\`"
	for i in `cat "$TMP"`; do
		if [ ! -z $i ]; then
			F="$i$F"
		fi
	done

	echo "$F" | awk '$O!=""{ print $O"\n"; }'
}

case "$1" in
	ls|lsrecent) getRecent;;
	up|update) twidge update "$2";;
	*) twidge "$1" "$2";;
esac

Pour l'utiliser :

Afficher/masquer le code
# ici, le script s'exécute via "tw"
prompt> tw ls # affiche les derniers twitts
prompt> tw up <message> # ajoute un twitt
prompt> tw <une commande twidge>