2011-06-14 23:09

La fonction PHP escapeshellarg dépend de votre locale courante. Je pense que c’est mal, mais les développeurs de PHP on fait ce choix. Si comme moi votre locale par défaut est ‘C’, vous perdez vos caractères UTF8.

Ils suggèrent d’utiliser quelque chose comme setlocale(LC_CTYPE, "en_US.UTF-8"). Ça ne fonctionne pas si la locale en_US.utf8 n’est pas installée sur votre système. Bien sûr vous avez peut-être fr_FR.utf8, ou de_DE.utf8, mais vous aller devoir toutes les essayer jusqu’à trouver une locale utf8 qui correspond. Et s’il n’y en a pas vous êtes foutus. C’est mauvais aussi si vous voulez du code qui marche partout.

Utilisez simplement :

$escapedArg = "'".str_replace("'", "'\\''", $arg)."'";

Ça fait la même chose que la fonction escapeshellarg : remplacer chainel'hyperlongue par

'chainel'\''hyperlongue'

comme décrit dans le manuel de escapeshellarg (et j’ai aussi jeté un œil au code source de PHP pour être sûr).

Voir aussi :

2011-06-14 23:09 · Tags: , ,
2011-03-13 21:42

Voici les quelques lignes que j’utilise pour sauvegarder mes bases de données MySQL sur mon serveur Debian :

#!/bin/sh
# This will dump all your databases

DATE=$(date +%Y%m%d%H%M)

for DB in $(echo "show databases" | mysql --defaults-file=/etc/mysql/debian.cnf -N)
do
        mysqldump --defaults-file=/etc/mysql/debian.cnf $DB > /backup/mysql/${DB}_${DATE}.sql

        gzip /backup/mysql/${DB}_${DATE}.sql
done

# purge old dumps
find /backup/mysql/ -name "*.sql*" -mtime +8 -exec rm -vf {} \;

Vous pouvez le lancer via un cron :

11 1 * * * /usr/local/bin/mysqldump.sh > /tmp/mysqldump.log

De cette manière, toute erreur affichée par le script sera envoyée par mail à l’utilisateur root (adresse configurée dans /etc/aliases).

Sous une autre distribution que Debian, s’il n’existe pas un fichier de mot de passe équivalent dans /etc/mysql/, vous devrez en créer un.

2011-03-13 21:42 · Tags: , ,
2011-01-13 23:32

J’ai récemment fait la demande et obtenu mon domaine en .42 !

http://positon.42

Les .42 ne sont pas (encore) officiels (c’est à dire agréés par l’ICANN et servi par les serveurs DNS racine).

Pour résoudre les domaines en .42, vous devez interroger un serveur DNS qui connait les .42.

Je reprend dans mon billet ma modeste contribution au wiki de 42registry.org, qui explique une manière de configurer cela sous Ubuntu :

The following allows you to use Geeknode DNS only for .42 domains while keeping your regular DNS provider for other domains.

Install dnsmasq :

aptitude install dnsmasq

Edit /etc/dnsmasq.conf and add the line :

server=/42/81.93.248.69

Restart dnsmasq :

sudo /etc/init.d/dnsmasq restart

Edit /etc/dhcp3/dhclient.conf, then uncomment or add the line :

prepend domain-name-servers 127.0.0.1;

Now disconnect and reconnect to you local network, to refresh the /etc/resolv.conf file, then test it !

Liens :

2011-01-13 23:32 · Tags: ,
2010-12-29 18:36

Vous disposez de deux systèmes et vous voulez mettre en place une sauvegarde sécurisée par rsync + SSH d’un système sur l’autre.

De manière très simple, vous pouvez utiliser la commande :

backup.example.com# rsync -avz --numeric-ids --delete root@myserver.example.com:/path/ /backup/myserver/

Pour faire la sauvegarde, vous devez être root sur le serveur, car certains fichiers ne sont lisibles que par root.

Problème : vous allez autoriser backup.example.com à faire n’importe quoi sur myserver.example.com, alors qu’un simple accès en lecture seule sur un dossier suffit.

Pour résoudre ce problème, il suffit d’utiliser la directive command="" dans le fichier authorized_keys pour filtrer la commande lancée.

Pour trouver cette commande, on lance rsync en ajoutant l’option -e'ssh -v' :

rsync -avz -e'ssh -v' --numeric-ids --delete root@myserver.example.com:/path/ /backup/myserver/ 2>&1 | grep "Sending command"

On obtient un résultat du genre :

debug1: Sending command: rsync --server --sender -vlogDtprze.iLsf --numeric-ids . /path/

Maintenant, il suffit d’ajouter la commande avant la clé dans le fichier /root/.ssh/authorized_keys :

command="rsync --server --sender -vlogDtprze.iLsf --numeric-ids . /path/" ssh-rsa AAAAB3NzaC1in2EAAAABIwAAABio......

Et pour encore plus de sécurité, on pourra ajouter un filtre par IP, et autres options :

from="backup.example.com",command="rsync --server --sender -vlogDtprze.iLsf --numeric-ids . /path/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAAB3NzaC1in2EAAAABIwAAABio......

Maintenant, vous pouvez essayer d’ouvrir un shell ssh, ou de lancer d’autres commandes rsync non autorisées…

Notes :

  • Attention, si vous changez les options de la commande rsync, à ne pas oublier de modifier aussi le fichier authorized_keys.
  • Plus besoin de chroot compliqué, vous pouvez oublier mon précédent article : SFTP-chroot-rsync

Voir aussi :

  • man ssh #/AUTHORIZED_KEYS FILE FORMAT
  • man rsync
  • view /usr/share/doc/rsync/scripts/rrsync.gz (restricted rsync, vous permet de gérer précisément les options autorisées)
2010-12-29 18:36 · Tags: , ,
2010-12-19 23:16

En ces temps d’Hadopi, je viens de tester le réseau I2P, qui fonctionne plutôt bien.

L’installation est très facile. Il suffit de télécharger le fichier .exe et de le lancer avec la commande java -jar comme indiqué (ça fonctionne sous Linux, oui oui).

Maintenant, si vous souhaitez accéder aux sites en .i2p, comme par exemple http://forum.i2p, vous devez configurer votre navigateur pour utiliser le proxy : localhost:4444

Si vous ne souhaitez pas utiliser le proxy pour vous connecter aux sites normaux non i2p, vous pouvez utiliser l’extension Firefox FoxyProxy.

Vous pouvez aussi utiliser directement un fichier PAC (Proxy Auto-Config) :

function FindProxyForURL(url, host) {
    if (dnsDomainIs(host, ".i2p")) {
        return "PROXY localhost:4444";
    } else {
        return "DIRECT";
    }
}

Ensuite, vous configurez Firefox, ou les préférences proxy de Gnome pour utiliser le fichier file:///chemin/vers/proxy.pac comme configuration.

Attention cependant : avec cette méthode, un eepsite (un site .i2p) mal intentionné peu arriver à détecter votre vraie adresse IP.

Liens :

2010-12-19 23:16 · Tags: , ,
2010-11-30 21:11

J’ai découvert Clementine il y a quelques temps déjà.

Il n’existe pas de paquet ni sous Ubuntu, ni sous Debian, mais le site officiel fournit un paquet .deb pour votre version d’Ubuntu préférée.
Il existe même en version Mac OS X et Windows…

Un petit clique sur le fichier .deb correspondant à votre distrib Ubuntu devrait suffire pour l’installer.

J’ai testé des tonnes de lecteurs (Amarok, Rythmbox, le vieux XMMS, Exaile, Listen, Totem…).

Clementine est un dérivé d’Amarok, très simplifié, et s’intègre très bien dans Gnome grâce aux librairies Qt4.

Bref, je suis heureux d’avoir découvert ce logiciel, que je vous recommande.

2010-11-30 21:11 · Tags: , , , ,
2010-11-09 23:51

Dans un précédent billet, j’expliquais comment mettre en place un “mangeur de courriel” avec Exim, de manière à se créer des adresses multiples qui redirigent toutes vers la même destination :

catchall_pub:
  driver = redirect
  domains = pub.mondomaine.com
  data = utilisateur@mondomaine.com

Ensuite, j’expliquais que sur l’adresse destination, on pouvait mettre en place un filtre Sieve ou Exim via un fichier .forward.

On peut vouloir mettre en place le filtre directement dans Exim, par soucis de centralisation de configuration, ou tout simplement si la boîte destination ne supporte pas les filtres.

Il suffit d’ajouter l’option local_parts :

catchall_pub:
  driver = redirect
  domains = pub.mondomaine.com
  local_parts = !/etc/exim4/pub.mondomaine.com.blacklist
  data = utilisateur@mondomaine.com

Dans /etc/exim4/pub.mondomaine.com.blacklist, on place les adresses rejetées, une par ligne :

toto1
titi2

Ainsi, les adresses toto1@pub.mondomaine.com et titi2@pub.mondomaine.com sont désormais rejetées.

Doc Exim4 :

2010-11-09 23:51 · Tags: , , ,
2010-10-30 16:50

Pour la gallerie d’images php Bizou, j’ai cherché différentes manière de précharger l’image suivante pour le mode “visualisation” (exemple).

Sous Firefox, c’est très simple. Il suffit d’utiliser la balise suivante pour que le navigateur précharge les contenus indiqués.
Les contenus sont préchargés en arrière-plan une fois que la page courante est chargée intégralement.

 [html]
<link rel="prefetch" href="/images/nextimage.jpg" />

Sauf que pour le moment seul Firefox supporte cette fonctionnalité.
Note : un ticket est ouvert sur le sujet pour le projet Chromium.

Pour les autres navigateurs que Firefox, il faut utiliser du Javascript déclenché à l’événement window.onload :

 [javascript]
<script type="text/javascript">
window.onload = function() {
    // pour les images
    var im = new Image();
    im.src = '/images/nextimage.jpg';
    // et pour les autres contenus
    var req = new XMLHttpRequest();
    req.open('GET', 'nextpage.php', false);
    req.send(null);
};
</script>

Attention aux en-têtes HTTP de cache envoyés par le serveur vers le navigateur.
Pour un préchargement efficace de page PHP, il faudra que votre script envoie un en-tête Expires.

header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 3600));

Enfin, pour une détection simple du navigateur depuis le script PHP :

<?php if (strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== false) { ?>
<link rel="prefetch" href="nextpage.php" />

<?php } else { ?>
<script type="text/javascript">
window.onload = function() {
    var req = new XMLHttpRequest();
    req.open('GET', 'nextpage.php', false);
    req.send(null);
};
</script>
<?php } ?>

Liens :

2010-10-30 16:50 · Tags: , , , , ,
2010-10-24 23:34

J’ai passé des heures à chercher sur le Web LE logiciel PHP qu’il me fallait, sans succès.

Les qualités requises :

  • Logiciel libre
  • Pas de base de données, dépôt des images dans un dossier et c’est tout.
  • Un code compréhensible que je puisse bricoler si besoin.
  • Le nombre de vignette en largeur qui s’adapte à la taille du navigateur.

Et voila, j’ai passé une autre fin de semaine recodant allègrement quelque chose qui existe surement déjà, mais au moins c’est simple et ça fait ce que je veux :

http://www.positon.org/bizou/fr.html

La démo ici

2010-10-24 23:34
2010-10-22 00:29

Trouver une bonne solution au problème du partage des fichiers entre utilisateurs Linux est un cauchemar.

Si elle convient il y a la solution de l’UID unique. Tous les clients accèdent aux fichiers avec le même UID utilisateur. Seulement on ne sais pas qui fait quoi. Et les utilisateurs ne peuvent pas gérer finement leurs droits.

Problème : le umask par défaut est TOUJOURS 0022, ce qui fait que tout fichier créé aura les droits rw– r–– r––. Seul le propriétaire peut écrire et personne d’autre.
Pour partager les fichier, un groupe doit aussi pouvoir écrire.

On peut changer ce umask. Pour la ligne de commande, ça se passe dans les fichiers .bashrc ou .profile, ou dans /etc/profile pour tous les utilisateurs. Pour un partage SFTP, on s’en sort avec un bricolage. Pour le serveur Apache, on s’en sort avec le fichier /etc/apache2/envvars sous Debian.

Si le partage de fichier se fait via un seul service, c’est simple de changer le umask, sinon, c’est compliqué. Et même en changeant tous les umask de tous les services, tout n’est pas parfait : par exemple, Nautilus via SFTP n’en fait qu’à sa tête. Certains clients posent le fichiers et font un chmod derrière : l’enfer. Il y a aussi la puissance des ACL POSIX qui permettent de forcer les droits. Mais là encore, certains clients vous poserons problème.

Enfin, on ne souhaite pas forcément que tous les fichiers soient posés avec l’écriture pour le groupe. On peut souhaiter une meilleure granularité.

D’expérience, j’ai abandonné l’idée du correctif à la source pour me tourner vers un bricolage agissant APRÈS la création du fichier.
La solution la plus simple est bien sûr la tâche cron, qui toutes les X minutes fait un chmod -R g+w sur un dossier. Déjà la solution n’est pas immédiate car désynchronisée de la création de fichiers, et elle rajoute une (très) petite charge supplémentaire à votre système.

Je propose une solution à base d’inotify, qui force les droits dès qu’un fichier est créé :

aptitude install inotify-tools

Et la commande magique :

inotifywait -mrq -e CREATE --format %w%f /tmp/mytest/ | while read FILE; do chmod g=u "$FILE"; done

MAJ 2010-10-30
Pour gérer les espaces en fin de fichiers, et les antislashs :

inotifywait -mrq -e CREATE --format %w%f /tmp/mytest/ | while IFS= read -r FILE; do chmod g=u "$FILE"; done

Merci à vitoreiji (voir commentaires)

La commande inotifywait écoute les événements du dossier /tmp/mytest. Dès qu’un fichier est créé, il est affiché sur la sortie standard. Chaque ligne-fichier est ensuite lue par la boucle while et les droits sont changés. Le g=u donne au groupe les mêmes droits que l’utilisateur (avec g+w, si l’utilisateur pose un fichier rw– ––– –––, les droits deviendraient rw– –w– –––).

Vous pouvez maintenant tester la création/copie de fichiers/dossiers. Même un mkdir -p a/b/c/d/e doit fonctionner.

Pour terminer, on ajoutera tout cela dans un script de démarrage :

vi /usr/local/bin/inotifywait.sh && chmod +x /usr/local/bin/inotifywait.sh
#!/bin/sh
# Take the directory name as argument

inotifywait -mrq -e CREATE --format %w%f "$1" | while read FILE
do
	chmod g=u "$FILE"
done
vi /etc/init.d/inotifywait.sh && chmod +x /etc/init.d/inotifywait.sh
#! /bin/sh

case "$1" in
  start|"")

	rm -f /tmp/inotifywait.log
	/usr/local/bin/inotifywait.sh /path/to/dir/ >/tmp/inotifywait.log 2>&1 &
	
	;;
  restart|reload|force-reload)
	echo "Error: argument '$1' not supported" >&2
	exit 3
	;;
  stop)
	# killall inotifywait ???
	;;
  *)
	echo "Usage: inotifywait.sh [start|stop]" >&2
	exit 3
	;;
esac

:

(sous Debian)

update-rc.d inotifywait.sh defaults

Note : un inconvénient : il y a une limite sur le nombre de fichier surveillés, voir l’option -r dans man inotifywait.

Et enfin la touche finale qui est utile pour que les fichiers créés conservent le groupe du dossier parent : le bit setgid au groupe pour tous les dossiers.

find /path/to/dir -type d -exec chmod g+s {} \;

Liens :

2010-10-22 00:29 · Tags: , , , ,