code. grind. sleep.

mardi 5 juillet 2011

Configuration réseau pour virtualiser chez OVH

Sur mon serveur chez OVH, j'ai un ensemble de machines virtuelles KVM et (bientôt) de conteneurs LXC. Pour fournir du réseau à tout ce petit monde, j'utilise de l'IPv4 et de l'IPv6, voici comment c'est configuré.

Pour l'IPv4, on a un nombre limité d'IP publiques parce que ça vaut de la thune et que ça va être de plus en tendu de multiplier les adresses, il nous faut un réseau privé (beurk), du NAT (rebeurk) et des redirections à base d'iptables (re-rebeurk). Il nous faut surtout un bridge, c'est une Debian donc ça se passe dans /etc/network/interfaces :

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
	bridge_ports eth0
	bridge_fd 0
	bridge_maxwait 0
	address 188.165.205.xxx
	netmask 255.255.255.0
	network 188.165.205.0
	broadcast 188.165.205.255
	gateway 188.165.205.254
	post-up iptables -t nat -A POSTROUTING -s 10.42.0.0/24 -o br0 -j SNAT --to 188.165.205.xxx
	pre-down iptables -t nat -D POSTROUTING -s 10.42.0.0/24 -o br0 -j SNAT --to 188.165.205.xxx

iface br0 inet6 static
	address 2001:41D0:xxxx:96ce::1
	netmask 64

auto br0:0
iface br0:0 inet static
	address 10.42.0.1
	netmask 255.255.255.0

Pour le bridge, on met l'IPv4 publique et une règle iptable pour NAT-er ce qui sort. Le réseau privé est 10.42.0.0/24, on peut bien sûr choisir ce qu'on veut dans ce que fourni la RFC 1918.

Pour l'IPv6, chez OVH c'est bizarre : il fournissent un prefix 64 bit et avec une route accessible sur le /56 incluant, mais pas à partir du /64. Il faut donc ruser de la façon suivante niveau routage :

  • On assigne l'IPv6 avec le prefix /64, c'est plus propre, sinon le kernel se plaint avec /56 :
# ip -6 addr add 2001:41D0:xxxx:96ce::1/64 dev br0
  • On met une route pour atteindre la gateway dans le /56 :
# ip -6 route add 2001:41d0:xxxx:96ce::/56 dev br0
  • On met la route par défaut :
# ip -6 route add default via 2001:41d0:xxxx:96ff:ff:ff:ff:ff

Pour avoir cette configuration appliquée automatiquement, il faut créer /etc/network/if-up.d/ovh-ipv6-route :

#!/bin/sh

if [ "$IFACE" = "br0" ]; then
	ip -6 route add 2001:41d0:2:96ce::/56 dev br0
	ip -6 route add default via 2001:41d0:2:96ff:ff:ff:ff:ff
fi

Et pour l'arrêt, /etc/network/if-down.d/ovh-ipv6-route :

#!/bin/sh

if [ "$IFACE" = "br0" ]; then
	ip -6 route del default via 2001:41d0:2:96ff:ff:ff:ff:ff
	ip -6 route del 2001:41d0:2:96ce::/56 dev br0
fi

Il faut ensuite activer le forward entre interfaces, sinon pas de routage vers les VM, dans /etc/sysctl.conf :

net.ipv6.conf.all.forwarding=1

Enfin, le routage chez OVH ne permet pas d'intercaler un routeur pour découper le /64, il faut donc ruser avec du proxy NDP (Neighbor Discovery Protocol) :

  • On active le proxy NDP, dans /etc/sysctl.conf :
net.ipv6.conf.all.proxy_ndp=1
  • On ajoute les IP à proxiser, celle de la gateway et chacune des IP fournies aux VM :
# ip neigh add proxy 2001:41d0:xxxx:96ff:ff:ff:ff:ff dev br0
# ip neigh add proxy 2001:41d0:xxxx:96ce::2 dev br0

En cas de reboot d'une VM, il faut d'abord virer ses IP du proxy, puis les remettre, sinon le kernel de la VM se plein d'une duplication d'adresse :

# ip neigh del proxy 2001:41d0:xxxx:96ce::2 dev br0
-> reboot de la VM
# ip neigh add proxy 2001:41d0:xxxx:96ce::2 dev br0

mercredi 29 juin 2011

Rediriger stdout/stderr depuis un script avec du pipe

Pour rediriger stdout/stderr à l'interieur vers l'entrée standard d'un commande, il faut utiliser exec et du sous-shell. Cette astuce est un bashisme a priori.

L'objectif est de renvoyer tous les messages du script dans syslog sans mettre de redirection sur la ligne de commande. Le principe général est :

exec FD> >(COMMAND)
  • FD est le numéro du file descriptor, 1 pour stdout, 2 pour stderr
  • COMMAND est la commande a exécuter, elle doit bien sûr lire les données en entrée.

Un plus gros exemple :

SYSLOG="no"
 
# Load configuration file
CONFIG=/etc/myconfig.conf
if [ -f "$CONFIG" ]; then
    . $CONFIG
fi
 
# Redirect output to syslog if configured
if [ "$SYSLOG" = "yes" ]; then
    SYSLOG_FACILITY=${SYSLOG_FACILITY:-local0}
    SYSLOG_IDENT=${SYSLOG_IDENT:-postgres}
 
    exec 1> >(logger -t ${SYSLOG_IDENT} -p ${SYSLOG_FACILITY}.info)
    exec 2> >(logger -t ${SYSLOG_IDENT} -p ${SYSLOG_FACILITY}.err)
fi

avec dans la configuration :

  • SYSLOG : mettre à yes ou no pour activer
  • SYSLOG_FACILITY : ou envoyer
  • SYSLOG_IDENT : avec quel tag

L'exemple est pris d'un de mes scripts d'archivage pour PostgreSQL, ce qui permet de logguer dans syslog sans mettre de pipe dans archive_command (ce qu'il ne faut pas faire parce que ça casse : le code retour donné à PostgreSQL est celui de la dernière commande de la chaîne de pipe)

mardi 21 juin 2011

Combiner des PDF en un seul

Pour combiner des pdf en un seul, on peut essayer pdfjoin fournit par le projet pdfjam. En attendant que les 250 Mo de dépendances (Latex principalement) s'installent, on peut utiliser ghostscript :

gs -sDEVICE=pdfwrite -dNOPAUSE -dQUIET -dBATCH -sOutputFile=../combined_doc.pdf *.pdf

Merci à http://www.perlmonks.org/?node_id=4...

dimanche 10 avril 2011

Installation de cgit

Cgit est un programme CGI écrit en C qui permet d'obtenir une interface web de navigation pour un ensemble de dépôts git.

Cgit a besoin de OpenSSL, le paquet Debian est libssl-dev.

On récupère la version de stable de cgit :

$ wget http://hjemli.net/git/cgit/snapshot/cgit-0.9.tar.bz2
$ tar xjf cgit-0.9.tar.bz2

Il faut d'abord configurer l'installation en éditant le fichier Makefile. L'interface a besoin d'un endroit accessible par un serveur web, nous allons prendre /var/www/orgrim.net/git. On configure donc les chemins dans le Makefile, de cette façon :

CGIT_SCRIPT_PATH = /var/www/orgrim.net/git
prefix = /usr/local/cgit

Les binaires iront donc dans /var/www/orgrim.net/git/, les bibliothèques et autres fichiers dans une arborescence sous /usr/local/cgit, le fichier de configuration, sera /etc/cgitrc, la valeur par défaut.

Ensuite, il faut suivre les instructions données dans le README. On doit récupérer le dépôt git de git :

$ make get-git

Puis on compile et on installe :

$ make
$ sudo make install

On configure ensuite un virtual host Apache :

$ cat /etc/apache2/sites-enabled/git.orgrim.net 
<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	ServerName git.orgrim.net

	DocumentRoot /var/www/orgrim.net/git
	<Directory /var/www/orgrim.net/git>
        	Addhandler cgi-script .cgi
        	DirectoryIndex cgit.cgi
		Options +FollowSymLinks +ExecCGI
		AllowOverride None
		Order allow,deny
		allow from all

        	RewriteEngine On
        	RewriteBase /
        	RewriteCond %{REQUEST_FILENAME} !-f
        	RewriteCond %{REQUEST_FILENAME} !-d
        	RewriteRule (.*) cgit.cgi/$1
        	RewriteRule ^cgit.cgi$  cgit.cgi/
	</Directory>

   	## Logs
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	ErrorLog /var/log/apache2/orgrim.net/git_error.log
	CustomLog /var/log/apache2/orgrim.net/git_access.log combined

</VirtualHost>

On peut aller voir le site, il doit afficher une page générée par cgit montrant qu'aucun dépôt n'est configuré pour l'affichage.

Il faut maintenant créer le fichier de configuration, /etc/cgitrc en recopiant la partie exemple du fichier source de la doc cgit-0.9/cgitrc.5.txt.

Ici, l'important est de définir le paramètre de configuration pour matcher avec la configuration des rewrite rules du virtual host :

virtual-root=/

Enfin, les chemins vers la CSS et le logo sont à adapter, par rapport au document root du virtual host :

css=/cgit.css
logo=/cgit.png

Le reste de la configuration est assez facile à adapter, pour pouvoir ajouter ses dépôts.

jeudi 24 mars 2011

Insérer des tabulations dans sa ligne de commande bash

Il y a longtemps que je me demandais comment faire ça, sans prendre la peine de rechercher ou lire le man. C'est chose faite, pour insérer une tabulation, il faut contourner la complétion de commandes avec le combo suivant :

C-v TAB

C'est simple, mais ça ne s'invente pas.

Pour le coup, c'est utile quand on veut voir un fichier de configuration sans les commentaires, par exemple postgresql.conf :

grep -Ev '^(( |        )*#|$)' postgresql.conf

On doit donc taper une tabulation dans l'expression régulière : on affiche toutes les lignes qui ne satisfont pas la condition « tout ce qui commence par 0 ou plusieurs espaces ou tabulations suivi d'un dièse, ou une ligne vide ».