Quicksort C++ implementation

Hello. I just had to implement a quicksort algorithm version in C++ for an exercise. Here is what I’ve done:

The code on friendpaste.com

#include <iostream>
#include <vector>

using namespace std;

void swap(int &a, int &b)
{
    int temp;
    a = b;
    b = temp;
}

int split_array(vector<int>& array, int pivot, int start_index, int end_index)
{
    int left_boundary = start_index;
    int right_boundary = end_index;

    while (left_boundary < right_boundary) {

        while (pivot < array[right_boundary] && right_boundary > left_boundary) {
            right_boundary--;
        }

        swap(array[left_boundary], array[right_boundary]);

        while (pivot >= array[left_boundary] && left_boundary < right_boundary) {
            left_boundary++;
        }

        swap(array[right_boundary], array[left_boundary]);
    }

    return left_boundary;
}

void quicksort(vector<int>& array, int start_index, int end_index)
{
    int pivot = array[start_index];
    int split_point;

    if (end_index > start_index) {
        split_point = split_array(array, pivot, start_index, end_index);
        array[split_point] = pivot;
        quicksort(array, start_index, split_point-1);
        quicksort(array, split_point+1, end_index);
    }
}
Posted in None | Tagged | View Comments

Time Machine, FreeBSD and AFP are on a little boat

Okay, I just had set up a backup system from a MacBookPro (let’s say, the client) to a FreeBSD-powered server (quite boringly, the server). I chose Time Machine because of it’s nice and polished interface and its deep integration with OSX. After a lot of (too much?) tries and spent time, I chose the AFP for the protocol between the two machines. I decided to write this post because there are plenty of outdated posts on the web concerning this setup, and I didn’t manage to hit my goal with them. So my post relates a way which works for me.

On the FreeBSD server

AFP service

The AFP protocol is provided by NetATalk, a free AFP implementation. Let’s install it with the ports tree:

cd /usr/ports/net/netatalk/ && make install clean

Add it to your configuration: add the following to /etc/rc.conf:

netatalk_enable="YES"
afpd_enable="YES"

Define an obscure setting in /usr/local/etc/afpd.conf:

"Time Machine" -uamlist uams_dhx2.so

Add your Time Machine share into /usr/local/etc/AppleVolumes.default (edit to make it fits your needs):

/storage/timemachine/    "Time Machine" allow:thomas

Finally start the service:

/usr/local/etc/rc.d/netatalk start

Howl (optional)

Howl is a free implementation of the Apple’s Bonjour protocol. It’s used to spread hostnames and shares on your network. You don’t really need it, but I think it’s smarter to use it.

Install by the ports tree:

cd /usr/ports/net/howl/ && make install clean

Add to the configuration (/etc/rc.conf):

mdnsresponder_enable="YES"
mdnsresponder_flags="-f /usr/local/etc/mDNSResponder.conf"

Create the configuration file /usr/local/etc/mDNSResponder.conf and fill it:

"Home Time Machine Server"     _afpovertcp._tcp     local.     548

Start the service:

/usr/local/etc/rc.d/mdnsresponder start

Needed steps on the client

Unsupported Network Volumes

By default, Time Machine only allows you to use an AirPort-based system if you want to backup your data throught your network. So we need to ask it politely to enable the support for every network drive. Grab your terminal and type:

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1

The sparsebundle image

(source of this part: http://jakub.fedyczak.net/post/28)

Since filesystem provided by FreeBSD is not quite compatible with Time Machine, you have to create your own file system image. Use Disk Utility to create image:

  • Save As: MachineNameMacAddress MachineName as read from “System Preferences / Sharing / Computer Name field”. MacAddress has to be ethernet address of en0 – as displayed in ifconfig en0 result in ehternet line – without colons. For example: jf010203040506. Always use ethernet interface. Wireless interface won’t work.
  • Name: Time Machine
  • Size: Custom – greater than your HD size (in fact, it’s the amount of disk space you want to allow to your backups)
  • Format: I use Mac OS Extended (Journaled) but I’m not sure which one is the best.
  • Partitions: Single partition – Apple partition map
  • Image format: sparse bundle disk image

Resulting file should have .sparsebundle extension. Copy it to your remote FreeBSD drive and you’re done.

Posted in None | Tagged , | View Comments

Test your django-piston API (with auth)

I have to build the API for one of my web service. It’s Django and django-piston powered application and it works well. Okay. I chose the TDD technique. So my problem was: how do I test the API parts which need authentication (basic HTTP, not OAuth for now)? The built-in test client of Django doesn’t seem to have such a feature.

So, here is my small workaround: you have to generate the HTTP_AUTHORIZATION field of your HTTP request. I wrote a small base test class for tests which need authentication:

import base64
import unittest
from django.test.client import Client

class BaseAuthenticatedClient(unittest.TestCase):
    def setUp(self):
        self.client = Client()
        auth = '%s:%s' % ('username', 'password')
        auth = 'Basic %s' % base64.encodestring(auth)
        auth = auth.strip()
        self.extra = {
            'HTTP_AUTHORIZATION': auth,
        }

You just have to replace username and password, and write your own test suite:

class TestAPIAuth(BaseAuthenticatedClient):

    def testrootauth(self):
        response = self.client.get('/api/aresource/id', {}, **self.extra)
        self.assertEqual(response.status_code, 200)

It should be OK. Have fun!

Posted in None | Tagged | View Comments

Sync Google Contacts and AddressBook.app

You may be aware of some limitations you may encounter to sync your Google Contacts with your built-in Mac OS X address book, especially if you don’t have an iPhone/iPod Touch. Here is the most suitable solution I found to get round of this annoying problem.

  1. First of all, you must let your system think you have an iPod. Just open the file ~/Library/Prefereces/com.apple.iPod.pllist, and change de FamilyID to 1001, then save it. Property List Editor

  2. Open your AdressBook.app, go to Preferences, then click Account button, pick the “Sync with Google” checkbox and click the “Configure” button on the right of the latest. AdressBook preferences You will be prompted for you Google credentials.

  3. One last thing. Your contacts are not sync automatically when you edit some of them or when you quit AdressBook.app. You have to set up a small script which will be executed hourly (Note: this part uses the notion of cron). Create the file ~/Library/crontab, and write the following line inside:

    @hourly /System/Library/PrivateFrameworks/GoogleContactSync.framework/Versions/A/Resources/gconsync —sync com.google.ContactSync

Then open your Terminal.app and invoke: crontab ~/Library/crontab.

You should be ok, and your contacts will sync every hour. Have fun.

Posted in None | Tagged , | View Comments

Mint for fresher statistics

mint

Four days ago I finally bought Mint, for pelletier.im. I used to use WordPress’ plug-in for my weblog and Google Analytics for all my other projects. I decided to get rid of WordPress’ plug-in because of its lack of flexibility and its heavy use of Flash. I didn’t want to come back Analytics because its far too slow: it’s really annoying! Lots of people advised me to use Mint. Well, I was really reluctant to spend $30 for a web-based software bound to a specific domain name. But I have got a brainwave and picked up my calculator and realised that $30 equals €20. Mint became more affordable just like that!

Mint is now running on thomas.pelletier.im! Great. Here is what I like and what I don’t really love with it:

Strength

  • Really easy to install. Just set up your database (with your fancy shell script which uses mysql-client — or if you are less geeky just visit your Phpmyadmin page), copy Mint onto your server and magic happens.
  • Flexible : Mint comes with few peppers (modules), but you just have to go to the Peppermill, download, copy and install some of them and your Mint gets empowered by more magic powers!
  • Realtime : refresh your page (or use a pepper which will do such a nasty task for you) and see your statistics: you don’t have to wait 1 hour or anything else.
  • Shaun Inman is very nice and you will never feel alone on Mint’s forum.
  • You have the source : if something in Mint bothers you, just load your favourite text editor and go beat some PHP lines of code.

Drawbacks

  • Peppers aren’t archived in the Peppermill: I’m looking for FreshView, but as you can see the original website is off and I don’t manage to grab the pepper.
  • You can’t display statistics for a chosen sub-domain.
  • You can’t tweak the way anonymous users see your Mint page: they can see it, or they can’t.

To put it in a nutshell, Mint is really awesome and I don’t regret buying it but I think I’ll need to hack a bit to get rid of this sub-domain limit.

logo-mint Minted too.

Posted in English | Tagged | View Comments

Hey, I speak English too!

EnglishPhoto credits: London Symbols by X it

Or at least I try to. I know my English skills are neither really impressive nor even high. I think I am likely to make progress by practicing. In fact, I hope using English each time I write on the Web will be more efficient than writing every month at school a 300 words long text about poverty or inequalities (or any subject I have nothing to say about). So please, English users, don’t hesitate to pick holes in my posts!

Language is not the only change. As some of you may have noticed, “Kiznet” is now titled “Thomas Pelletier” (far more serious right?) and I put back the “Journalist” theme (which is smarter than the old one). Oh, one last change: the domain name has become thomas.pelletier.im instead of kiznet.fr. Please update your bookmarks!

(Blogger Tip) Have you ever tried Zemanta? It’s a freaking awesome tool which analyses texts and displays useful related informations (such as Wiki links, photos from Flickr and keywords).

Posted in English | Tagged | View Comments

Mercurial : Publier sur plusieurs dépôts

Le problème

Vous avez plusieurs dépôts Mercurial, en général un principal et un miroir (pour la sauvegarde). Cependant, toujours garder les deux dépôts synchronisés n’est pas toujours une mince affaire.

Une solution

Ayant fait fasse au problème ci-dessus il y a peu, j’ai cherché une solution qui pourrait le résoudre. Impossible cependant, de mettre la main sur quoi que ce soit. J’ai donc décider d’écrire ma première extension pour Mercurial. Voici hg-publishall. Une extension simple qui rajoute une commande à l’outil hg : pushall. Lors de son exécution, l’extension va lire le fichier .hg/hgrc du dépôt et y récupérer tous les éléments dans [paths], et pour chaque va effectuer un hg push <url_du_depot>.

Installation

Récupérez la dernière version du script : hg-publishall (trunk). Décompressez l’archive et déplacez le script publishall.py là où vous placez vos extensions Mercurial (chez moi c’est /Users/thomas/Library/Mercurial/). Pensez à le rendre exécutable par le ou les utilisateurs qui vont utiliser le script (chmod +x publishall.py sous Linux/BSD).

Vous devez ensuite configurer le dépôt qui va bénéficier de cette extension :

Soit le dépôt ~/depot-test/, j’ouvre le fichier ~/depot-test/.hg/hgrc et le modifie comme suit :

[paths]
default = ssh://server.localnet/depot-test/
bitbucket = https://:<user>:<pass>@bitbucket.org/<user>/depot-test/

[extensions] publishall = /Users/thomas/Library/Mercurial/publishall.py

Votre dépôt est maintenant configuré pour utiliser l’extension hg-publishall; et il sera publié sur deux autres dépôts : default (un dépôt sur le serveur du réseau local) et bitbucket (notez au passage que l’authentification sur les dépôts distant est exactement la même qu’ailleurs dans Mercurial).

Utilisation

Rien de bien compliqué. Toujours dans ~/depot-test/, après y avoir travaillé un peu comme vous en avez l’habitude, il suffit de taper :

$ hg pushall
Et c’est parti, les modifications que vous avez effectué sur le dépôt vont être publiées. Pour information : vous pouvez aussi utiliser hg pusha, qui est un alias à hg pushall.

Conclusion

Amusez vous bien, et n’hésitez pas à faire remonter tout ce que vous pouvez !

Posted in None | Tagged | View Comments

FreeBSD : serveur web Lighttpd

Je pars ici sur le fait que vous avez d’une part, les bases d’utilisation d’une FreeBSD (ou de n’importe quelle autre *BSD, voir distribution Linux) et d’autre part un système FreeBSD récent (7 series actuellement) installé, fonctionnel et connecté à internet.

Servir pour le web

Pour cela, vous devez déterminer quel serveur web remplira cette tache pour vous. Chacun ses choix, chacun ses arguments. Je choisi ici d’installer Lighttpd (a.k.a. Lighty), car il convient parfaitement à mes besoins et est simple pour une utilisation standard.

Je couvrirais ici son installation et sa configuration pour l’utilisation suivante :

Rien de bien sorcier, le tout étant d’être méthodique et de prévoir dès le départ où on veut aller.

Lighty

Rien de bien compliquer dans l’installation de Lighty par les ports :

$ cd /usr/ports/www/lighttpd

make install clean

Normalement, les options de compilation pour Lighty doivent vous être demandées. Voici celles que j’ai choisi :

Options de compilation Lighty

Options de compilation Lighty

Normalement, l’installation devrait se dérouler sans trop de problème. Ajoutez maintenant la ligne suivante à /etc/rc.conf :

lighttpd_enable="YES"
Rien d’autre à faire ici. Pour votre information, le fichier de configuration est placé suivant la norme FreeBSD : /usr/local/etc/lighttpd.conf. Pour lancer/arrêter/redémarrer le serveur, utilisez /usr/local/etc/rc.d/lighttpd start|stop|restart. Pour récupérer des infos en cas de soucis, c’est tail -f /var/log/lighttpd.error.log.

PHP5

Là aussi, on va utiliser les ports :

$ cd /usr/ports/lang/php5

make install clean

Rien de très palpitant ici. Il nous faut maintenant installer les extensions PHP voulues, toujours par les ports :

$ cd /usr/ports/lang/php5-extensions

make install clean

Lors de la configuration, la liste des extensions à installer devrait vous êtres demandée. Choisissez celles que vous voulez. Pour info, j’ai choisis celles-ci : ctype, curl, dom, gd, imap, mbstring, mcrypt, mysql, mysqli, pcre, posix, session, simplexml, xml, xmlreader, xmlrwriter, zlib.

A la fin de l’installation, ouvrez le fichier de configuration de Lighty et effectuez les modifications suivantes :

  • Dans la liste server.modules, dé-commentez mod_fastcgi.
  • Descendez et dé-commentez le bloc relatif à fastcgi.server :
    fastcgi.server = ( ".php" =>
                             ( "localhost" =>
                                  (
                                   "socket" => "/tmp/php-fastcgi.socket",
                                   "bin-path" => "/usr/local/bin/php-cgi"
                                  )
                             )
     )

Enregistrez et relancer Lighty. PHP est maintenant opérationnel (vous pouvez tester avec un <?php phpinfo(); ?>).

Django

C’est ici la partie qui m’intéresse le plus.

Premièrement, installez Django (notez que ceci n’est qu’une façon de faire) :

$ cd /usr/ports/devel/py-setuptools

make install clean

/usr/local/bin/easy_install django

OK. Bon, dans mon cas, j’ai une application située dans /storage/www/thomas/, qui sera accessible depuis le web par http://thomas.pelletier.im/. Adaptez suivant vos besoins.

  1. Créez un dossier public dans /storage/www/thomas/.
  2. Adaptez et placez-y le fichier lighty.sh suivant :
    #!/bin/sh
    app_path='/storage/www/thomas/'
    p='/tmp/thomas-django.pid'
    cd "$app_path"
    if [ -f $p ]; then
     kill $(cat -- $p)
     rm -f -- $p
    fi
    
    exec /usr/bin/env \
     PYTHONPATH="$app_path/.." python \
     manage.py runfcgi \
     daemonize=false \
     method=prefork \
     maxspare=2 \
     pidfile="$p"
  3. Rendez le exécutable par www :
    $ chown www:www lighty.sh
    $ chmod +x lighty.sh
  4. Créez un fichier vide django.fcgi dans public/ (pas nécessaire je pense, mais ça marche pour moi).
  5. Ajoutez le bloc suivant à votre ligtttpd.conf :
    $HTTP["host"] == "thomas.pelletier.im" {
            server.document-root = "/storage/www/thomas"
    
            url.rewrite-once = (
                    "^(/.*)$" => "/public/django.fcgi$1",
            )                    
    
            fastcgi.server = (
                    ".fcgi" => (
                            "django" => (
                                    "socket" => "/tmp/thomas-django.socket",
                                    "bin-path" => "/storage/www/thomas/public/lighty.sh",
                                    "check-local" => "disable"
                            )
                    )
            )
    
    }
  6. Enregistrez et relancer Lighty.

Normalement c’est bon, votre projet Django est maintenant servi par lighty !

Mercurial

NB : je ne vais pas entrer dans les détails de la configuration d’un dépôt mercurial.

Il existe plusieurs moyens de servir des dépôts mercurial. J’ai choisis hgwebdir. Le site officiel détail l’installation en CGI. Je trouve ça dommage. Pour ma part, j’utilise ici FastCGI.

Je pars du fait que vous avez vos dépôts déjà configurés et fonctionnels dans /mesdepots/ et que vous avez deux dépôts : un publique : “helloworld” et l’autre privé “myproject”.

Pour la petite histoire, helloworld sera accessible en lecture ET écriture par tout le monde. C’est fait exprès, à but purement pédagogique. myproject lui, n’est accessible en écriture et en lecture uniquement par vous.

Premièrement, créez un dossier hg dans /mesdepots/. Placez-y le fichier hgwebdir.fcgi suivant :

#!/usr/bin/env python
#

An example CGI script to export multiple hgweb repos, edit as necessary

adjust python path if not a system-wide install:

import sys

sys.path.insert(0, "/path/to/python/lib")

enable demandloading to reduce startup time

from mercurial import demandimport; demandimport.enable()

Uncomment to send python tracebacks to the browser if an error occurs:

import cgitb

cgitb.enable()

If you'd like to serve pages with UTF-8 instead of your default

locale charset, you can do so by uncommenting the following lines.

Note that this will cause your .hgrc files to be interpreted in

UTF-8 and all your repo files to be displayed using UTF-8.

#

import os

os.environ["HGENCODING"] = "UTF-8"

from mercurial.hgweb.hgwebdir_mod import hgwebdir from flup.server.fcgi import WSGIServer

The config file looks like this.  You can have paths to individual

repos, collections of repos in a directory tree, or both.

#

[paths]

virtual/path1 = /real/path1

virtual/path2 = /real/path2

virtual/root = /real/root/*

/ = /real/root2/*

#

[collections]

/prefix/to/strip/off = /root/of/tree/full/of/repos

#

paths example:

#

* First two lines mount one repository into one virtual path, like

'/real/path1' into 'virtual/path1'.

#

* The third entry tells every mercurial repository found in

'/real/root', recursively, should be mounted in 'virtual/root'. This

format is preferred over the [collections] one, using absolute paths

as configuration keys is not supported on every platform (including

Windows).

#

* The last entry is a special case mounting all repositories in

'/real/root2' in the root of the virtual directory.

#

collections example: say directory tree /foo contains repos /foo/bar,

/foo/quux/baz.  Give this config section:

   [collections]

   /foo = /foo

Then repos will list as bar and quux/baz.

#

Alternatively you can pass a list of ('virtual/path', '/real/path') tuples

or use a dictionary with entries like 'virtual/path': '/real/path'

WSGIServer(hgwebdir('hgweb.config')).run()

Toujours dans le même dossier, créez et complétez le fichier hgweb.config suivant :
[paths]
helloworld = /mesdepots/helloworld/
myproject = /mesdepots/myproject/

[extensions] hgext.highlight=

[web] style = monoblue allow_archive = bz2 gz zip baseurl = /hg/ pygments_style =

Dans le fichier .hg/hgrc de myproject, ajoutez les paramètres suivant dans le bloc [web] :
allow_push = monutilisateur
allow_read = monutilisateur
Vous allez maintenant devoir créer le fichier contenant les comptes virtuels (ie : les utilisateurs mercurial ne sont pas des utilisateurs système). Créez le fichier /mesdepots/hg/passwords et ajoutez une ligne par utilisateur (vous pouvez utiliser des outils en ligne pour générer les lignes à rajouter). Pensez que dans l’exemple, le nom d’utilisateur est monutilisateur.

Editez le fichier /usr/local/etc/lighttpd.conf en l’adaptant à vos besoin : ici, les dépôts sont accessibles depuis http://monsite.com/hg/.

$HTTP["host"] == "monsite.com" {
    server.document-root = "/mesdepots/"
    server.follow-symlink = "enable"
    fastcgi.debug = 1

url.rewrite-once = (
    "^/hg(.*)" =&gt; "/hg/hgwebdir.fcgi$1",
)

$HTTP["url"] =~ "^/hg/" {
    dir-listing.activate = "enable" 

    # My Private repositories
    auth.debug = 2
    auth.backend = "htpasswd"
    auth.backend.htpasswd.userfile = "/mesdepots/hg/passwords"
    $HTTP["url"] =~ "myproject/" {
        auth.require = ( "" =&gt; (
                "method" =&gt; "basic",
                "realm" =&gt; "This is a private repository. If not allowed, go fuck yourself.",
                "require" =&gt; "valid-user"
            )
        )
    }

    # Global config

    fastcgi.server = (
        ".fcgi" =&gt; (
            "hgwebdir" =&gt; (
                "bin-path" =&gt; "/mesdepots/hg/hgwebdir.fcgi",
                "socket" =&gt; "/tmp/hg.socket",
                "check-local" =&gt; "disable",
            )
        )
    )
}

}

Définissez l’utilisateur et le groupe www comme propriétaire du dossier /mesdepots/hg (chown -R www:www /mesdepots/hg). Donnez enfin les droits d’exécution à hgwebdir.fcgi (chmod +x /mesdepots/hg/hgwebdir.fcgi) et redémarrez votre lighty.

Posted in None | Tagged , , , | View Comments

FreeBSD : serveur DNS Bind9

Je pars ici sur le fait que vous avez d’une part, les bases d’utilisation d’une FreeBSD (ou de n’importe quelle autre *BSD, voir distribution Linux) et d’autre part un système FreeBSD récent (7 series actuellement) installé, fonctionnel et connecté à internet.

Gardez en tête que je n’aborde ici que les aspects techniques de l’affaire, le domaine des DNS étant un trop vaste sujet.

Je discerne deux utilisations d’un serveur de noms :

  1. Servir de cache pour le réseau local : les postes utilisant le serveur verront leur vitesse de résolution de noms augmenter fortement (chez moi, je suis passé de 400ms à 6ms).
  2. Agir en maître d’un domaine : cela vous permet, si vous possédez mondomaine.com, d’indiquer au monde que serveur.mondomaine.com réside à telle ou telle adresse IP, entre autres.

Bien sûr, il est possible de faire bien plus de choses avec Bind9, mais ça ne m’intéresse pour le moment pas. Gardez aussi à l’esprit que je présente une méthode pour atteindre les objectifs prévus. Il doit en exister pleins d’autres. Si la mienne ne vous convient pas, et ben allez voir ailleurs tiens :)

Installation de Bind9

En fait, cette section est plus faite pour faire beau qu’autre chose, car Bind9 (aussi connu sous le nom de Named) est installé par défaut sous FreeBSD. Pour l’activer, rien de plus simple :

  1. Ajoutez la ligne suivante à /etc/rc.conf
    named_enable="YES"
  2. Démarrez le démon :
    /etc/rc.d/named start

Néanmoins, je tiens à préciser un point : par défaut, Bind9 n’écoute qu’en local, c’est-à-dire que seule la machine sur laquelle il tourne peut y accéder. Si vous voulez ouvrir votre serveur à l’extérieur (votre réseau local, mais aussi le net),  modifiez la ligne suivante dans /etc/namedb/named.conf :

listen-on       { 192.168.0.16; };
192.168.0.16 est l’adresse IP sur le réseau local de la machine en question.

Servir de cache pour le réseau local

Bien. Tout se passe dans le fichier /etc/namedb/named.conf. Ouvrez le avec votre éditeur favori et suivez le guide.

Exploiter les serveurs DNS de votre FAI

Pour éviter que votre propre serveur DNS n’ai a attaquer directement les serveurs DNS mondiaux (pour des raisons d’efficacité et d’encombrement de réseau), vous devez donner à Bind9 l’IP du serveur DNS primaire et secondaire de votre FAI. Dans mon exemple, c’est Numéricable, mais vous devriez pouvoir trouver les infos concernant le votre sur cette page.

Recherchez, décommentez et complétez l’options forwarders comme ceci :

forwarders {
 89.2.0.1;
 89.2.0.2;
};

N’autoriser que votre réseau local

Si vous laissiez votre serveur DNS répondre à n’importe quelle machine, je pense que ça ferait bien mal à votre serveur, votre bande passante, et votre moral. C’est pourquoi nous allons définir une Acess Control List, que vous allez adapter suivant votre configuration actuelle.

Ajoutez ce bloc avant le bloc options du fichier de configuration :

acl localnet {
 127.0.0.1/32;
 192.168.0.1/24;
};
Ici, je dit qu’appartiendront au groupe localnet les ordinateurs ayant les ips de type 127.0.0. et 192.168.0., autrement dit : le serveur lui même et les ordinateurs de mon réseau local.

Les permissions

Le plus gros du travail est fait. Maintenant vous devez dire à Bind9 qu’il doit :

  • Autoriser les requêtes venant de tous le monde (important pour la suite, voyez-ci après si vous ne voulez pas que ce soit le cas).
  • N’autoriser uniquement les membres du groupe localnet crée plus tôt à demander de résoudre un nom dont le serveur n’est pas le maître (on appelle cela la recursion. C’est plus compliquer que ça, mais on va laisser la théorie de côté pour aujourd’hui).

Dans le bloc options du fichier de configuration, ajoutez les 3 lignes suivantes :

allow-query     { "any"; };
allow-transfer  { localnet; };
allow-recursion { localnet; };
Il est important que allow-query soit sur any si vous souhaitez agir en tant que maître d’un domaine (voir ci-après). Si seul le cache vous intéresse, n’accordez les requêtes que depuis localnet (pour éviter le flood) :
allow-query     { localnet; };
C’est tout ! Redémarrez Bind9 : /etc/rc.d/named restart, et admirez.

Agir en maître d’un domaine

Pour l’exemple, je vais configurer un domaine local : localnet. Pour information, si vous voulez gérer un domaine international (mondomaine.com par exemple), c’est exactement la même chose !

Le but de mon domaine local est de fournir des adresses canoniques à certaines de mes machines :

  • server.localnet -> mon serveur perso : 192.168.0.16
  • router.localnet -> le routeur de la maison : 192.168.0.1
  • hdd.localnet -> le disque dur réseau : 192.168.0.14

Et c’est tout. Mais c’est quand même déjà sympathique.

Je ne vais pas rentrer dans le détail de la configuration. Les fichiers parlent d’eux-mêmes, et si vous les trouvez obscur, Google arrivera à vous éclairer.

Premièrement, créez et complétez le fichier /etc/namedb/localnet :

$TTL    2h

@    IN    SOA    server.localnet. postmaster.localnet. ( 2009101201 8H 2H 1W 1D )

@    IN    NS    server.localnet.

server        A    192.168.0.16 router        A    192.168.0.1 hdd         A    192.168.0.14

C’est ce fichier qui permet à Bind9 d’associer une adresse IP à un nom (on lui donne le nom, il nous rend l’IP). Il faut aussi qu’il soit capable de faire l’inverse : on lui donne une IP, il nous donne le nom. Le fichier qui s’en occupe est relativement semblable.

Créez et complétez le fichier /etc/namedb/localnet.reverse :

$TTL 2h
@    IN    SOA    server.localnet. postmaster.localnet. (
                              2009101201
                              8H
                              2H
                              1W
                              1D
 )

@    IN    NS    server.localnet.

1     IN    PTR    router.localnet. 16    IN    PTR    server.localnet. 14    IN    PTR    hdd.localnet.

Notez que les nombres à gauche sont la dernière partie de l’adresse IP local de la machine cible. Exemple de mon routeur : son IP est 192.168.0.1 le numéro qui apparait en première place de sa ligne est donc 1.

Vous devez ensuite dire à Bind9 qu’il est le DNS maître du domaine localnet et qu’il ne doit répondre pour ce domaine qu’aux requête du groupe localnet (celui qu’on a crée plus haut).

Ajoutez à la fin du fichier /etc/namedb/named.conf :

zone "localnet" {
 type master;
 file "/etc/namedb/localnet";
 allow-query { localnet; };
};

zone "0.168.192.in-addr.arpa" { type master; file "/etc/namedb/localnet.reverse"; allow-query { localnet; }; };

Vous devez faire attention ici dans le deuxième bloc : 0.168.192 est l’inverse de 192.168.0. Donc si vos IP de votre réseau local sont du genre 192.168.1.*, vous devrez indiquer la zone 1.168.192.in-addr.arpa.

Redémarrez Bind9, et si votre ordinateur est configuré pour utiliser le serveur en tant que serveur DNS, vous devriez pouvoir ping router.localnet (dans mon exemple).

Conclusion

Voilà, c’est tout. C’est pas bien compliqué quand on y pense. Bon courage avec votre DNS !

Posted in None | Tagged | View Comments

FreeBSD : Serveur Mail

Je viens de trouver un excellent howto (en anglais) concernant la mise en place d’un serveur mail complet (IMAP/SMTP/webmail/antispam/antivirus) avec FreeBSD.

Je comptais en écrire un, mais je ne pense pas pouvoir faire mieux (tout au mieux, le traduire en français), donc le voici :

FreeBSD Mail Server Setup on purplehat.org

Posted in None | Tagged | View Comments