Installer un serveur dédié « Source » sur FreeBSD 8

Source Dedicated Server, le serveur de jeu dédié de Valve pour Team Fortress, Left 4 Dead et Counter Strike (entre autres), est un logiciel Linux ou Windows, propriétaire. Donc les choses ne se présentent pas forcément très bien pour une installation sur FreeBSD. Cependant, il n'y a pas beaucoup d'efforts à faire pour installer et faire fonctionner ce logiciel grace à la compatibilité Linux de FreeBSD.

Dans un premier temps il faut activer, si ce n'est déjà fait, la compatibilité Linux dans le noyau de FreeBSD :

# chargement manuel du module
kldload /boot/kernel/linux.ko
# activation du chargement automatique au démarrage
echo 'linux_enable="YES"' >> /etc/rc.conf 

Ensuite (et pas avant), on peut installer les librairies Linux. Pour FreeBSD 8, il faut installer la version f10 :

portinstall -PP linux_base-f10

Attention, si vous êtes en FreeBSD 64 bits (amd64), le package refusera de s'installer, il faudra alors utiliser :

portinstall linux_base-f10

On termine de préparer l'environnement de compatibilité Linux en montant le système de fichier procfs. Il faut ajouter la ligne suivante au fichier /etc/fstab

linproc         /compat/linux/proc      linprocfs       rw 0 0

puis faire un

mount -a

Enfin, on peut installer le client steam :

portinstall linux-steam

En réalité, c'est seulement un logiciel de mise à jour du client steam qui est installé, il faut lancer la mise à jour pour que la vraie commande steam soit installée. Je fais cette étape deux fois :

cd /usr/local/steam/
./steam
# on attend la fin de l'exécution
# puis on recommence 
./steam

Le binaire steam est maintenant installé, à jour, et totalement fonctionnel. Via ce client, il est possible d'installer n'importe quel jeu compatible. Voilà comment procéder pour installer Left 4 Dead 2 :

./steam -command update -game left4dead2 -dir /chemin/du/jeu

On remplacera /chemin/du/jeu par le chemin du répertoire dans le quel on souhaite stocker les fichiers du jeu. Attention, pour Left 4 Dead 2 il y a environ 8 Go à télécharger. Si vous êtes sur de l'UFS, c'est donc 8 Go de stockage qui seront consommés. Si vous êtes sur un volume ZFS avec compression GZip, il faut compter environ 4,2 Go d'espace disque consommé. Le téléchargement est assez long, faites une pause, voire même, lancez la commande avant d'aller vous coucher.

Après cela, le répertoire /chemin/du/jeu contiendra un répertoire left4dead2. Dans ce dernier se trouve un script de lancement qui permet de démarrer le serveur dédié Source : srcds_run.
Voici un exemple de lancement :

cd /chemin/du/jeu/left4dead2
./srcds_run -ip 192.168.1.1 +sv_lan 1

L'option -ip permet d'imposer l'IP sur la quelle le serveur écoute. C'est très utile car le script est d'une bêtise monumentale. En effet, pour une raison que j'ignore, le serveur dédié se lance par défaut en utilisant la toute première IP configurée dans le fichier /etc/rc.conf même si la ligne est commentée !
C'est à dire que si votre rc.conf contient les lignes suivantes :

#ifconfig_em0="inet 192.168.128.201  netmask 255.255.255.0"
ifconfig_em0="inet 193.30.227.216  netmask 255.255.255.192"

et bien cet abruti de serveur tente de se lancer sur l'IP 192.168.128.201, alors que, bien sûr, l'IP n'est pas active. Épargnez votre santé mentale, imposez dès le départ une IP à srcds.
L'option +sv_lan 1 quant à elle impose un fonctionnement sur le LAN uniquement, ce qui permet aisément de tester le fonctionnement du serveur sans l'ouvrir sur le monde.

Vous devrez veiller à quelques points de détail :

  • le firewall doit autoriser les connexions TCP et UDP sur les ports 26901 et 27015.
  • le jeu peut (doit) être lancé avec un utilisateur non privilégié. Créez un compte pour l'occasion, avec un shell /bin/nologin, et toute autre mesure de protection que vous jugerez nécessaire.
    Attention, faire tourner le jeu avec un utilisateur non privilégié n'est pas forcément très simple, surtout si vous l'avez installé en root. J'ai découvert que lancer le jeu une première fois en root peut régler certains problèmes.
  • l'utilisateur en question devra notamment pouvoir écrire dans les répertoires /chemin/du/jeu/left4dead2/update, /chemin/du/jeu/left4dead2/left4dead2 et /chemin/du/jeu/left4dead2/left4dead2/{downloads,logs} et dans les fichiers /chemin/du/jeu/left4dead2/left4dead2/*.cache
  • il devra aussi pouvoir exécuter les fichiers /chemin/du/jeu/left4dead2/srcds_run /chemin/du/jeu/left4dead2/srcds_linux

Pour un utilisateur non privilégié, en "nologin", le moyen fiable de lancer le serveur est d'utiliser sudo, dans un screen pour être tranquille :

cd /chemin/du/jeu/left4dead2/
screen nice -n -5 sudo -u utilisateur_steam ./srcds_run -ip 192.168.1.1

Avec tout ceci, votre serveur doit être fonctionnel, et permet déjà de jouer. Le plus dur reste à faire, puisque de toute l'histoire de l'informatique, ce sont les serveurs de jeu qui détiennent la triste palme des logiciels les moins bien documentés au monde. Créez un fichier /chemin/du/jeu/left4dead2/left4dead2/cfg/server.cfg et testez des combinaisons jusqu'à obtenir le résultat souhaité.

Related posts

Capture et analyse distante avec Wireshark

Wireshark est un outil sympathique, quand vient le moment d'analyser ce qui passe sur un réseau, qui fait quoi, quel protocole prend toute votre bande passante, etc. Malheureusement, la machine sur la quelle on voudrait faire l'analyse n'est pas toujours celle sur la quelle vous pouvez lancer le logiciel.
Il est possible facilement de capturer les paquets voulus sur une machine, et de les analyser à postériori sur une autre. Par contre, effectuer une analyse en direct et à distance nécessite d'utiliser quelques astuces.
Avant d'aller plus loin dans les explications, voici quelques pré-requis :

  • Vous devez installer Wireshark sur votre machine (A)
  • Vous devez aussi pouvoir vous connecter en root via SSH sur la machine que vous voulez utiliser pour la capture (B)

Dans un premier temps, il s'agit de créer un socket UNIX via mkfifo. C'est ce socket que votre Wireshark va lire en local sur la machine A.

mkfifo capture.fifo

Dans un deuxième temps, il faut ouvrir une connexion SSH de A vers B, lancer tcpdump dans cette connexion, et rediriger la sortie standard dans votre tout nouveau socket.

ssh root@machineB tcpdump -s 0 -U -n -w - -i ath0 >  capture.fifo

Remplacez ath0 par le nom de l'interface réseau qui vous intéresse, et éventuellement, ajoutez aux options de tcpdump les filtres adéquats pour affiner votre analyse.
Attention, pour une connexion avec mot de passe, ssh ne vous demandera le fameux sésame qu'au moment où Wireshark ouvrira le socket. C'est à dire à l'étape suivante.

Dans un troisième et dernier temps, vous pouvez lancer Wireshark sur la machine A si ce n'est déjà fait, et le configurer pour lire votre socket capture.fifo. Pour cela, ouvrez les options de capture, et saisissez le chemin de votre socket dans le champ "interface" :

Enfin, cliquez sur "Start" pour lancer la capture, et si nécessaire, tapez votre mot de passe pour la machine B dans la fenêtre de terminal où votre connexion SSH est établie.

Related posts

Concours photo « La Vie en Rose »

C'est malheureux à dire, mais une fois de plus je constate que le plaisir du plus grand nombre est gâché par la bêtise d'une minorité. Finalement ce n'est rien d'autre qu'une vraie constante de la nature humaine qui se vérifie aujourd'hui avec le concours photo "La Vie en Rose" organisé dans le cadre de la biennale de la danse.
photo (c) Thomas GasparettoLe but du jeu est simple : chaque personne peut envoyer jusqu'à trois photos, prises pendant le défilé de la biennale, et illustrant le thème de "la vie en rose". Chaque visiteur (adresse IP) peut voter une fois par jour pour sa photo favorite.
Les organisateurs ont eu en plus la bonne idée de ne pas afficher toutes les photos à chaque visiteur. Ainsi, avant d'avoir voter, vous pouvez visionner un peu plus de 30 pages de 8 photos chacune sélectionnées au hasard dans la masse de photos des candidats, et présentées dans un ordre aléatoire. Vous pouvez alors voter pour un seul cliché. Après votre vote, vous pouvez visionner, si le cœur vous en dit, plus de 140 pages de photos, classées par ordre de nombre de votes.

Quelques utilisateurs sont tout de même parvenus à pervertir ce système de vote. Ce n'était pas bien compliqué, c'est certain, mais était-ce bien nécessaire ? Ils ont localisé dans le code HTML une adresse qui permet de voter pour une photo donnée sans l'étape laborieuse du visionnage. Ils ont alors sans aucun doute transmis l'URL adéquate à leurs "amis" de facebook, et c'est ainsi que la plupart des photos en tête de classement sont à la fois totalement hors sujet et complètement inintéressantes. On en voit même certaines gagner plus de 200 votes en quelques minutes. Le pire, c'est qu'il est même techniquement possible de faire voter les gens pour une photo précise à leur insu.

Je ne suis pas surpris que des types pas drôles et sans grande morale se livrent à ce genre de sport. Je suis juste un peu écœuré pour les participants honnêtes, dont les photos sont parfois très jolies et pertinentes, car ils ne seront pas récompensés.
Comment peut on encore participer de bonne foi à ce genre de concours, si on sait que de toute manière seuls les plus roublards, les plus tricheurs, les moins finauds gagneront ?

crédit photo : Thomas Gasparetto

edit : le règlement du concours a été mis à jour, le choix des gagnants sera fait par un jury. Voilà qui est une bonne nouvelle (et qui ne me laisse aucune chance ;) )

Related posts

Quelques nouveautés

En ce début d'année (scolaire, puisque dans l'éducation nationale on fonctionne comme ça), j'ai décidé d'ajouter une version "mobile" à ce blog, et à ma galerie photo. Mon entourage connaît en général mon dédain plus que profond pour tout ce qui ressemble à un téléphone permettant d'accéder à internet (tous les iBidules en général, en fait). J'aurai donc pu facilement m'abstenir de passer de longues heures à ajuster une version "mobile" de mes sites. Finalement, j'ai réalisé que c'est pour moi une manière ironique et provocante d'aller au bout de ma démarche : utilisateurs de iBidules, vous aurez droit à une version amputée du site. Sans doute bien plus lisible, mais partielle.
Cela dit, et sans mauvais esprit aucun : bonne visite à tous.

Et puis, pour justifier le pluriel de mon titre : j'ai aussi cédé aux sirènes des réseaux sociaux, puisque je suis désormais inscrit sur LinkedIn et Viadeo (Shame. On. Me.).

Related posts

Sylights : une idée lumineuse ?

Sylights, c'est un site web intéractif qui vous permet de construire et partager des plans d'installation de lumières pour des prises de vues. Si vous êtes photographe, et que vous travaillez souvent avec du matériel pour façonner votre lumière, vous comprenez ce dont il s'agit.
Boîtes à lumière, réflecteurs, "gobo", fonds, flashes… tout est là, ou presque, pour vous permettre de cartographier fidèlement vos montages de prise de vue. Il manque tout de même de quoi annoter les plans, et peut être quelques éléments comme des murs.

Je pense que c'est un très bon complément à Flickr (même si je n'utilise pas ce dernier).
Sylights devrait s'étoffer rapidement, avec des fonctions d'annotation, et la possibilité de poster des photos illustrant le montage de lumière décrit (ça semble primordial !).

Un petit exemple tout simple pour la route : mon premier essai.

L'avenir nous dira si c'est une idée lumineuse ou pas. Mais quand les plans seront ré-éditables, qu'on pourra y faire des annotations, et qu'on pourra les "hot-linker" depuis un blog, ça deviendra certainement un outil de référence !

Related posts

Créer un proxy personnalisé avec launchd (2/2)

Cet article est la suite de la première partie : "Créer un proxy personnalisé avec launchd (1/2)"

Coder votre proxy personnalisé.

C'est théoriquement l'étape du travail la plus intéressante, puisque c'est ici que l'on peut exprimer toute sa créativité, et surtout apporter la réponse à un de ses problèmes. Comme le programme sera lancé à la demande par launchd, et que c'est ce dernier qui va gérer le socket de communication avec le client, la tâche est simplifiée. En contrepartie, le programme ne peut pas être trop lourd, car des lancements à répétition seraient alors pénalisants pour le reste du système.
Mac OS X est livré avec de nombreux langages de script et de programmation (C, Java, PHP, Python, Ruby, Perl, Shell…). Contrairement à mon habitude, j'ai choisi de coder mon proxy en PHP. De la sorte, je pouvais réutiliser mon code dans un autre contexte au cas où le fonctionnement en proxy ne donnait pas satisfaction.
Voici le squelette de mon script PHP, à titre d'exemple :

#!/usr/bin/php
<?php
// get request from http client
$request = explode(" ", trim(fgets(STDIN)));
$MyGET = $request[1];
// curl request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $MyGET);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
// cleanup
curl_close($ch);   

// callback
function fetch_author($matches) {
    ../..
    return $matches[1].$matches[2].$author[1]." ".$matches[3];
}

// html parsing
$apresreplace = preg_replace_callback('/.../',"fetch_author",$output);

// output
echo $apresreplace;
?>

J'ai volontairement simplifié et tronqué mon code. La seule chose qui compte est le squelette du programme. Première remarque, le script fonctionne en mode "ligne de commande". C'est du PHP, mais il ne sera pas interprété par Apache, donc les variables intéressantes de $_SERVER, de $_GET, ... n'existent pas. Je récupère la requête du client HTTP en lisant tout simplement la première ligne de STDIN.
Ensuite, j'utilise les fonctions de la librairie CURL pour aspirer le contenu distant qui correspond à l'URL transmise par le client. Puis je fais sur ce contenu un rechercher-remplacer via la fonction preg_replace_callback et via la fonction attachée que j'ai créée (dite fonction de callback).
Les détails ne sont pas importants, à ce stade ce qu'il faut bien comprendre, c'est que mon script de proxy a reçu l'URL demandée par le client. Il a téléchargé le contenu correspondant à cette URL, et il l'a enrichi selon mes besoins. La dernière ligne du script renvoie dans la sortie standard le contenu enrichi. Le client (mon lecteur de flux RSS) reçoit alors la réponse à sa requête.

Lancer le proxy à la demande

Launchd est l'outil idéal pour lancer le proxy dès qu'une connexion est initiée dans sa direction. Le fonctionnement est alors similaire à inetd (ou xinetd). La problématique est la même que dans le cas de la création d'un tunnel ssh à la demande, donc je passe sur les détails.
Voici le fichier plist de configuration qu'il faut charger dans launchd pour activer le proxy :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Debug</key>
        <false/>
        <key>Label</key>
        <string>tld.monsuper.proxy</string>
        <key>ProgramArguments</key>
        <array>
                <string>/chemin/du/programme/de/proxy</string>
        </array>
        <key>Sockets</key>
        <dict>
                <key>Listeners</key>
                <dict>
                        <key>SockNodeName</key>
                        <string>127.0.0.1</string>
                        <key>SockServiceName</key>
                        <string>8080</string>
                        <key>SockType</key>
                        <string>stream</string>
                </dict>
        </dict>
        <key>StandardErrorPath</key>
        <string>/tmp/proxy.err</string>
        <key>inetdCompatibility</key>
        <dict>
                <key>Wait</key>
                <false/>
        </dict>
</dict>
</plist>

Après avoir adapté le Label, le chemin du programme, le port de connexion, et éventuellement le fichier de stderr, il faut enregistrer ce fichier plist dans ~/Library/LaunchDaemons/ (pour vous seul) ou dans /Library/LaunchDaemon/ (pour tous les utilisateurs de la machine). Ensuite il faut le charger via launchctl load /chemin/du/fichier.plist.

C'est terminé. Toutes les briques du proxy personnalisé sont en place. Le client (si il honore bien les préférences systèmes) utilisera le proxy désigné dans le fichier .PAC. Launchd recevra la requête et la transmettra au programme du proxy. Ce dernier fera les traitements sur les données téléchargées, et renverra le résultat au client.

edit : style et coquilles
edit : ajout de l'IP 127.0.0.1 pour le bind, ça évite que le proxy puisse êtes utilisé par n'importe qui sur le réseau… :)

Related posts

Créer un proxy personnalisé avec launchd (1/2)

Pourquoi un proxy personnalisé ?

De temps en temps, on aimerait modifier pour son confort personnel des flux de données que l'on ne maîtrise pas. Ces derniers jours par exemple, j'ai été confronté à un flux RSS qui ne contient pas toutes les données dont j'ai besoin. J'ai donc créé un proxy HTTP personnalisé pour enrichir le flux RSS et obtenir un résultat complètement satisfaisant.
On peut bien sûr appliquer le même principe à tout un tas de choses. Le gros avantage de l'opération, c'est que l'on est libre de coder avec le langage de son choix, sans se compliquer la vie : launchd prend en charge la partie "réseau local" et les préférences système s'occupent de publier les réglages de proxy auprès des clients. Il ne reste finalement à s'occuper que de la partie intéressante du code : la transformation des données reçues (ou envoyées).

Schema de l'architecture logique du proxy personnalisé

Vue d'ici, la partition peut sembler complexe à jouer : il faut faire communiquer un client avec un serveur au travers d'un proxy lancé à la demande par launchd, le tout en s'appuyant sur les préférences système de proxy. Il y a donc quelques pré-requis de base. Il faut que la version de Mac OS X supporte la configuration automatique de proxy (testé sur 10.5 et 10.6). Et il faut aussi que le client supporte l'utilisation des proxy définis dans les préférences système.

Configurer les préférences de proxy de Mac OS X.

Il s'agit de ne pas de faire passer tout le trafic au travers de notre script maison, mais seulement des requêtes bien particulières. On utilise pour cela les préférences de configuration automatique de proxy. La configuration automatique de proxy s'appuie sur un fichier en javascript, qui fournit les règles de proxy que l'on souhaite utiliser. Normalement ce fichier est distribué automatiquement via DHCP, ou mis à disposition sur le réseau via une URL standardisée. Ici, nous allons procéder à la main.
La première étape consiste à créer un fichier PAC contenant les règles souhaitées. C'est un simple fichier texte. Voici le contenu du fichier "proxy.pac" que j'ai créé pour répondre à mes besoins :

function FindProxyForURL(url, host) {
      if (shExpMatch(url, "*cfsl.net/forum*/feed.php*"))    {
         return "PROXY localhost:8080";
      } 
      // All other requests go directly to the WWW:
      return "DIRECT";

Le fichier décrit les règles suivantes :
- si l'URL que je demande contient *cfsl.net/forum*/feed.php*, alors utilise le proxy à l'adresse localhost:8080.
- dans tous les autres cas, n'utilise pas de proxy.

Vous trouverez d'autres exemples de fichiers PAC sur wikipedia et ailleurs.

La seconde étape est l'activation de ces règles dans les préférences système. Il faut pour cela ouvrir les préférences réseau, et entrer dans les paramètres avancés de l'interface réseau active. Sous l'onglet "Proxy", on retrouve une case à cocher correspondant au mécanisme de configuration automatique de proxy. Il faut cocher cette case, et désigner le chemin du fichier PAC créé à la première étape :

Et voilà, maintenant il ne reste plus qu'à créer le programme de proxy et son plist de lancement.
Lire la suite !

Related posts

Hello Bokeh !

La distribution de noms de domaine gratuits a été un beau succès. Et c'est avec plaisir que je vous communiquerai les adresses des sites créés à cette occasion.

Le premier porte un nom que je trouve choupinou tout-plein : Hello Bokeh ! Bravo annso.

J'attends les vôtres :)

Related posts