27 Oct 2014, 00:00

Cartes son multiples et ordre sous ALSA

Sur mon ordinateur portable, j’ai 2 cartes sons qui sont reconnues : le chipset de la CM, et la carte son intégrée à la carte graphique. Le système s’obstine à prendre par défaut la sortie HDMI, ce qui ne m’intéresse pas du tout. Voici ce que j’obtenais avec la commande cat /proc/asound/cards (qui liste les cartes détectées par ALSA) :

0 [Generic        ]: HDA-Intel - HD-Audio Generic
                     HD-Audio Generic at 0xf0344000 irq 45
1 [Generic_1      ]: HDA-Intel - HD-Audio Generic
                     HD-Audio Generic at 0xf0340000 irq 46

(les valeurs entre crochets sont les id des cartes).

Puis avec la commande cat /proc/asound/modules :

0 snd_hda_intel
1 snd_hda_intel

Le même pilote est donc utilisé pour les 2 cartes.

Le premier workaround que j’ai trouvé a été de demander à ALSA d’utiliser la carte avec l’inex n°1. Pour ce faire, j’ai mis dnas le fichier /etc/asound.conf :

defaults.ctl.card 1
defaults.pcm.card 1
defaults.timer.card 1

Ceci fonctionnait bien pour la lecture. Par contre, les touches de mon clavier controlant le son controllaient toujours la carte d’index 0.

J’ai donc voulu passer la carte intégrée en index 0. Il faut pour ceci éditer le fichier /etc/modprobe.d/alsa-base.conf : Echanger les numéros de slot sur les 2 première lignes :

install sound-slot-0 modprobe snd-card-0
install sound-slot-1 modprobe snd-card-1

deviennent donc

install sound-slot-1 modprobe snd-card-0
install sound-slot-0 modprobe snd-card-1

Puis ajouter à la fin :

## Carte interne avant HDMI
options snd-hda-intel id=Generic_1 index=0
options snd-hda-intel id=Generic index=1

en adaptant le nom des pilotes et les id des cartes.

Source

26 Oct 2014, 00:00

APT, Pinning et fichier preferences

RAPPEL : La gestion des priorités est à considérer comme une fonction avancée, ne remettant pas en cause les choix indiqués par le sysadmin de la machine, et pouvant facilement mener à une corruption totale du système. Il faut l’utiliser avec parcimonie, et en connaissance de cause. Ou sur une machine que l’on compte réinstaller dans la demi-heure suivante :-)

Généralités

Le système APT, via apt-get ou aptitude fait appel à un niveau de priorité, appelé Pinning, affecté à chaque paquet disponible. Lors de l’installation d’un paquet, celui installé est le paquet ayant la plus haute version parmi les paquets ayant la plus haute priorité.
Si aucune version par défaut n’est spécifiée, via la directive APT::Default-Release dans le fichier /etc/apt/apt.conf[.d/XXX] (cas par défaut sous Debian), elle affecte :

  • une prorité de 100 à tout paquet actuellement installé
  • une priorité de 500 à tout paquet disponible dans un dépôt
  • une priorité de 1 à tout paquet disponible dans un dépôt qui a la directive NotAutomatic
  • une priorité de 100 à tout paquet disponible dans un dépôt qui a la directive NotAutomatic ET la directive ButAutomaticUpdates

(Ces directives sont mentionnés dans le fichier Release que nous verrons plus loin.)

Il est possible de voir toutes les versions et priorités d’un paquet, avec la commande apt-cache policy nomdepaquet, sachant que la ligne /var/lib/dpkg/status correspond à la version actuellement installée, et donc référencée par DPKG/APT.

Le but du pinning est de modifier ces priorités par défaut, afin d’avoir, typiquement, un système complètement stable avec quelques bouts de backports, testing ou encore unstable dedans, pour les composants utiles à mettre à jour régulièrement (navigateur web, par exemple).

Affectation des priorités

Chaque entrée du fichier sources.list ramène à une URL. Lorsqu’on a une entrée du type deb http://depot.monsite.org/path/ version archive1 archive2 aptitude va chercher les infos du dépôt à l’empacement http://depot.monsite.org/path/dists/version/Release

Ce fichier Release contient plusieurs lignes, définissant le dépôt, qui aident à configurer correctement un éventuel fichier /etc/apt/preferences , ou plus proprement des fichiers /etc/apt/preferences.d/XXX.pref . Le nom de ces fichiers n’accepte que les les caractères alphanumériques, les points, les traits d’union - et les underscore _. Ils doivent avoir une extension en .pref ou pas d’extension du tout. Ces fichiers servent au pinning, c’est-à-dire la gestion avancée des versions de logiciels.

La syntaxe générale d’une entrée d’un fichier de préference est la suivante :

Package: *
Pin: keyword x=definition
Pin-Priority: integer

La ligne Package définit le ou les paquets auxquels s’applique cette entrée de pinning. Ce peut être un nom précis de paquet (iceweasel), un ensemble de paquets commençant par le même motif (iceweasel*), un ensemble de paquet contenant le même motif (/weasel/) ou tous les paquets (*).

La ligne Pin définit les sources dont les paquets seront sujets à cette entrée. Il contient un mot-clé (keyword) qui définit le mode de sélection de ces sources. Il y a 2 modes de sélection de ces sources : origin, release et version. Origin est le plus simple, il selectionne toutes les entrées sorrespondant à une url de dépot. Par exemple :

Package: *
Pin: origin "ftp.debian.org"
Pin-Priority: 990

affectera une priorité de 990 à tous les paquets de l’archive principale de Debian, quelle que soit l’archive. On ne peut pas faire plus précis avec le mot-clé origin.

Pour le mot clé release, nous pouvons spécifier plusieurs paramètres, séparés par des virgules, qui cadreront très précisément les groupe de paquets auquel s’applique le ping. Ces paramètres sont comparés avec les valeurs du fichier Release de chaque dépôt, vu plus haut. Les paramètres sont : o pour l’origine (la valeur Origin du fichier Release, à ne pas confondre avec le mot clé Origin désignant l’URL), a pour l’archive (testing, stable etc), n pour le codename (squeeze, wheezy etc), v pour la version de paquet, l pour le Label (trouvé dans le fichier Release, toujours), et c pour le composant (main, contrib, non-free etc) Par exemple :

Package: *
Pin: release o=Debian Backports,n=wheezy-backports,l=Debian Backports
Pin-Priority: 50

affectera une priorité de 50 à tous les paquets venant de l’archive wheezy-backports, on voit que les valeurs correspondent avec le fichier Release.

Le mot clé version est assez explicite. Par exemple :

Package: perl
Pin: version 5.10*
Pin-Priority: 1001

Installation de packages non-prioritaires

Le plus souvent, il suffira de fournir l’option -t à aptitude, pour lui indiquer l’archive à partir de laquelle nous souhaitons installer le paquet. Il est également possible, dans le cas de paquets de versions différentes sur le même nom d’archive (par exemple l’archive wheezy de Debian, et l’archive wheezy de deb-multimedia.org), de spécifier la version précise que nous souhaitons installer, grâce à la syntaxe paquet=version. Le numéro de version précis à entrer est celui renvoyé par apt-cache policy paquet Par exemple :

aptitude install build-essential=11.7

tentera d’installer la version 11.7 de build-essential, c’est à dire celle de Jessie. Ce paquet faisant appel à plein de paquets de jessie, qu’aptitude ne priorise pas, il ne proposera d’installer ces paquets qu’après plusieurs solutions refusées. On peut taper à la place :

aptitude install build-essential=11.7 -t jessie

ainsi nous précisons la version exacte à utiliser, tout en donnant à aptitude l’ordre d’installer à partir de jessie tout ce quie est nécessaire.

Pour plus d’informations, consultez man apt_preferences.

07 Oct 2014, 00:00

Sauvegarder via Rsync un backup Time Machine

Lorsqu’on sauvegarde avec Time Machine sur un disque réseau (fonctionnement différent du disque local), les données sont stockées au format .sparsebundle, une image disque qui s’étend à volonté, et qui contient un plusieurs anciennes versions des fichiers. Bien qu’elle apparaisse en tant que fichier sous OSX, une image qu’on peut monter dans le Finder pour en lire/écrire le contenu, c’est en réalité un dossier, qui contient quelques petits fichiers descriptifs, et surtout un gros dossiers, bands, qui contient lui-même toutes les données de l’image, découpé en fichiers de 8,4 Mo. Seule une petite partie de ces fichiers est mise à jour lors d’une sauvegarde Time Machine, et seule cette petite partie sera synchronisée via Rsync (environ 300 Mo. Il va de soi qu’avoir une connexion avec un bon upload, dans le cas d’une sauvegarde réellement distante, est un gros plus.

L’idée du script qui va suivre est de, régulièrement :

  • déclencher une sauvegarde Time Machine
  • monter le volume de sauvegarde (volume réseau, appelé “Time Capsule” ici, bien que ce puisse être n’importe quel volume proprement configuré) sur un point de montage précis
  • synchroniser le point de montage via rsync, avec un serveur ssh (par définition n’importe où dans le monde)

Les prérequis sont :

  • avoir configuré, via GUI ou autre, Time Machine, et être sûr que le setup fonctionne correctement
  • avoir configuré la redirection de ports sur le routeur devant le serveur ssh
  • avoir une configuré une authentification ssh sur le serveur via clé, sans demande de mot de passe, pour pouvoir l’automatiser
  • savoir identifier la time capsule sur le réseau, y accéder via hostname et connaître un couple user/password valide pour la lecture des données
  • avoir désactivé la planification de Time Machine. Le script s’occupe de lancer la sauvegarde, et une MAJ du contenu du sparsebundle pendant la synchronisation distante via rsync pourrait créer une incohérence dans les données.
  • avoir une système de fichiers de destination (sur le serveur ssh) qui supporte les liens durs (hard-link). Typiquement ext4. Bien qu’on stocke du HFS+, il n’est pas nécessaire que cette destination sot en HFS+, car le .sparsebundle contient un système de fichier virtuel, qui s’occupe de conserver toutes les permissions/ACL/attributs étendus nécessaires.

Voici le script proprement dit, très inspiré de cet article, avec un bon paquet de code copié/collé. Cependant, je choisis de simplement conserver les x dernières versions de la sauvegarde. En effet, Time Machine s’occupe déjà de faire un historique régulier (journalier, mensuel, annuel etc), le but de cette sauvegarde est simplement de la déporter sur un site externe, tout en pouvant retrouver une ancienne version en cas de corruption des données Time Machine, et en conservant la facilté de restauration. Ainsi, avec le paramètre daystokeep=90, nous disposons de 3 mois d’historique du contenu de la Time Capsule.

#!/bin/sh

### VARS
  # local
identifier=`hostname`
# the following folder will store lock and log files
filesPath="/path/to/folder with spaces/"  # must contain the trailing /
logfile="${filesPath}${identifier}.log"
lockfile="${filesPath}${identifier}.lck"


  # TimeCapsule (source)
  # should match the Time Machine settings (via TM GUI)
  # name is the Zeroconf name provided in the "Time Capsule" tab within the Airport Utility, finishing by .local
  # for the actual Time Capsule, username seems to be indifferent, but you need the correct password
  # for any AFP share server, username have to be correct
tc_name="Time-Capsule.local"  # it never contains spaces
tc_share="Server Backups"
tc_user="timemachine"
  # if password contains a @ sign, replace it with %40. Spaces are OK.
tc_pw="password %40 TimeCapsule"
tc_mount_point="/Volumes/TC/"  # must contain the trailing /
  # this var could be retrieved from the hostname, but is not for the moment
tc_file_name="iMac de User.sparsebundle"


  # Remote disk (destination)
ssh_user='backupuser'
ssh_server='storage.mydomain.com'
ssh_port=1111
ssh_connect="${ssh_user}@${ssh_server} -p $ssh_port "
target="/path/to/folder/" # must contain the trailing /

###  END OF VARS



# Date for this backup.
date=`date '+%Y-%m-%d_%Hh%Mm'`
# Process ID for this backup
mypid=${$}

### Log beginning of the backup
echo "\n" >> "${logfile}"
if [ ! -d "$filesPath" ]
  then mkdir "$filesPath"
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- $filesPath was just created" >> "${logfile}"
fi

echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- backup started" >> "${logfile}"




###  Check if process is already running to avoid multiples backups at the same time
###  which could corrupt data
if [ -f "${lockfile}" ]
then
  # Lockfile already exists, check if it belongs to a running process
  read -r lockpid < "${lockfile}" #Read the first line which contains a PID
  if [ -z "`ps -p ${lockpid} | grep ${lockpid}`" ]
  then
	# The process doesn't exist anymore. Should there be an incomple folder, it will be removed at the end of the script.
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Lockfile for ghost process (PID: ${lockpid}) found, continuing backup." >> "${logfile}"
  else
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Lockfile '${lockfile}' for running process (PID: ${lockpid}) found, backup stopped." >> "${logfile}"
	exit 73 # can't create (user) output file
  fi
fi
# The lockfile doesn't exist or belongs to a ghost process, make or update it containing the current PID.
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- Création du fichier lock" >> "${logfile}"
echo ${mypid} > "${lockfile}"


### Launch the Time Machine Backup
# On OSX 10.6, the command `/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper` is a "BACKUP NOW" command
#On 10.7 and later, Apple introduced the `tmutil` command which would allow to do the same
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup launched" >> "${logfile}"
/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper

## The backupd-helper command quits before the save is really finished
## so we check the existence of the process 'backupd'
while [ `/bin/ps -arxo state,comm | /usr/bin/grep backupd | wc -l` -ne 0 ];
do
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup still working. Waiting 180 seconds" >> "${logfile}"
	sleep 180
done
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup succeed !" >> "${logfile}"



### Check if the ssh connection can be made, a ssh keypair without keyphrase must exist.
ssh -q -q -o 'BatchMode=yes' -o 'ConnectTimeout 10' ${ssh_connect} exit &> /dev/null

if [ $? != 0 ]
then
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] SSH connection ${ssh_connect} failed." >> "${logfile}"

  # Remove lockfile
  rm -f "${lockfile}"

  exit 69 # service unavailable
fi
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] SSH connection ${ssh_connect} succeed." >> "${logfile}"


### check if target exists
if ssh ${ssh_connect} "[ ! -d '${target}' ]"
then
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Target '${target}' does not exist, backup stopped." >> "${logfile}"

  # Remove lockfile
  rm -f "${lockfile}"

  exit 66 # cannot open input
fi



### Mount the TC volume on the Filesystem
# if mountpoint doesn't exists, we create it
[ -d "$tc_mount_point" ] || mkdir "$tc_mount_point"

# mount the network disc
/sbin/mount_afp "afp://${tc_user}:${tc_pw}@${tc_name}/${tc_share}" "${tc_mount_point}"

# wait for the network disk to be actually mounted
sleep 30

### Make the actual backup of the backup

# check folder for rsync logs
if [ ! -d "${filesPath}"rsync_logs ]
then
    mkdir "${filesPath}"rsync_logs
fi

  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Rsync started." >> "${logfile}"

/usr/local/bin/rsync3 \
	-e "ssh -p $ssh_port" \
	--bwlimit=75 \
	--archive \
	--compress \
	--human-readable \
	--delete \
	"${tc_mount_point}${tc_file_name}" \
	"${ssh_user}@${ssh_server}:'${target}latest'" | tee -a "${filesPath}"rsync_logs/`date '+%Y-%m-%d_%Hh%Mm%S '

  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Rsync finished." >> "${logfile}"



### Create "history" folder if it doesn't exists
if ssh ${ssh_connect} "[ ! -d '${target}history/' ]"
then
  ssh ${ssh_connect} "mkdir '${target}history'"
fi


### archive current backup
ssh ${ssh_connect} "cp -al '${target}latest' '${target}history/${date}'"

### Remove backups older than specified days
ssh ${ssh_connect} "$target/historyClean.sh"  # this file have to be created on the backup's destination. It is detailed at the end.

### Unmount the TC Volume
/sbin/umount "${tc_mount_point}"

echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Remote backup successfully finished ! " >> "${logfile}"
# Remove lockfile, this must always be done at the latest moment possible to avoid conflicting processes.
rm -f "${lockfile}"

Et voilà le script historyCleaning, qui doit être mis directement sur la machine (Unix-like) qui contient les sauvegardes du backup Time Machine (par exemple un NAS Synology).

## VARS
target="/path/to/folder/"  # path to the backup's backup. Must match the one in the main script and contain the trailing slash
tc_file_name="iMac de User.sparsebundle"  # must match the one in the main script
daystokeep=200
## END OF VARS

## We search for backups older than daystokeep ; modification time is only on the hostname.sparsebundle folder, so we search it and then we truncate the path
find "$target"history/*/* -maxdepth 0 -type d -mtime +$daystokeep | sed "s#/$tc_file_name##" > $target/dirsToRemove.txt


## We delete each folder
for j in `cat "$target"dirsToRemove.txt`
do
	# it is advised to check if everything is ok
	echo $j
	# if ok, uncomment this line
	#rm -R $j
done

29 Sep 2014, 00:00

Créer un réseau en NAT sur une connection wifi ou 3g

L’idée : capter une connection wifi ou 3G, et la partager à travers le port Ethernet de l’ordinteur, en créant un sous-réseau, avec DHCP. Le paquet isc-dhcp-server est nécessaire.

Paramétrer le fichier /etc/dhcp/dhcpd.confafin qu’il soit ainsi, en adaptant les valeurs à vos préférences :

# option definitions common to all supported networks...
option domain-name "nomdureseau";
option domain-name-servers 8.8.8.8, 8.8.4.4;

default-lease-time 3600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;


subnet 10.88.1.0 netmask 255.255.255.0 {
  range 10.88.1.5 10.88.1.199;
  option routers 10.88.1.1;
  option domain-name-servers 8.8.8.8, 8.8.4.4;
  option broadcast-address 10.88.1.255;
}

Ce fichier sert à définir le réseau et la plage d’IP qui seront distribuées par le serveur DHCP.

Si on souhaite désactiver l’IPv6 afin de ne pas avoir de message d’erreur, on édite le fichier /etc/default/isc-dhcp-server et on ajoute le nom de l’interface filaire à la ligne “INTERFACESv4=”
Source

Créer ensuite le fichier /etc/network/interfaces.nat qui contiendra ceci :

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 10.88.1.1
netmask 255.255.255.0
network 10.88.1.0
broadcast 10.88.1.255

Ce fichier sert à définir manuellement les paramètres réseaux de la carte qui servira le DHCP. Il doit être en cohérence avec le dhcpd.conf ci-dessus.

On copie le fichier interfaces actuel pour pouvoir le restaurer lorsqu’on quittera ce mode de partage :

sudo cp /etc/network/interfaces /etc/network/interfaces.pasnat

Puis on crée les scripts. Créer quelque part le fichier nat.sh qui contiendra ceci :

#!/bin/sh

# on coupe les services réseau
service network-manager stop
service networking stop

# on configure les interfaces et le forward
echo 1 > /proc/sys/net/ipv4/ip_forward
cp /etc/network/interfaces.nat /etc/network/interfaces

# on réinitialise et remet en route le réseau
ip addr flush eth0
ifconfig eth0 up
service networking start
service isc-dhcp-server start
service network-manager start

# on masquerade les paquets qui vont vers toutes les interfaces actuellement actives sauf eth0 et loopback
iptables -t nat -F
for interface in $(ip link show | grep UP | grep -v DOWN | grep -v eth0 | grep -v LOOPBACK | sed s/^[0-9]*:\ // | sed s/:.*$//);
do
  iptables -t nat -A POSTROUTING -o ${interface} -j MASQUERADE;	## On crée dans iptables la règle de NAT à proprement parler
done

# On prépare pour le prochain reboot
cp /etc/network/interfaces.pasnat /etc/network/interfaces

Puis le fichier pour retourner en connection standard, pasnat.sh :

#!/bin/sh

# On coupe le réseau
service network-manager stop
service networking stop
service isc-dhcp-server stop

# On désactive le forward ipv4, et reconfigure les interfaces normalement
echo 0 > /proc/sys/net/ipv4/ip_forward
cp /etc/network/interfaces.pasnat /etc/network/interfaces

# on réinitialise et remet en route le réseau
ip addr flush eth0
service networking start
service network-manager start

# on purge les tables iptables
iptables -t nat -F
iptables -F

On rend ces 2 fichiers exécutables

chmod +x /path/to/nat.sh
chmod +x /path/to/pasnat.sh

On peut désormais les lancer avec sudo

sudo /path/to/nat.sh

et les connections (wifi, USB, ppp etc) sera partagée à tous les clients branchés sur la carte filaire du l’ordi !

15 Sep 2014, 00:00

Résolution de noms Netbios et Zeroconf

La résolution de noms Zeroconf en .local ou encore en .custom sous Linux se fait grâce au logiciel Avahi, sous la forme du paquet avahi-daemon. Sous windows, il est possible d’installer Bonjour (livré avec iTunes et extractible de l’installeur). Sous OSX, Bonjour est présent par défaut.

Pour résoudre les noms Netbios sous Debian, une méthode facile est d’installer le paquet libnss-winbind, puis de configurer le fichier /etc/nsswitch.conf de sorte à ce qu’il ressemble à ceci :

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat
group:          compat
shadow:         compat

## Ligne originelle
#hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4
hosts:		files dns wins mdns4_minimal
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

L’utilisation du protocle mdns4, qui correspond à Zeroconf, peut considérablement ralentir la recherche ping, notamment sur les recherches Netbios. On préférera utilser mdns4_minimal qui ne recherche que dans les adresses .local en ignorant n’importe quel .custom mais va beaucoup plus vite. L’ajout de la directive wins correspond à la recherche Netbios.

Normalement, ainsi le poste pourra pinger (donc niveau système, et accessible à toutes les applis) les hostname.local des ordis ayant une implémentation de Zeroconf en fonctionnement et les hostname de tous les postes Windows et les Linux ayant un samba en fonctionnement, et la navigation internet en général ne devrait pas du tout être ralentie.

10 Sep 2014, 00:00

Notes en vrac sur OpenSSH, les hôtes et l'authentification par clé

Côté client

Le fichier qui contient tous les hôtes qu’un client ssh connaît est /home/$USER/.ssh/known_hosts. Si il y a un conflit de clés (clé d’un serveur renouvelée par exemple), on peut supprimer uniquement la ligne concernant le serveur en question, dont il faut connaitre le hostname : ssh-keygen -R HOSTNAME

Si on souhaite créer une clé d’authentification RSA (ou DSA), on peut le faire via la commande ssh-keygen -t rsa -b 4096 -C "Commentaire pour ditinguer la clé" (ou ssh-keygen -t dsa pour l’algo DSA, bien que ce soit aujourd’hui moins conseillé). Il est possible de créer une passphrase pour ces clés. Les fichiers créés le seront par défaut à l’emplacement ~/.ssh/id_rsa pour la clé privée et ~/.ssh/id_rsa.pub pour la clé publique. Ces clés peuvent servir pour se connecter sans mot de passe à un serveur ssh. Le commentaire se retrouve à la fin de la clé publique.

Le programme utilisé pour gérer la liste des clés utilisables pour l’authentification par clé est ssh-agent. La clé à l’emplacement par défaut est toujours référencée par ssh-agent. On peut gérer ce programme via la commande ssh-add. Par exemple ssh-add -L liste les clés référencées, ssh-add -D supprime toutes les clés référencées, ssh-add /path/to/id_rsa référence la clé en question et ssh-add -d /path/to/id_rsa supprime uniquement cette clé.

Pour que tous les terminaux partagent le même agent, il faut placer ceci dans son .bashrc (et peut-être le .profile) (source) :

	export SSH_AUTH_SOCK=~/.ssh/ssh-agent.$HOSTNAME.sock
	ssh-add -l 2>/dev/null >/dev/null
	if [ $? -ge 2 ]; then
	  ssh-agent -a "$SSH_AUTH_SOCK" >/dev/null
	fi

Côté serveur

Les clés publiques/privées du serveur sont créées à l’installation du serveur SSH. Elles se trouvent par défaut à /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_dsa_key.pub, /etc/ssh/ssh_host_rsa_key et /etc/ssh/ssh_host_rsa_key.pub.

Pour accepter les connections par clé RSA, le serveur doit avoir les directives RSAAuthentication yes PubkeyAuthentication yes #AuthorizedKeysFile %h/.ssh/authorized_keys dans le fichier de configuration du serveur /etc/ssh/sshd_config.

Comme l’indique la 3ème directive ci-dessus, les clés (publiques) acceptées pour chaque user sur le serveur doivent se trouver dans le fichier /home/$USER/.ssh/authorized_keys. Ce paramètre peut-être modifié en décommentant cette ligne et en mettant un emplacement différent.
Une des manières de l’ajouter, depuis le poste client, est de rentrer la commande ssh-copy-id -i /path/to/id_rsa -p port user@serveur. La paramètre -i est facultatif, en son absence ce sera l’emplacement par défaut qui sera utilisé.
On peut également le copier à la main sur le serveur, en copiant la clé publique correspondante à l’emplacement indiqué dans le fichier de conf.

12 Aug 2014, 00:00

Booter un système Linux en mode UEFI ou en mode BIOS

Le but de la manipulation est de pouvoir, aisément, booter un système Linux Debian aussi bien en mode UEFI que MBR, sans avoir à faire de reconfiguration particulière en passant de l’un à l’autre, avec un disque dur partitionné en GPT. Ceci me permet de pouvoir, à la volée, grâce au menu de démarrage (sur un HP DM1-4332sf), booter mon OS linux en mode BIOS, permettant un meilleur support du matériel (la mise en veille ne fonctionnant actuellement pas en mode EFI), tout en conservant les systèmes Windows 7, Windows 8 et mon système Debian bootables en mode EFI.

N’ayant actuellement pas réussi à faire cohabiter grub-pc et grub-efi sur une même installation, le démarrage par efi se fera via GRUB et le démarrage par MBR se fera via EXTLINUX.

Cette démarche fonctionne aussi en cas de multiboot, mais ce multiboot ne sera possible qu’en mode EFI (via GRUB pour EFI). Le système Syslinux ne sera capable de démarrer que la Debian. Cet article ne parlera toutefois pas du tout de la configuration du dual-boot en EFI, celui-ci étant de toute façon totalement indépendant de la coexistence avec un Syslinux pour BIOS.

Le disque /dev/sda est supposé partitionné comme ceci :

/dev/sda1 : FAT32, EFI System Partition (label EFI)
/dev/sda2 : NTFS Partition (label WIN_7)
/dev/sda3 : Ext4 partition (label SLASH)
/dev/sda4 : Ext4 partition (label HOME)
/dev/sda5 : swap partiton
/dev/sda6 : NTFS partition (label DATA)

Il faut ensuite rajouter le flag legacy_boot à la partition SLASH (/dev/sda3 ici). Ceci peut se faire via GParted. Dans le cas d’une partiton /boot séparée, il faut probablement positionner ce flag sur la partition /boot .

Le système est présupposé fonctionnel en mode EFI, via GRUB (soit par une installation directement en mode EFI, soit en rendant le système bootable en EFI après une installation classique, comme détaillé ici). Comme les labels l’indiquent, /dev/sda3 est monté sur / , /dev/sda4 est monté sur /home/ . Le setup ne contient PAS de partiton /boot/ séparée. La partition EFI System Partition est montée sur /boot/efi/.

Il faut d’abord installer le paquet extlinux. sudo aptitude install extlinux syslinux-common Il crée automatiquement un répertoire /boot/extlinux/ avec la configuration nécessaire. Il install également extlinux sur le MBR du disque (commande extlinux-install), or celui-ci ne convient pas à l’installation actuelle, car il est conçu pour les partitons natives en MBR. On écrase donc ce mbr avec le extlinux prévu pour les partitions GPT :

dd if=/usr/lib/syslinux/gptmbr.bin of=/dev/sda

Et voilà ! Si on choisit de démarrer l’ordinateur en mode BIOS, sur le disque dur, on aura la liste de nos noyaux bootables via Extlinux. D’après mes tests, l’ajout et la suppression de noyaux peuvent être faits à partir du mode BIOS ou EFI, GRUB et Extlinux auront tous les 2 leur configuration mise à jour.

29 Jul 2014, 00:00

Installer freenet sous Wheezy

On va créer un utilisateur dedié, qui installera et lancera l’instance de freenet. Il n’est pas nécessaire et donc pas recommandé de lancer l’instance en root.

Installation :

    sudo adduser --system --group freenet
    cd ~freenet
    sudo su -s "$SHELL" freenet
    wget https://downloads.freenetproject.org/alpha/installer/new_installer_offline.jar
    java -jar new_installer_offline.jar -console

Selectionner un répertoire, par exemple /home/freenet/freenet_bin pour l’installation. Le client est lancé automatiquement suite à l’installation. Pour couper/lancer le serveur ou savoir s’il tourne, les commandes, en tant qu’utilisateur freenet, sont /home/freenet/freenet_bin/run.sh stop, /home/freenet/freenet_bin/run.sh start et /home/freenet/freenet_bin/run.sh status.

On peut ensuite accéder au panneau de contrôle via l’url, dans son navigateur favori : http://localhost:8888

02 Jul 2014, 00:00

L'UEFI et GPT en vrac

Généralités

Legacy Mode = Compatibility Support Module (CSM) = BIOS Mode . Utilisé pour qu’un système UEFI se comporte comme un BIOS traditionnel.

Pour savoir si l’on a bien booté en mode efi : Sous Linux : dmesg | grep -i EFI ne renverra presque rien si l’on est en mode BIOS, mais plein d’infos (gestion mémoire etc) si on est en mode efi.
Sous Windows, il suffit de se repérer à la table de partition du disque système : il ne peut booter en mode BIOS que sur disque MBR, et en mode EFI que sur disque GPT.

À une certaine époque, fdisk ne gèrait pas les disques GPT. Aujourd’hui oui. gdisk les gère aussi, et permet un certain nombre d’actions dessus.

Les tables de partition GPT sont dupliquées ; en début ET en fin de disque. Pour cette raison, dumper un disque vers un disque plus grand ne fonctionne plus, car la table de secours ne sera pas correctement placée. Il faut copier la table de partition (sudo sgdisk /dev/sdX -R /dev/sdY pour copier la table de sdX vers sdY), puis dumper chacune des partitions une à une.

Une table de partition GPT contient une zone réservée habituellement au MBR, avec plusieurs états possibles : cette zone MBR peut-être en protective (non utilisée, montre une seule grosse fausse partition de max 2To), en hybrid (une pseudo-table MBR devant concorder avec la table gpt sur 4 partitions) ou en MBR-only (c’est nativement un disque MBR). Le rôle de cette zone est d’éviter la modification/création d’une table MBR par des outils ne connaissant pas le GPT.
gdisk peut (ré)écrire une table hybrid-MBR pour qu’elle concorde avec l’état actuel de la table GPT. L’utilisation d’un hybrid-MBR est toutefois un hack étant aujourd’hui plutôt déconseillé.

On peut voir l’état de ce mbr avec l’outil gdisk :
sudo gdisk -l /dev/sdX

gparted gère sans problème les disques GPT, sauf dans le cas d’un disque en Hybrid-MBR. Les modifications seraient dans ce cas faites uniquement sur la pseudo-table mbr, sans tenir compte de la gpt, et donc de l’agencement réel des partitions, ce qui risque très probablement de casser toute la table. (edit : probablement plus vrai aujourd’hui)

Lors de la création d’une table de partition, va être créé un “Disk identifier” (sous forme d’UUID pour du GPT, et de 8 caractères hexadécimaux pour du MBR). Cet identifiant est purement logiciel.

Flags, types de partition

Une table de partition GPT associe à chaque partition un type, qui permet de donner une indication sur le rôle de la partition. Ce type est un UUID, qui se traduit en une appellation (qui peut être différente selon les programmes). Un fdisk -l affiche le type de chaque partition existante. On peut voir la liste complète des types de partition avec fdisk /dev/sdX puis l.

On peut également voir/modifier facilement les types de partition avec cfdisk .

La partition sera accessible, même si le type ne concorde pas avec le formatage. Toutefois, certains types peuvent ne pas apparaître dans l’explorateur, et nécessiter un montage à la main (par exemple esp).

Sous GParted, un certain nombre de ces types de partition sont représentés par des drapeaux (flags). Par exemple,

  • absence de drapeau = Linux Filesystem (ou Inconu sous diskpart) = UUID 0fc…de4
  • drapeau “esp” (également “boot”) = type EFI System Partition (ou Système sous diskpart) = c12…93b
  • swap = Linux Swap = 065…f4f
  • bios_grub = BIOS boot
  • diag = Windows recovery environment
  • msftdata = Microsoft Basic Data (ou Principale sous diskpart) = ebd…9c7
  • msftres = Microsoft reserved (ou Réservé sous diskpart) = e3c…5ae

Lors du formatage vers certains systèmes de fichiers (par exemple ext4 ou ntfs), GParted assigne automatiquement le type “évident” à la partition (par exemple “Linux filesystem” ou “Microsoft basic data”). Un formatage en FAT32 ne semble pas modifier le type déjà existant.

Certains drapeaux sont toutefois indépendants du type ; par exemple “hidden” et “legacy_boot”.
Il y’a une explication de nombreux drapeaux ici.

Types en table MRB

Les partitions ont également un type dans les partitions MBR. L’identifiant est sur 2 octets et Par exemple

Démarrage

L’UEFI ne peut démarrer un périphérique (disque dur, clé usb etc) qu’à partir d’une partition en fat32 (en réalité, certaines cartes-mères sont capables de lire le NTFS aussi). Généralement, elle est nommée “EFI System Partition” (ESP) et elle a le flag “boot” dans GParted (et le flag “esp” si la table de partition est GPT).

Le chemin par défaut où l’UEFI va chercher un bootloader (exécutable EFI) est ${ESP}/boot/BOOT${ARCH}.efi , typiquement /efi/boot/BOOTX64.efi. Si l’exécutable est ailleurs, on peut aller le chercher à la main lors du choix de boot (bien que ceci dépende de l’implémentation sur la carte-mère).

L’UEFI supporte aussi l’enregistrement d’entrées de démarrage au sein-même de l’UEFI. Ceci permet d’avoir plusieurs bootloaders en parallèle, avec un chemin et un nom associés. Par exemple ${ESP}/Microsoft\bootmgrfw.efi (Windows Boot Manager) et ${ESP}/debian/grubx64.efi (debian). Ces entrées peuvent se visualiser et se gérer sous Linux avec la commande efibootmgr. Si définies, elles sont prioritaires sur le chemin par défaut.
Ces entrées comportent le chemin absolu de l’exécutable, avec l’UUID de la partition (PARTUUID dans blkid) le contenant. Par conséquent, une fois enregistrée dans l’UEFI, il est possible de démarrer depuis une partition n’ayant PAS le flag boot/esp. Cette partition doit toutefois être en FAT32.

Les CD et DVD sont bootables en UEFI via le format ElTorito, comme les BIOS auparavant.

Les disques au format MBR sont bootables aussi sans problème par un système UEFI, tant que la partition à booter est en fat32. La limitation de Windows qui ne peut booter en UEFI que sur GPT vient de Windows et non de la norme UEFI.
(note : Windows n’accepte de s’installer que sur une table de partition correspondant à son type de démarrage, mais il est possible de le faire démarrer sur une table non-prévue en installant les fichiers à la main).

À l’inverse, les disques GPT peuvent être démarrés sur un système BIOS. Si GRUB est utilisé, il a besoin d’une partition dédiée (1Mo, non formatée) avec le flag “bios_grub”. Ceci lui permet de stocker les infos qui sont habituellement stockées dans un espace libre de la MBR (qui est ici utilisé par la table de partition GPT elle-même). Sans quoi la commande grub-install /dev/sdX renverra une erreur de “listes de blocs”. Une fois utilisée, cette partition apparaîtra avec le système de fichiers “grub2 core.img”.
Dans ce cas, la partition ESP ainsi que les flags “boot” et “esp” ne sont pas nécessaires. Ils peuvent toutefois être positionnés, pour faciliter une migration future vers un système EFI. Ceci nécessitera toutefois le remplacement du paquet grub-pc par le paquet grub-efi.

La plupart des UEFI sont de nature 64 bits, mais certains (souvent des PCs assez bas-de-gamme) ont un EFI uniquement en 32 bits. Ceci n’empêche pas le chargement d’un système en 64 bits, mais l’exécutable EFI (grub-efi, syslinux-efi etc) doit être en 32 bits.

Bien que déconseillé, il est possible d’avoir 2 (ou + ?) partitions ESP en même temps sur un disque interne. On peut aussi positionner/enlever les flags boot pour alterner entre 2 ESP.

efibootmgr

Pour lister les entrées, lancer simplement efibootmgr. On peut avoir plus de détails avec efibootmgr -v.

Pour supprimer l’entrée “BootABCD”, on entre
sudo efibootmgr -b ABCD -B

Utilitaires

Le comportement de certains programmes est le suivant :

grub-update : os-prober ne référencera que les exécutables UEFI situés sur la (les ?) partitions ESP (comportant le flag boot)

grub : peut booter sur une partition qui n’est PAS la partition ESP ; peut aussi lancer des OS/noyaux qui sont sur une partition non-ESP

Install Windows : si pas de partition flaggée ESP lors de l’install, il va en créer une dans le premier espace libre sur le disque ; si pas d’espace libre, message “Nous n’avons pas pu créer de partition…” et l’install ne pourra pas continuer.
Si la partition ESP est en NTFS, l’installation échouera en demandant de la formater en FAT32 (toutefois certaines cartes-mères sont capables de démarrer depuis une partition NTFS si on recrée les fichiers manuellement).

Windows : si absent de la liste de démarrage UEFI et que la partition contenant son bootloader est flaggée ESP, alors il s’enregistre dans l’UEFI lors du démarrage et se place en priorité

bcdboot : crée les fichiers de démarrage sur la partition ESP, sauf si le flag /s X: est spécifié, X: étant la lettre assignée à la partition où l’on souhaite créer ces fichiers

veracrypt : lors du chiffrement de la partition système (et du pre-test qui va avec), les fichiers EFI de veracrypt sont écrits sur la partition flaggée ESP
Lors du déchiffrement, les fichiers sont aussi écrits sur la partition flaggée ESP

Ordre des partitions

Si on aime avoir le numéro des partitions qui correspond à leur ordre sur le disque, on peut utiliser la commande
sudo sgdisk -s /dev/sdX

Ou aussi la commande gdisk :

sudo gdisk /dev/sdX
s
p
w
Y

02 Jun 2014, 00:00

Petit mémo rapide pour Samba

Lister les utilisateurs : Si les mots de passe sont stcokés de manière sécurisée (directive passdb backend = tdbsam dans le fichier /etc/samba/smb.conf) sudo pdbedit -L Sinon cat /etc/samba/smbusers

Tous les utilisateurs samba doivent correspondre à un utilisateur Unix sur le système. Pour créer un mot de passe à un utilisateur (ou le modifier), et qu’il puisse donc être utilisé comme identifiant pour une connexion via partage réseau : sudo smbpasswd -a username Pour le supprimer de la base d’utilisateurs samba : sudo smbpasswd -x username

Pour définir si un utilisateur a le droit d’accéder à un partage, il existe, dans les paramètres du partage, la directive valid user = username1 username2 @groupname1 Les droits des utilisateurs sont ensuite définis par 2 paramètres, read only = et write list = . Si on a read only = no alors tout le monde (parmi les valid users) aura accès en lecture/écriture. Si on a read only = yes write list = username1 @groupname1 alors seul l’utilisateur username1 et les utilisateurs du groupe groupname1 auront droit à l’écriture.

Cela peut donner, par exemple : [Reception] comment = reception browseable = yes path = /path/to/reception guest ok = yes read only = no

[private]
   comment = User private folder
   browseable = no # it only made it disappear from broadcasted shares, but doesn't affect the real browseability
   path = /home/user/
   guest ok = no
   valid users = gaetan
   read only = yes
   write list = gaetan

Ces règles ne sont pas valides pour le mode de sécurité security = share