<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>MadeInSyria.fr</title>
	
	<link>http://madeinsyria.fr</link>
	<description>For A Geek New World</description>
	<lastBuildDate>Sat, 22 Oct 2011 17:00:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/madeinsyria" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="madeinsyria" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">madeinsyria</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>[Summer Camp] Etape 5 : Mise en cache avec Varnish</title>
		<link>http://madeinsyria.fr/2011/10/summer-camp-etape-5-mise-en-cache-avec-varnish/</link>
		<comments>http://madeinsyria.fr/2011/10/summer-camp-etape-5-mise-en-cache-avec-varnish/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 22:09:35 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[Mes Projets]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=841</guid>
		<description><![CDATA[On a une infra haute dispo, mais pas encore vraiment haute perf. Pour y passer, on va utiliser Varnish qui mettra en cache les pages de notre site ! Ce n&#8217;était pas prévu au planning initial que j&#8217;ai posé une nuit très tard&#8230; Mais c&#8217;est un MUST ! Varnish sera situé entre le load balancer et les [...]]]></description>
			<content:encoded><![CDATA[<p>On a une infra haute dispo, mais pas encore vraiment haute perf. Pour y passer, on va utiliser Varnish qui mettra en cache les pages de notre site ! Ce n&#8217;était pas prévu au planning initial que j&#8217;ai posé une nuit très tard&#8230; Mais c&#8217;est un MUST !</p>
<p>Varnish sera situé entre le load balancer et les frontaux (qu&#8217;il load balancera). Sont fonctionnement est simple :</p>
<ol>
<li>Je reçois une requête pour la page X</li>
<li>L&#8217;ai-je dans mon cache ?</li>
<li>Si oui je fournis == je soulage un frontal et les bases de X requêtes</li>
<li>Si non je récupère et je la cache si possible (on ne peut pas cacher les pages d&#8217;utilisateur logé par exemple)</li>
</ol>
<p>Il est cependant vrai qu&#8217;en environnement de production, on mettra les caches devant les load balancer afin d&#8217;éviter de charger les load balancer pour rien. Leur load balancing se fera alors en Round-Robin DNS.</p>
<p>Vous allez voir, c&#8217;est simple et efficace ! Je vais montrer pour une des deux VM, la deuxième sera une copie conforme.</p>
<h2><span id="more-841"></span></h2>
<h2>Prérequis :</h2>
<p>Nous allons donc utiliser dans ce tuto deux machines sous FreeBSD 8.2 (load balancer par le load balancer) :</p>
<ul>
<li>4 vCPU</li>
<li>1024Mo de RAM</li>
<li>Un disque de 40Go pour un site &#8220;normal&#8221;</li>
<li>1 cartes réseau : une sur le VLAN LB-FRONT</li>
</ul>
<h2>Installation de Varnish :</h2>
<p>La version de varnish dans les ports de FreeBSD est à jour, nous allons donc l&#8217;utiliser ! Avant tout on s&#8217;assure d&#8217;avoir des ports bien à jour :</p>
<pre lang="bash">oaf-prj-cache# portsnap fetch &#038;&#038; portsnap extract &#038;&#038; portsnap update</pre>
<p>Puis on installe Varnish :</p>
<pre lang="bash">oaf-prj-cache# cd /usr/ports/www/varnish
oaf-prj-cache# make install &#038;&#038; make clean</pre>
<p>Et voilà&#8230; C&#8217;est bon&#8230;</p>
<h2>Configuration de Varnish :</h2>
<p>Varnish utilise un langage de configuration très puissant nommé &#8220;VCL&#8221; pour Varnish Configuration Language (pas très original). Tous les fichier .vcl dans le répertoire de configuration (/usr/local/etc/varnish/) sont interprétés.</p>
<p>Voici dont un fichier, commenté comme d&#8217;habitude, en guise d&#8217;explications :</p>
<pre lang="bash">oaf-prj-cache# vim test.fr.vlc

#On défini nos frontaux
backend web01 {
   #On défini le hostname...
  .host = "oaf-srv-web01";
   #...le header sur lequel matcher...
  .host_header = "test.fr";
   #...le port d'écoute...
  .port = "80";
   #...le nobre de connexion pour le front...
  .max_connections = 5000;
   #...le timeout des sessions...
  .connect_timeout = 60s;
   #...le timeout après l'initiation de la session...
  .first_byte_timeout = 6s;
   #...le timeout entre deux paquets...
  .between_bytes_timeout = 6s;
}

#...Idem pour le deuxième frontal...
backend web02 {
  .host = "oaf-srv-web02";
  .host_header = "test.fr";
  .port = "80";
  .max_connections = 5000;
  .connect_timeout = 60s;
  .first_byte_timeout = 6s;
  .between_bytes_timeout = 6s;
}

#Puis on crée le groupe de front load balancé
director test_fr {
        {
                .backend = web01
        }
        {
                .backend = web02
        }
}

#Pour matcher sur toute les requêtes et augmenter la cachabilite, on réécrit les header
sub vcl_recv {

  if (req.http.host ~ "(?i)^localhost$") {
  set req.http.host = "test.fr";
  set req.backend = test_fr;
  }

  if (req.http.host ~ "(?i)^12.34.56.78$") {
  set req.http.host = "test.fr";
  set req.backend = test_fr;
  }

  if (req.http.host ~ "(?i)^test.fr$") {
  set req.http.host = "test.fr";
  set req.backend = test_fr;
  }

  if (req.http.host ~ "(?i)^test.fr$") {
  set req.http.host = "test.fr";
  set req.backend = test_fr;
  }

  if (req.backend.healthy) {
                set req.grace = 30s;
        } else {
                set req.grace = 1h;
  }

  if (req.url ~ "\.(.flv|js|css|jpg|jpeg|ico|png|gif|tgz|bz2|tbz|mp3|ogg|swf)$") {
    return (lookup);
  }

  if (req.http.Range) {
    return(pipe);
  }

  # Add a unique header containing the client address LOG
  remove req.http.X-Forwarded-For;
  set    req.http.X-Forwarded-For = client.ip;
}

#On défini ce que l'on peut cacher
sub vcl_fetch {

  if (req.url ~ "\.(flv|js|css|jpg|jpeg|ico|png|gif|tgz|bz2|tbz|mp3|ogg|swf)$") {
  set beresp.ttl = 2h;
  unset beresp.http.set-cookie;
  return (deliver);
  }

  #On defini la durée de vie du cache
  set beresp.ttl = 1h;
  set beresp.grace = 2h;
  return (deliver);

}

sub vcl_hit {

        # Le force-refresh met à jour le cache
        if (req.http.Cache-Control ~ "no-cache") {
                # Ignore requests via proxy caches, IE users and badly behaved crawlers
                # like msnbot that send no-cache with every request.
                if (! (req.http.Via || req.http.User-Agent ~ "bot|MSIE")) {
                        set obj.ttl = 0s;
                        return (restart);
                }
        }

        return (deliver);
}</pre>
<p>Et voilà !</p>
<p>Il ne reste plus qu&#8217;à ajouter les entrés au fichier host :</p>
<pre lang="bash">oaf-prj-cache# echo "192.168.10.10       oaf-srv-web01" >> /etc/hosts
oaf-prj-cache# echo "192.168.10.11       oaf-srv-web02" >> /etc/hosts</pre>
<p>On ajoute le service en démarrage automatique au lancement du sytème :</p>
<pre lang="bash">oaf-prj-cache# echo 'varnishd_enable="YES"' >> /etc/rc.conf</pre>
<p>Pour finir on fait pointer les load balancer sur les varnish, mais ça vous savez déjà faire !</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/10/summer-camp-etape-5-mise-en-cache-avec-varnish/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Etape 4 – Load balancing HAPROXY et stunnel</title>
		<link>http://madeinsyria.fr/2011/10/summer-camp-etape-4-load-balancing-haproxy-et-stunnel/</link>
		<comments>http://madeinsyria.fr/2011/10/summer-camp-etape-4-load-balancing-haproxy-et-stunnel/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 13:32:47 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[HAPROXY]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[stunnel]]></category>
		<category><![CDATA[SysAdmin]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=826</guid>
		<description><![CDATA[On continu d&#8217;avancer et on touche presque à la fin. A la fin de ce tuto, on aura une plateforme web fonctionnelle. Aujourd&#8217;hui nous allons mettre en place le load balancer HAPROXY qui aura pour objectif de répartir la charge entre les deux frontaux web installés mais aussi stunnel qui s&#8217;occupera de gérer la couche [...]]]></description>
			<content:encoded><![CDATA[<p>On continu d&#8217;avancer et on touche presque à la fin. A la fin de ce tuto, on aura une plateforme web fonctionnelle. Aujourd&#8217;hui nous allons mettre en place le load balancer HAPROXY qui aura pour objectif de répartir la charge entre les deux frontaux web installés mais aussi stunnel qui s&#8217;occupera de gérer la couche SSL (HAPROXY en étant dépourvu). Cette machine portera l&#8217;IP publique de notre site.</p>
<p>Le flux passera donc par HAProxy pour les connexions HTTP qui répartira la charge sur les frontaux web. Dans le cas du HTTPS, stunnel reçoit la connexion, la forward à HAProxy qui la forward au frontaux web.</p>
<p>J&#8217;entend d&#8217;ici : mais c&#8217;est un SPOF ! On se calme, l&#8217;étape 5 va nous permettre de clusteriser cette brique (et le <a title="[Summer Camp] Etape 3.2 – MySQLProxy : Split Read/Write" href="http://madeinsyria.fr/2011/10/summer-camp-etape-3-2-mysqlproxy-split-readwrite/">MySQLProxy</a> aussi <img src='http://madeinsyria.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) .</p>
<p>Sans plus attendre, on attaque !</p>
<p><span id="more-826"></span></p>
<h2>Prérequis :</h2>
<ul>
<li>4vCPU</li>
<li>1024Mo de RAM</li>
<li>Un disque (j’utilise des VMDK) 8Go pour le système</li>
<li>2 cartes réseau sur, une sur VLAN LB-Front et l&#8217;autre sur l&#8217;Internet</li>
</ul>
<p>L’OS qui portera ce beau monde est : FreeBSD 8.2 x64. On a besoin d&#8217;une stack TCP/IP robuste et d&#8217;un OS économe en resource (je viens de donner une partie de la définition de FreeBSD).</p>
<h2>Installation de HAPROXY :</h2>
<p>La version de HAPROXY étant relativement récente dans les dépôts FreeBSD, on lance une installation à la FreeBSD, très classique :</p>
<pre lang="bash">root@haproxy-pts/0 [/usr/ports]# cd /usr/ports/net/haproxy
root@haproxy-pts/0 [/ports/net/haproxy]# make config &#038;&#038; make &#038;&#038; make clean</pre>
<p>Et voilà ! HAProxy est déployé ! On l&#8217;ajoute aux services à lancer au démarrage du système :</p>
<pre lang="bash">root@haproxy-pts/0 [~]# echo 'haproxy_enable="YES"' >> /etc/rc.conf</pre>
<h2>Installation de stunnel :</h2>
<p>La version de stunnel étant tout aussi récente, on utilise le même mécanisme :</p>
<pre lang="bash">root@haproxy-pts/0 [~]# cd /usr/ports/security/stunnel
root@haproxy-pts/0 [/ports/security/stunnel]# make config &#038;&#038; make &#038;&#038; make clean</pre>
<p>On ajoute stunnel aux services à lancer au démarrage du système :</p>
<pre lang="bash">root@haproxy-pts/0 [~]# echo 'stunnel_enable="YES"' >> /etc/rc.conf</pre>
<h2>Configuration HAProxy</h2>
<p>Toute la configuration de HAProxy tient dans un seul fichier : /usr/local/etc/haproxy.conf. Ci dessous ma configuration avec les commentaires qui vont bien :</p>
<pre lang="bash">global
        #On log en local
        log 127.0.0.1 syslog
        #On gere 10000 connexions sec
        maxconn  10000
        #On chroot pour plus de secu
        chroot /usr/share/haproxy
        #On lance le bousin avec le user nobody
        uid 65534
        gid 65534

defaults
        #Niveau de log
        log     global
        #On forward les requetes RFC-Compliants
        mode    http
        #On log les requete http et les timers
        option  httplog
        #Onlog pas le vide...
        option  dontlognull
        #On redistribu les session en cas de fail d un node
        option  redispatch
        #On active les X-Forwarded-For
        option  forwardfor
        #Nombre de test avant de declarer un node mort
        retries 3
        #Assez explicit...
        contimeout      1000
        clitimeout      10000
        srvtimeout      10000]

#On cree une interface uniquement pour les stats sur le port 1000
listen admin_page :1000
        mode http
	stats enable
	stats hide-version
        stats realm HA\ Proxy\ Stats\
        stats auth raff:hehehyesfdsf
        stats uri /

listen  test :80
        bind    :80
        #URL a tester
        option  httpchk /
        contimeout      1000
        clitimeout      10000
        srvtimeout      10000
        retries 5
        maxconn 10000
        balance roundrobin
        cookie  SERVERID nocache rewrite
        server oaf-prj-web01 192.168.10.1:80 cookie
        server oaf-prj-web02 192.168.10.2:80 cookie
        #On capture les new visiteurs
        capture cookie vgnvisitor= len 32</pre>
<h2>Configuration stunnel</h2>
<p>Tout comme HAProxy, toute la configuration de stunnel tient en un fichier. On crée donc le fichier /usr/local/etc/stunnel/stunnel.conf :</p>
<pre lang="bash">;On configure le demon
setuid = stunnel
setgid = nogroup
pid = /tmp/stunnel.pid

;On met les certificats par defaut
cert = /usr/local/etc/stunnel/test.madeinsyria.fr.crt
key = /usr/local/etc/stunnel/test.madeinsyria.fr.key

;On renforce la stack SSL
options = NO_SSLv2
options = SINGLE_ECDH_USE
options = SINGLE_DH_USE

;On configure les logs
output = /var/log/stunnel.log

;On configure les services https
[https]
accept  = 443
connect = 80
TIMEOUTclose = 0</pre>
<p>Le services est donc joignable sur sont IP publique en HTTP et HTTPS. De plus l&#8217;outil de stats est joignable sur l&#8217;IP publique sur le port 1000 avec le login et mot de passe spécifiés plus haut.</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/10/summer-camp-etape-4-load-balancing-haproxy-et-stunnel/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Etape 3.2 – MySQLProxy : Split Read/Write</title>
		<link>http://madeinsyria.fr/2011/10/summer-camp-etape-3-2-mysqlproxy-split-readwrite/</link>
		<comments>http://madeinsyria.fr/2011/10/summer-camp-etape-3-2-mysqlproxy-split-readwrite/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 16:43:09 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[Mes Projets]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=809</guid>
		<description><![CDATA[Poursuivons le Summer Camp qui devient plus au Autumn Camp&#8230; Après la mise en réplication de nos bases de données, on va mettre en place le slipt Read/Write sur nos bases. La base maitre servira pour l&#8217;écriture de données et la base slave pour la lecture. Il est à noter que l&#8217;on peut ajouter autant [...]]]></description>
			<content:encoded><![CDATA[<p>Poursuivons le Summer Camp qui devient plus au Autumn Camp&#8230; Après la mise en réplication de nos bases de données, on va mettre en place le slipt Read/Write sur nos bases. La base maitre servira pour l&#8217;écriture de données et la base slave pour la lecture. Il est à noter que l&#8217;on peut ajouter autant e slave que l&#8217;on veut. Il suffit de rajouter quelque ligne à la configuration de MySQLProxy. On attaque donc la dernière brique MySQL de la série !</p>
<p><span id="more-809"></span></p>
<h2>Prérequis :</h2>
<p>Nous allons donc utiliser dans ce tuto une machine sous Debian 6 :</p>
<ul>
<li>1 vCPU</li>
<li>512Mo de RAM</li>
<li>Un disque de 8Go pour le système</li>
<li>2 cartes réseau : une sur le VLAN Backend et l&#8217;autre sur le VLAN LB-Back</li>
</ul>
<h2>Installation de MySQLProxy et configuration système :</h2>
<p>Nous sommes sous Debian et nous avons la chance d&#8217;avoir une version de MySQLProxy relativement à jour (à une mineure près&#8230;) dans les dépôts. Nous allons donc profiter du système de package ! Pour cela :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# aptitude install mysql-proxy</pre>
<p>Et voilà&#8230; C&#8217;est tout. Avant de continuer, on va mettre à jour le fichier host du serveur :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# echo "192.168.20.10         OAF-PRJ-SQL01" >> /etc/hosts
root@OAF-PRJ-MYSQLPROXY:~# echo "192.168.20.11         OAF-PRJ-SQL01" >> /etc/hosts</pre>
<p>On passe maintenant à la configuration de MySQLProxy.</p>
<h2>Configuration de MySQLProxy :</h2>
<p>MySQLProxy utilise des script pour définir sont mode de fonctionnement. Nous allons utiliser un des scripts fourni pour effectuer le split read/write et tout simplement créer un script de lancement.</p>
<p>Le script de lancement sera positionné dans /etc/mysql-proxy/. Pour le reste, ça fonctionne tout seul ! Voilà donc le mode opératoire :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# mkdir /etc/mysql-proxy/
root@OAF-PRJ-MYSQLPROXY:~# cd /etc/mysql-proxy/
root@OAF-PRJ-MYSQLPROXY:/etc/mysql-proxy# ls
root@OAF-PRJ-MYSQLPROXY:/etc/mysql-proxy# vim rw_launcher.sh

#!/bin/bash
#On déclare le master, le slave et le path vers le binaire
MASTERDB=192.168.20.10
SLAVEDB01=192.168.20.11
ROOT_DIR=/usr/share

#On déclare le path vers les scripts de configuration
LUA_PATH="$ROOT_DIR/mysql-proxy/?.lua" 

#On défini la commande de lancement
/usr/bin/mysql-proxy \
 --daemon \
 --proxy-backend-addresses=$MASTERDB:3306 \
 --proxy-read-only-backend-addresses=$SLAVEDB01:3306 \
 --proxy-lua-script=$ROOT_DIR/mysql-proxy/rw-splitting.lua</pre>
<p>Et voilà ! Maintenant, on prépare un petit script de lancement automatique que l&#8217;on pose dans /etc/init.d. En fait, on va remplacer le script existant qui pu un peu :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# cd /etc/init.d/
root@OAF-PRJ-MYSQLPROXY:/etc/init.d# rm mysql-proxy
root@OAF-PRJ-MYSQLPROXY:/etc/init.d# vim mysql-proxy

### BEGIN INIT INFO
# Provides: mysql-proxy
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Lance MySQLProxy
# Description: La meme...
### END INIT INFO

start(){
    echo "Demarrage..."
    /etc/mysql-proxy/rw_launcher.sh
}

stop(){
    echo "Arret..."
    killall mysql-proxy
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: mysql-proxy {start|stop|restart}"
exit 1
esac</pre>
<p>On l&#8217;ajoute aux scripts de lancement automatique au moment du boot (normalement c&#8217;est déjà le cas) :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# insserv mysql-proxy</pre>
<p>Et voilà ! Maintenant, il suffit de faire pointer vos applications vers l&#8217;IP de cette machine sur le port 4040 (celui de MySQLProxy). Pour vérifier que le service tourne bien, il suffit de voir si cette commande retourne bien une ligne :</p>
<pre lang="bash">root@OAF-PRJ-MYSQLPROXY:~# netstat -tape | grep "4040"
tcp        0      0 *:4040                  *:*                     LISTEN      root       3919        1043/mysql-proxy</pre>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/10/summer-camp-etape-3-2-mysqlproxy-split-readwrite/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Etape 3.1 – MySQL Réplication</title>
		<link>http://madeinsyria.fr/2011/10/summer-camp-etape-3-1-mysql-replication/</link>
		<comments>http://madeinsyria.fr/2011/10/summer-camp-etape-3-1-mysql-replication/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 14:44:57 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SysAdmin]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=782</guid>
		<description><![CDATA[C&#8217;est plus trop l&#8217;été mais bon&#8230; On va le faire perdurer ici ! On a donc les frontaux&#8230; sur lesquels on a monté les partages de fichiers statiques. Mon PHP est bien fonctionnel&#8230; mais j&#8217;ai pas encore de bases pour stocker ma donnée. Contrairement à ce que j&#8217;ai annoncé, nous n&#8217;allons pas utiliser un MySQL [...]]]></description>
			<content:encoded><![CDATA[<p>C&#8217;est plus trop l&#8217;été mais bon&#8230; On va le faire perdurer ici ! On a donc les frontaux&#8230; sur lesquels on a monté les partages de fichiers statiques. Mon PHP est bien fonctionnel&#8230; mais j&#8217;ai pas encore de bases pour stocker ma donnée.</p>
<p>Contrairement à ce que j&#8217;ai annoncé, nous n&#8217;allons pas utiliser un MySQL Cluster. Ce choix est justifié par la spécificité de MySQL Cluster qui demande un développement spécifique. En effet, le moteur de base est différent et n&#8217;est que très rarement supporté par des CMS ou même des développement spécifique. à la place, je vous propose de faire un Split Read/Write via MySQL Proxy. Il s&#8217;agit donc de répartir la lecture sur plusieurs bases (répliqués entre elles) mais de faire les insertions que sur une seule. Typiquement on écrit sur un serveur et on lit sur l&#8217;autre.</p>
<p>On attaque donc cette partie qui nous amènera un peu plus près de la fin du projet. Aujourd&#8217;hui on va faire de la réplication MySQL.</p>
<p><span id="more-782"></span></p>
<h2>Prérequis</h2>
<p>Nous allons donc utiliser dans ce tuto 2 machines sous Debian 6 :</p>
<ul>
<li>4vCPU</li>
<li>1024Mo de RAM</li>
<li>Un disque (j’utilise des VMDK) 8Go pour le système</li>
<li>1 carte réseau sur le VLAN Backend</li>
<li>Prévoir un disque supplémentaire de XGo en fonction du besoin</li>
</ul>
<h1>Installation des serveurs MySQL :</h1>
<p>On attaque donc avec le premier serveur MySQL SQL01 (le maitre). Vous allez voir c&#8217;est très simple, on fait l&#8217;installation via le gestionnaire de paquets dont on met à jour la liste des paquets au préalable :</p>
<pre lang="bash">root@OAF-PRJ-SQL01:~# aptitude update
root@OAF-PRJ-SQL01:~# install mysql-server</pre>
<p>Durant l&#8217;installation, je gestionnaire demande le mot de passe root de la base de données.</p>
<p>On réitère la même chose sur le SQL02 (l&#8217;esclave).</p>
<p>On sécurise un minimum le tout avant de poursuivre grâce à la commande suivante dont on répondra au question :</p>
<pre lang="bash">root@OAF-PRJ-SQL01:~# mysql_secure_installation</pre>
<p>On a donc notre base de travail.</p>
<h1>Mise en réplication des bases :</h1>
<p>Avant de mettre en place la réplication nous allons insérer une base factice qui nous servira pour les tests. Pour cela, sur le server SQL01, nous allons importer la base de test MySQL Sakila (<a href="http://dev.mysql.com/doc/sakila/en/sakila.html">http://dev.mysql.com/doc/sakila/en/sakila.html</a>). Il s&#8217;agit d&#8217;une base fournies à des fins de test proposée par MySQL. Allons y, nous importons donc d&#8217;abord la structure, puis la donnée :</p>
<pre lang="bash">root@OAF-PRJ-SQL01:~# wget "http://downloads.mysql.com/docs/sakila-db.tar.gz"
root@OAF-PRJ-SQL01:~# tar xzf sakila-db.tar.gz
root@OAF-PRJ-SQL01:~# cd sakila-db/
root@OAF-PRJ-SQL01:~/sakila-db# mysql -p &lt; sakila-schema.sql
root@OAF-PRJ-SQL01:~/sakila-db# mysql -p &lt; sakila-data.sql</pre>
<p>Nous pouvons donc maintenant mettre en place la réplication avec un support de test. Le mécanisme est simple : nous allons activer quelques options nécessaire au bon fonctionnement sur le master et le slave. Puis nous créerons un compte dédié à la réplication avec des droits spécifique. Pour finir, nous mettrons en place la réplication sur le slave.</p>
<p>Préparons donc la réplication en définissant un ID unique pour chaque serveur et en activant les log binaires sur la master. Ces log permettrons de transmettre les requêtes. Il faut éditer /etc/mysql/my.cnf et modifier les directives suivante dans la rubrique [mysqld] sur SQL01 :</p>
<pre lang="bash">root@OAF-PRJ-SQL01:~# vim /etc/mysql/my.cnf 

[mysqld]
.
.
.
bind-address            = 0.0.0.0
.
.
.
server_id               = 1
log-bin
binlog-format           = mixed
.
.
.</pre>
<p>Puis sur SQL02 :</p>
<pre lang="bash">root@OAF-PRJ-SQL01:~# vim /etc/mysql/my.cnf 

[mysqld]
.
.
.
bind-address            = 0.0.0.0
.
.
.
server_id               = 2</pre>
<p>Ne pas oublier de restarter le service MySQL sur SQL01 et SQL02.</p>
<p>Il faut maintenant créer le compte de réplication sur le master :</p>
<pre lang="sql">mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepasswordofroxxor';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'slavepasswordofroxxor';
Query OK, 0 rows affected (0.00 sec)</pre>
<p>Avant de finir, on execute un dump un peu spécial qui aura pour but de synchroniser les deux bases au niveau de la lecture des logs binaire (ceux qui permettent de rejouer les requêtes), puis on l&#8217;envoie sur le slave.</p>
<pre lang="bash">root@OAF-PRJ-SQL02:~# mysqldump -p --master-data sakila > dump.sql
root@OAF-PRJ-SQL02:~# scp dump.sql OAF-PRJ-SQL02:/root</pre>
<p>Le compte est donc crée et le dump pret à importer. L&#8217;étape suivante est donc la configuration de la réplication sur le slave. Pour cela on commence à ajouter le hostname du slave dans le fichier host :</p>
<pre lang="bash">root@OAF-PRJ-SQL02:~# echo "192.168.20.11      OAF-SRV-SQL02" >> /etc/hosts</pre>
<p>Puis on importe le dump du master :</p>
<pre lang="bash">root@OAF-PRJ-SQL02:~# mysql -p &lt; dump.sql</pre>
<p>Puis on configure le slave sur la base MySQL et on le lance ! :</p>
<pre lang="sql">mysql> CHANGE MASTER TO
    -> MASTER_HOST='OAF-SRV-SQL02',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='slavepasswordofroxxor',
    -> MASTER_PORT=3306,
    -> MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.02 sec)
mysql> slave start;</pre>
<p>pour finir on test le bon fonctionnement de la réplication. Pour cela, on vérifie que la commande qui suit retourne bien &#8220;Yes&#8221; pour les variable Slave_IO_Running et Slave_SQL_Running :</p>
<pre lang="sql">mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: OAF-PRJ-SQL01
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysqld-bin.000018
          Read_Master_Log_Pos: 247
               Relay_Log_File: mysqld-relay-bin.000033
                Relay_Log_Pos: 393
        Relay_Master_Log_File: mysqld-bin.000018
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 247
              Relay_Log_Space: 593
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
1 row in set (0.00 sec)</pre>
<p>Et voilà ! Parfait ! La prochaine étape, c&#8217;est le MySQL proxy, dans le prochain billet <img src='http://madeinsyria.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/10/summer-camp-etape-3-1-mysql-replication/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Etape 2 – Serveur de Fichiers NFS + ZFS</title>
		<link>http://madeinsyria.fr/2011/08/summer-camp-etape-2-serveur-de-fichiers-nfs-zfs/</link>
		<comments>http://madeinsyria.fr/2011/08/summer-camp-etape-2-serveur-de-fichiers-nfs-zfs/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 00:56:43 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[NFS]]></category>
		<category><![CDATA[NGINX]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=738</guid>
		<description><![CDATA[Dans le post précédent du Summer Camp, nous avons vu comment monter les frontaux web. Aujourd&#8217;hui, nous allons voir comment mettre en place le serveur de fichier. Mais avant de commencer, pourquoi mettons nous en place des serveurs de fichiers ? Pourquoi le frontal ne porte-t-il pas la donnée directement. La réponse est simple : un [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le <a title="[Summer Camp] Étape 1 – Frontaux Web (Nginx + PHP5)" href="http://madeinsyria.fr/2011/08/summer-camp-etape-1-frontaux-web-nginx-php5/">post précédent</a> du <a title="[Summer Camp] Infra Web Haute Disponibilité" href="http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/">Summer Camp</a>, nous avons vu comment monter les frontaux web. Aujourd&#8217;hui, nous allons voir comment mettre en place le serveur de fichier. Mais avant de commencer, pourquoi mettons nous en place des serveurs de fichiers ? Pourquoi le frontal ne porte-t-il pas la donnée directement. </p>
<p>La réponse est simple : un frontal est une machine &#8220;jetable&#8221;. Elle a pour but d&#8217;être déployée rapidement et simplement. Si un frontal porte 250Go de données, il sera lent à répliquer et gourmand en espace disque. Sans compter les problèmes de réplications de données entre les frontaux. Pour répondre à tout cela, nous allons mettre en place un serveur de fichier avec un partage réseau NFS qui sera monté sur les frontaux. Le système de fichier utilisé sera ZFS sous FreeBSD. En effet il offre des possibilités de réplication et de sauvegarde très interessantes, mais là n&#8217;est pas l&#8217;objet du billet, nous y reviendrons.<br />
<span id="more-738"></span></p>
<h2>Prérequis :</h2>
<ul>
<li>4vCPU</li>
<li>1024Mo de RAM</li>
<li>Un disque (j&#8217;utilise des VMDK) 8Go pour le système</li>
<li>Un disque de XGo pour la data (en fonction du besoin&#8230;)</li>
<li>1 carte réseau sur le VLAN Backend</li>
</ul>
<p>L’OS qui portera ce beau monde est : FreeBSD 8.2 x64. Le ZFS y est natif, le NFS supporté et al robustesse du système n&#8217;est plus à prouver : que du bonheur. Dans une version optimisée à venire de la plateforme, je ferai la même chose, mais sous Solaris.</p>
<h2>Partitionment ZFS :</h2>
<p>Nous allons donc crée notre partiton ZFS qui utilisera l&#8217;ensemble de notre disque DATA. Pour cela, après avoir identifié dans /dev/ le nom de mon disque (ici da1) :</p>
<pre lang="bash">root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# zpool create data /dev/da1
root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# zpool list
NAME   SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
data  49.8G  76.5K  49.7G     0%  ONLINE  -
root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# ls -l /
total 50
-rw-r--r--   2 root  wheel      798 Feb 17 03:19 .cshrc
-rw-r--r--   2 root  wheel      265 Feb 17 03:19 .profile
drwxrwxr-x   2 root  operator   512 Aug 18 04:18 .snap
-r--r--r--   1 root  wheel     6200 Feb 17 03:19 COPYRIGHT
drwxr-xr-x   2 root  wheel     1024 Feb 17 03:18 bin
drwxr-xr-x   7 root  wheel     1024 Aug 18 04:23 boot
drwxr-xr-x   2 root  wheel      512 Aug 18 04:18 cdrom
lrwxr-xr-x   1 root  wheel       10 Aug 18 04:23 compat -> usr/compat
drwxr-xr-x   2 root  wheel        2 Aug 18 02:31 data
dr-xr-xr-x   6 root  wheel      512 Aug 18 04:25 dev
drwxr-xr-x  20 root  wheel     2048 Aug 18 02:26 etc
drwxr-xr-x   3 root  wheel     1536 Feb 17 03:19 lib
drwxr-xr-x   2 root  wheel      512 Feb 17 03:18 libexec
drwxr-xr-x   2 root  wheel      512 Feb 17 03:18 media
drwxr-xr-x   2 root  wheel      512 Feb 17 03:18 mnt
dr-xr-xr-x   2 root  wheel      512 Feb 17 03:18 proc
drwxr-xr-x   2 root  wheel     2560 Feb 17 03:19 rescue
drwxr-xr-x   2 root  wheel      512 Aug 18 02:29 root
drwxr-xr-x   2 root  wheel     2560 Feb 17 03:19 sbin
lrwxr-xr-x   1 root  wheel       11 Feb 17 03:19 sys -> usr/src/sys
drwxrwxrwt   7 root  wheel      512 Aug 18 02:29 tmp
drwxr-xr-x  16 root  wheel      512 Aug 18 04:23 usr
drwxr-xr-x  23 root  wheel      512 Aug 18 04:26 var</pre>
<p>Nous avons donc un système de fichier ZFS d&#8217;environ 50Go de crée (on le vois via la commande zpool list), nommé data, et monté à la racine (un simple ls -l /). Pour finir, on active le ZFS au démarrage de la machine :</p>
<pre lang="bash">root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# echo 'zfs_enable="YES"' >> /etc/rc.conf</pre>
<p>Et voilà, pas besoin de plus ! Et si on partageait tout ça ?</p>
<h2>Partage NFS :</h2>
<p>NFS est un partage réseau qui est natif aux kernels de la quasi totalité des Unix. Il est basé sur le protocole RPC. Il est donc très avantageux de le privilégier pour partager ma partition ZFS. En effet, si je décide de changer de type d&#8217;Unix au niveau de mon frontal, je suis quasi sur de ne pas perdre la compatibilité. Une autre possibilité de ZFS dont je ne vous ai pas parlé, c&#8217;est le partage en NFS d&#8217;un pool de données. Pas mal non ?! C&#8217;est très simple :</p>
<pre lang="bash">root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# zfs set sharenfs="-maproot=root -alldirs -network 192.168.1.0 -mask 255.255.255.0" data</pre>
<p>On remarque que le paramètre sharenfs prend en option les options NFS. Dans mon cas l&#8217;autorise le montage à partir de tous les sous répertoires de la partition ZFS pour toutes les machines du réseau 192.168.1.0/24. L&#8217;option maproot permet à l&#8217;utilisateur root distant d&#8217;avoir les droits d&#8217;écriture en root sur la partition partagée.</p>
<p>On peut verifier l&#8217;option via :</p>
<pre lang="bash">root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# zfs get sharenfs data</pre>
<p>Bien sur, les partage ZFS s&#8217;appuie sur le NFS, il faut donc ajouter les services  lockd et statd de NFS en démarrage automatique. Ses services permettent le lock des fichiers et la gestion du monitoring réseau pour RPC. On édite donc le fichier /etc/rc.conf :</p>
<pre lang="bash">
root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# rpc_statd_enable="YES" >> /etc/rc.conf
root@oaf-prj-static.madeinsyria.fr-pts/0 [~]# rpc_lockd_enable="YES" >> /etc/rc.conf</pre>
<p>Un petit reboot du server permet de verifier que tout est bien fonctionnel.</p>
<h2>Montage des partages :</h2>
<p>Sur les machines clients on monte les partages tous fraichement crées en utilisant la commande mount. Un rapide df -h permet de verifier que le filesystem est bien monté:</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# mount -t nfs 192.168.20.100:/data /data
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# df -h
Filesystem              Size    Used   Avail Capacity  Mounted on
/dev/da0s1a             989M    291M    619M    32%    /
devfs                   1.0K    1.0K      0B   100%    /dev
/dev/da0s1e             989M     14K    910M     0%    /tmp
/dev/da0s1f              11G    1.1G    8.7G    12%    /usr
/dev/da0s1d             4.8G    5.3M    4.4G     0%    /var
192.168.20.100:/data     49G     22K     49G     0%    /data</pre>
<p>Pour que le montage se fasse automatiquement au démarrage de la machine, il faut éditer le fichier /etc/fstab et y ajouter la ligne ci dessous :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo "192.168.100.20:/data   /data    nfs rw  0   0" >> /etc/fstab</pre>
<p>On adapte Nginx en modifiant la valeur de la variable &#8220;root&#8221; et &#8220;fastcgi_param&#8221;. On obtiens donc :</p>
<pre lang="bash">server {
        listen       80;
        server_name  test.madeinsyria.fr;

        access_log  /var/log/test.madeinsyria.fr.access.log  main;
        location / {
            root   /data;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /data;
        }
        #GESTION DU PHP
        location ~ \.php$ {
       try_files  $uri  /path/to/404.htm;
                #Dossier racine
            root           html;
            #On revoie vers la socket
            fastcgi_param SCRIPT_FILENAME /data/$fastcgi_script_name;
            fastcgi_pass   unix:/tmp/fcgi.socket;
            fastcgi_index  index.php;
            include        fastcgi_params;
        }
    }
</pre>
<p>On relance bien sur les service Nginx et hop c&#8217;est dans la boite ! Nos frontaux s&#8217;appuient sur une partition ZFS distante montée en NFS ! La haute dispo est en marche !!!</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/08/summer-camp-etape-2-serveur-de-fichiers-nfs-zfs/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>#OpSyria – Vu que ça devient public…</title>
		<link>http://madeinsyria.fr/2011/08/opsyria-vu-que-ca-devient-public/</link>
		<comments>http://madeinsyria.fr/2011/08/opsyria-vu-que-ca-devient-public/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 11:00:07 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Edito]]></category>
		<category><![CDATA[Causes]]></category>
		<category><![CDATA[Libertés]]></category>
		<category><![CDATA[Securité]]></category>
		<category><![CDATA[Syria]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=720</guid>
		<description><![CDATA[J&#8217;en ai déjà parlé à plusieurs reprises (ici, ici, et là), mais je ne faisant qu&#8217;en parler. Maintenant que mes amis de Reflets en parle, je vais devenir un peu plus&#8230; verbeux (pardonnez moi l&#8217;expression&#8230;). Depuis le 15 mars, des gens meurs dans les rues Syriennes, et une resistance s&#8217;organise. Parmi cette resistance, une cyber resistance. [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;en ai déjà parlé à plusieurs reprises (<a href="http://madeinsyria.fr/2011/05/syrie-chez-moi-vu-de-lexterieur/">ici</a>, <a href="http://madeinsyria.fr/2011/05/revolution-syrienne-dans-une-lignee-de-soulevements-arabes/">ici</a>, et <a href="http://madeinsyria.fr/2011/05/revolution-syrienne-une-diaspora-qui-prend-position/">là</a>), mais je ne faisant qu&#8217;en parler. Maintenant que mes amis de <a href="http://reflets.info">Reflets</a> en parle, je vais devenir un peu plus&#8230; verbeux (pardonnez moi l&#8217;expression&#8230;).</p>
<p>Depuis le 15 mars, des gens meurs dans les rues Syriennes, et une resistance s&#8217;organise. Parmi cette resistance, une cyber resistance. En effet, la dictature en place à Damas est la première au monde à avoir une cyber armée, avec ses objectifs, ces cibles. Mais qu&#8217;à cela ne tienne&#8230; en face il y a une resistance électronique.</p>
<p>On peut citer les plus connues comme Anonymous ou Telecomix. Sous ces noms, se cache en réalité d&#8217;autres groupes, plus fins, plus organisés, plus influents, plus puissants. Ces groupes ont monté #OpSyria. L&#8217;objectif est simple : anéantir la présence de la dictature sur le net, mais aussi redonner la liberté numérique aux Syriens.</p>
<p>Aujourd&#8217;hui, je revendique publiquement (oui, c&#8217;est contraire à l&#8217;éthique du groupe) mon appartenance à #OpSyria. J&#8217;y ai organisé et executé un certain nombre d&#8217;actions, du simple DoS, à l&#8217;action plus poussée sur les Internet Ground Services de la Syrie en passant par des actions ultra médiatisés.</p>
<p>Mes actions m&#8217;ont en particulier permis de documenter une partie du backbone Syrien ainsi de que l&#8217;architecture du réseau Internet. Je ne possède à l&#8217;heure actuelle plus aucune des données critiques sur moi, je ne suis pas assez fou pour ça. Tout est en sécurité sur des systèmes sur lesquels je n&#8217;ai aucunement la main.</p>
<p>Si je commence à parler en publique c&#8217;est parce que d&#8217;une part mon rôle dans cette resistance n&#8217;est plus mon rôle initial : je vais plus travailler sur la documentation et l&#8217;aide aux citoyens censurés. D&#8217;autre part, j&#8217;avoue ne plus me sentir entièrement en sécurité ou entièrement caché. Je préfère publier ce billet haut et fort plutôt que me retrouver dans une situation inconfortable sans avoir pu parler.</p>
<p>Grace aux aides fournis par Reflets (et donc Telecomix), sachez que de grande actions se prépare et à des dates symboliques.</p>
<p>Je suis ouvert à toute question soit via les commentaires, soit via le formulaire de contact.</p>
<p>Nous sommes Légion, Nous ne pardonnons pas, Nous n&#8217;oublions pas, attendez-vous à nous.<em></em></p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/08/opsyria-vu-que-ca-devient-public/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>#OpSyria – Let it be public…</title>
		<link>http://madeinsyria.fr/2011/08/opsyria-let-it-be-public/</link>
		<comments>http://madeinsyria.fr/2011/08/opsyria-let-it-be-public/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 10:59:13 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Edito]]></category>
		<category><![CDATA[Causes]]></category>
		<category><![CDATA[Libertés]]></category>
		<category><![CDATA[Securité]]></category>
		<category><![CDATA[Syria]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=727</guid>
		<description><![CDATA[I already talked about the Syrian Revolution sevral times (here, here and also here - french only sorry), but it was just a some posts. Now that my friends at Reflets are talking about it and giving information about the Syrian censorship, I feel like it&#8217;s my duty to also go public. Since Mach 15th, people in Syria have [...]]]></description>
			<content:encoded><![CDATA[<p>I already talked about the Syrian Revolution sevral times (<a title="Révolution Syrienne : chez moi vu de l’extérieur" href="http://madeinsyria.fr/2011/05/syrie-chez-moi-vu-de-lexterieur/">here</a>, <a title="Révolution Syrienne : dans une lignée de soulèvements Arabes ?" href="http://madeinsyria.fr/2011/05/revolution-syrienne-dans-une-lignee-de-soulevements-arabes/">here</a> and also <a title="Révolution Syrienne : une diaspora qui prend position" href="http://madeinsyria.fr/2011/05/revolution-syrienne-une-diaspora-qui-prend-position/">here</a> - french only sorry), but it was just a some posts. Now that my friends at <a href="http://reflets.info">Reflets</a> are talking about it and giving information about the Syrian censorship, I feel like it&#8217;s my duty to also go public.</p>
<p>Since Mach 15th, people in Syria have been dying, but a resistance is also growing. The resistance I want to talk about, is of course, the electronic one. What you should know is that the Syrian dictatorship is the first one to have a Cyber Army with objectives, targets, and to be honest, results. Of course, armies fight one another.</p>
<p>The most famous enemies of the Syrian cyber army, are Anonymous and Telecomix. Actually, smaller groups are hidding behind those names. They are more organized, more powerful and more influential : they are the ones who created #OpSyria. They have a very simple goal : destroy the Syrian dictatorship presence online and bring electronic liberty to Syria.</p>
<p>Today, I would like to make public (which is the opposite of the group&#8217;s ethic) the fact that I&#8217;m part of #OpSyria. I&#8217;ve organized and/or executed several actions from the highly covered DoS&#8217;s to the heavy actions on the Syrian Internet Ground Services.</p>
<p>My actions made me able to dress a good card of the Syrian internet backbone and to gain good access to a part of it. I currently don&#8217;t have any information on any of my electronic/paper devices. I&#8217;m not that stupid : everything is in a safe place on systems I don&#8217;t have access to.</p>
<p>I am going public today because firstly my role in this war is not same anymore : I will work on helping people to protect themselves and on covering their actions. Secondly, I don&#8217;t feel safe and anonymous like I used to. I prefer to make everything public before I can&#8217;t do it anymore.</p>
<p>Expect some heavy actions in the next days/week. The war has just begun and is almost finished.</p>
<p>I&#8217;m open to any questions/comments. You can use the comments or the contact form.</p>
<p>We are Legion. We do not forget. We do not forgive. Expect Us.</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/08/opsyria-let-it-be-public/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Étape 1 – Frontaux Web (Nginx + PHP5)</title>
		<link>http://madeinsyria.fr/2011/08/summer-camp-etape-1-frontaux-web-nginx-php5/</link>
		<comments>http://madeinsyria.fr/2011/08/summer-camp-etape-1-frontaux-web-nginx-php5/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 13:23:24 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[Mes Projets]]></category>
		<category><![CDATA[NGINX]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SysAdmin]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=683</guid>
		<description><![CDATA[C&#8217;est partie ! On commence le summer camp de façon technique avec la mise en place de la première brique de notre Infra Web Haute Dispo (http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/), les frontaux Web. Ils porteront principalement : Nginx et PHP5. Pour rappel, j&#8217;ai choisis Nginx pour sa capacité à tenir, avec les même resources, une charge en moyenne [...]]]></description>
			<content:encoded><![CDATA[<p>C&#8217;est partie ! On commence le summer camp de façon technique avec la mise en place de la première brique de notre Infra Web Haute Dispo (<a href="http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/">http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/</a>), les frontaux Web. Ils porteront principalement : Nginx et PHP5.</p>
<p>Pour rappel, j&#8217;ai choisis Nginx pour sa capacité à tenir, avec les même resources, une charge en moyenne dix fois superieur à celle d&#8217;un Apache2. De plus, il s&#8217;agit d&#8217;un serveur web qui gagne énormément en popularité, maitriser sa mise en place ne peut être qu&#8217;un plus !</p>
<p><span id="more-683"></span></p>
<h2>Prérequis :</h2>
<p>La configuration hardware des VM utilisées est la suivante :</p>
<ul>
<li>4vCPU</li>
<li>1024Mo de RAM</li>
<li>20Go de disque</li>
<li>2 Cartes réseau sur les 2 Vlan (LB-FRONT et LB-BACK)</li>
</ul>
<p>L&#8217;OS qui portera ce beau monde est : FreeBSD 8.2 x64. J&#8217;aime la robustesse et la stabilité de cet OS qui n&#8217;est en rien comparable à celle d&#8217;un Linux (oui, il y a un peu de troll dans l&#8217;histoire&#8230;).</p>
<h2> Installation de nginx</h2>
<p>La version fournie par les package étant trop ancienne (0.8.53 vs 1.0.5 pour la version stable  actuelle), nous allons procéder à une installation via les sources.</p>
<p>Tout d&#8217;abord, installons les dépendances (la librairie pcre) :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports]# pkg_add -r pcre</pre>
<p>Puis il faut récupérer la tarball nginx depuis le site. Pour cela on install &#8220;wget&#8221; puis on l&#8217;utilise pour récupérer la tarball :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# pkg_add -r wget
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# wget http://nginx.org/download/nginx-1.0.5.tar.gz</pre>
<p>Il faut ensuite procéder à la décompression de la tarball et sa compilation. On ne peut plus classique :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# tar xzvf nginx-1.0.5.tar.gz
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd nginx-1.0.5/
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# ./configure \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --sbin-path=/usr/local/nginx/nginx \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --conf-path=/usr/local/etc/nginx/nginx.conf \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --pid-path=/var/run/nginx/nginx.pid \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --http-log-path=/var/log/nginx/access.log \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --with-http_ssl_module
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# make
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# make install</pre>
<p>On se retrouve donc avec nginx installé dans /usr/local/nginx et le fichier de configuration dans /usr/local/etc/nginx/. Les logs seront placé dans /var/log/nginx.</p>
<p>On crée le script d&#8217;init pour finir, puis on le rend executable (le script est pompé du wiki Nginx) :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# vim /usr/local/etc/rc.d/nginx
##### Copié / Collé / Save / Exit #####
#!/bin/sh

NGINX_BASE_DIR="/usr/local/nginx/"
NGINX_DAEMON="${NGINX_BASE_DIR}/sbin/nginx"
NGINX_CONF="/usr/local/etc/nginx/nginx.conf"

__launch_signal( ) {

  ${NGINX_DAEMON} -s ${1} &amp;&gt;/dev/null
}

__checkconfig( ) {

  ${NGINX_DAEMON} -c ${NGINX_CONF} -t &amp;&gt;/dev/null
}

__start( ) {

  [ -r ${NGINX_CONF} ] || exit 1 

  __checkconfig &amp;&amp; ${NGINX_DAEMON} -c ${NGINX_CONF} &amp;&gt;/dev/null || return ${?}
}

__stop( ) {

  __launch_signal stop
}

__reload( ) {

  __checkconfig &amp;&amp; __launch_signar reload || return ${?}
}

__restart( ) {

  __stop &amp;&amp; __start
}

__show_usage( ) {

  echo "Usage: ${0} {start|stop|restart|reload}"
  exit 3
}

##
# :: main ::
case "${1}" in
  start|stop|restart|reload)
    [ -x ${NGINX_DAEMON} ] || exit 2
    __${1}
    ;;
  *)
    __show_usage
    ;;
esac

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# chmod +x /usr/local/etc/rc.d/nginx</pre>
<p>&nbsp;</p>
<h2>Installation de PHP5</h2>
<p>On install maintenant PHP5 avec le support CGI, pour cela :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd /usr/ports/lang/php52
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52]# make config <span style="color: #ff0000;">#### Cocher FastCGI ####</span>
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52]# make install &amp;&amp; make clean</pre>
<p>Puis on install les extensions PHP généralement utilisés :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd /usr/ports/lang/php52-extensions
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52-extensions]# make config <span style="color: #ff0000;">#### Cocher mcrypt, GD, toutes les PDO, MySQL, zlib ####</span>
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52-extensions]# make install &amp;&amp; make clean</pre>
<h2>Intégration Nginx/PHP5</h2>
<p>Contrairement à Apache ou Lighttpd, Nginx ne sait pas faire appel de lui même (spawn) à FastCGI pour le traitement des requêtes PHP. Pour cela, il y a plusieurs façon de faire. Celle que je vais utiliser est baser sur la brique de Lighttpd : spawn-fcgi. (Option 2 : utiliser php-fpm).  Pour faire simple : l&#8217;utilisateur appel une page via Nginx (1). Nginx crée un proccess FastCGI via spawn-fcgi (php-fpm) (2), puis lui soumet la requête (3). La page executée (4) est alors renvoyé à l&#8217;utilisateur via Nginx (5).</p>
<p><a href="http://madeinsyria.fr/wp-content/uploads/2011/08/fastcgi.png"><img class="aligncenter size-medium wp-image-704" title="fastcgi" src="http://madeinsyria.fr/wp-content/uploads/2011/08/fastcgi-300x107.png" alt="" width="300" height="107" /></a></p>
<p>&nbsp;</p>
<h3>Option 1 (spawn-cgi) :</h3>
<p>On commence donc par télécharger et installer spawn-fcgi (la dernière version est dispo ici : http://redmine.lighttpd.net/projects/spawn-fcgi/news) :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# wget "http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.bz2"
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# tar xzvf spawn-fcgi-1.6.3.tar.bz2
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd spawn-fcgi-1.6.3/
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# ./configure
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# make
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# make install</pre>
<p>On a donc un spawn-fcgi installé dans /usr/local/bin/.</p>
<p>Puis on crée notre script d&#8217;init et on le rend executable (bon il est pompé du wiki Nginx http://wiki.nginx.org ) :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# vim /usr/local/etc/rc.d/php-cgi
##### On colle le script suivant, on save and quit #####
#!/bin/sh
# Modified spawn-fcgi for rc.d (original: vivek@nixcraft.com)
NAME=php-cgi
SPAWNFCGI=/usr/local/bin/spawn-fcgi
FCGI_CHILDREN=3
PROCESS_NAME=lua
SERVER_SOCKET=/tmp/fcgi.socket
SERVER_PID=/tmp/fcgi.pid
SERVER_USER=www
SERVER_GROUP=www
FCGI_PROCESS=/usr/local/bin/php-cgi
SOCKSTAT=/usr/bin/sockstat
GREP=/usr/bin/grep
KILLALL=/usr/bin/killall
cmd=$1
fcgi_restart()
{
        fcgi_stop
        fcgi_start
}
fcgi_start()
{
        $SPAWNFCGI -s $SERVER_SOCKET -P $SERVER_PID -u $SERVER_USER -g $SERVER_GROUP -F $FCGI_CHILDREN -f $FCGI_PROCESS
}
fcgi_stop()
{
        $KILLALL $PROCESS_NAME
}
fcgi_status()
{
        $SOCKSTAT -u | $GREP -i $SERVER_SOCKET &gt; /dev/null
        [ $? -eq 0  ] &amp;&amp; echo "$PROCESS_NAME is running" || echo "$PROCESS_NAME is not running!"
}
fcgi_help()
{
        echo "Usage: $0 {(re)start|status|stop}"
}
case ${cmd} in
[Rr][Ee][Ss][Tt][Aa][Rr][Tt]) fcgi_restart;;
[Ss][Tt][Aa][Rr][Tt]) fcgi_start;;
[Ss][Tt][Oo][Pp]) fcgi_stop;;
[Ss][Tt][Aa][Tt][Uu][Ss]) fcgi_status;;
*) fcgi_help;;
esac
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# chmod +x /usr/local/etc/rc.d/php-cgi</pre>
<h3>Option 2 ( php-fpm ) :</h3>
<p>C&#8217;est un paquet déjà installé avec php (si vous avez bien suivi les instructions&#8230;). Bah oui, facil. Il ne reste plus qu&#8217;à ajouter php-fpm en démarrage automatique via :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'php_fpm_enable="YES"' &gt;&gt; /etc/rc.conf</pre>
<p>On peut alors démarrer FastCGI de la façon la plus classique avec le script d&#8217;init.</p>
<p>Pour finir, il ne reste plus qu&#8217;à ajuster la configuration de Nginx et tester !</p>
<h2>Finalisation et test</h2>
<p>Il suffit tout simplement de dire à Nginx de renvoyer les requêtes vers le FastCGI. La connexion se fait via la socket /tmp/fcgi.socket.</p>
<p>Pour faire simple, voici mon fichier de configuration, plus ou moins commenté (pour plus d&#8217;info, il y a la doc&#8230;) :</p>
<pre lang="bash">#User qui lance le process et nombre de fork
user www;
worker_processes  1;

#Error log et PID file
error_log  /var/log/error.log;
pid        /var/run/nginx/nginx.pid;

#Nombre max de clients par fork
events {
    worker_connections  1024;
}

#Gestion des connexions HTTP
http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/access.log  main;

    sendfile        on;
    keepalive_timeout  15;
    gzip  on;
#Gestion des VHOST
    server {
        listen       80;
        server_name  test.madeinsyria.fr;

        access_log  /var/log/test.madeinsyria.fr.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
#GESTION DU PHP
        location ~ \.php$ {
            #Dossier racine
            root           html;
            #On revoie vers la socket
            fastcgi_pass   unix:/tmp/fcgi.socket;
            fastcgi_index  index.php;
            #On défini le chemin des scripts php
            fastcgi_param  SCRIPT_FILENAME /usr/local/nginx/html/$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}</pre>
<p>Il suffit alors de faire une page php index.php, de mettre un phpinfo(); dedans et d&#8217;y accéder afin de valider le bon fonctionnement.</p>
<p>Pour finir, on passe les services Nginx et FastCGI en démarrage automatique. Pour cela :</p>
<pre lang="bash">root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'nginx_enable="YES"' &gt;&gt; /etc/rc.conf
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'php_cgi_enable="YES"' &gt;&gt; /etc/rc.conf</pre>
<p>Et voilà ! On a notre premier frontal web ! Il ne reste plus qu&#8217;à le cloner (bah oui, c&#8217;est une VM) pour faire le deuxième. La prochaine étape, c&#8217;est le serveur de fichiers statique en NFS, ça sera bien plus simple. On s&#8217;accroche !</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/08/summer-camp-etape-1-frontaux-web-nginx-php5/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[Summer Camp] Infra Web Haute Disponibilité</title>
		<link>http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/</link>
		<comments>http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 23:00:07 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[HAPROXY]]></category>
		<category><![CDATA[Haute Dispo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mes Projets]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[NGINX]]></category>
		<category><![CDATA[Pacemaker]]></category>
		<category><![CDATA[Puppet]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=665</guid>
		<description><![CDATA[Bonsoir à tous ! Pour occuper votre temps cet été (on sait tous que c&#8217;est plus calme en juillet/août), je vous propose de monter ensemble et en plusieurs étapes une palteforme Web Haute Disponibilité basée uniquement sur des technologies OpenSource. HAPROXY, Nginx, MySQL, NFS, Puppet, tout y passera. Faites chauffer les VM, faites chauffer le [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir à tous !</p>
<p>Pour occuper votre temps cet été (on sait tous que c&#8217;est plus calme en juillet/août), je vous propose de monter ensemble et en plusieurs étapes une palteforme Web Haute Disponibilité basée uniquement sur des technologies OpenSource. HAPROXY, Nginx, MySQL, NFS, Puppet, tout y passera. Faites chauffer les VM, faites chauffer le café, on va y aller !</p>
<p>Aujourd&#8217;hui je ne ferai que vous presenter cette infra, les choix techniques, et les differentes étapes de mise en place.</p>
<p><span id="more-665"></span>Un schéma résume souvent mille paroles et explications en IT. Je vais commencer par le schéma donc :</p>
<p><a href="http://madeinsyria.fr/wp-content/uploads/2011/08/INFRA-HA2.png"><img class="aligncenter size-medium wp-image-793" title="INFRA-HA" src="http://madeinsyria.fr/wp-content/uploads/2011/08/INFRA-HA2-300x227.png" alt="" width="300" height="227" /></a></p>
<p>&nbsp;</p>
<p>Alors que voit-on sur ce schéma ?</p>
<p>Tout d&#8217;abord, on a une couche de <strong>load balancing</strong> HTTP/HTTPS gérée par <strong>HAPROXY</strong>. Cette couche est <strong>clusterisée</strong> en mode failover grace à <strong>Pacemaker</strong>.</p>
<p>On retrouve ensuite les serveurs de caches Varnish qui soulagent au mieux les frontaux web grace au maintiens des éléments statique et des pages compilés.</p>
<p>La charge est alors répartie sur X serveurs <strong>web frontaux</strong> propulsés par le serveur web <strong>Nginx</strong>. Si j&#8217;ai choisi Nginx, c&#8217;est pour sa robustesse et sa capacité à gérer un nombre de connexions en moyenne 10 fois superieur à celui d&#8217;Apache2. Les frontaux web ne portent que de la configuration de serveur web et des interpreteurs de code (comme PHP par exemple).</p>
<p>Le code et autres données statiques sont portés par le<strong> serveur de fichiers</strong> dans le réseau <strong>backend</strong>. Le fichiers sont donc disponibles grace à un montage <strong>NFS</strong>.</p>
<p><del>Les applications web utilisent les <strong>frontaux SQL</strong> pour effectuer les requêtes en base. La charge sera répartie entre ces frontaux via <strong>ldirectord</strong>, un outil de load balancing intégré à Pacemaker.</del></p>
<p><del>Les frontaux SQL, eux, interrogent des<strong> datanode SQL. </strong>Le SGBD retenu est <strong>MySQL</strong>. En effet il existe en version Cluster et ses performances ne sont plus à prouver.</del></p>
<p>Pour les bases, on utilisera au final du <strong>MySQL Proxy</strong> pour faire du <strong>Split Read/Write</strong> sur des base répliqués en <strong>Master/Slave </strong>(j&#8217;explique le pourquoi du comment dans le billet).</p>
<p>En parallèle, dans le VLAN d&#8217;administration, on trouvera un <strong>Syslog</strong> portant les logs de l&#8217;ensemble de la plateforme. On trouvera aussi une <strong>machine d&#8217;administration</strong> portant un ensemble d&#8217;outils mais aussi un gestionnaire de configuration <strong>Puppet</strong>.</p>
<p>Tout ce beau monde tournera dans la mesure du possible sous <strong>FreeBSD</strong>. Dans certain cas (MySQL) je passerai par Linux pour la facilité d&#8217;installation et le support fourni.</p>
<p>Au niveau de l&#8217;ordre de déploiement on fera dans l&#8217;ordre :</p>
<ol>
<li><a title="[Summer Camp] Étape 1 – Frontaux Web (Nginx + PHP5)" href="http://madeinsyria.fr/2011/08/summer-camp-etape-1-frontaux-web-nginx-php5/">Frontaux Web (Nginx + PHP5)</a></li>
<li><a title="[Summer Camp] Etape 2 – Serveur de Fichiers NFS + ZFS" href="http://madeinsyria.fr/2011/08/summer-camp-etape-2-serveur-de-fichiers-nfs-zfs/">Serveur de fichier (ZFS + NFS)</a></li>
<li><a title="[Summer Camp] Etape 3.1 – MySQL Réplication" href="http://madeinsyria.fr/2011/10/summer-camp-etape-3-1-mysql-replication/">Réplication MySQL</a></li>
<li><a title="[Summer Camp] Etape 3.2 – MySQLProxy : Split Read/Write" href="http://madeinsyria.fr/2011/10/summer-camp-etape-3-2-mysqlproxy-split-readwrite/">MySQL Proxy : Split Read/Write</a></li>
<li><a title="[Summer Camp] Etape 4 – Load balancing HAPROXY et stunnel" href="http://madeinsyria.fr/2011/10/summer-camp-etape-4-load-balancing-haproxy-et-stunnel/">HAPROXY</a></li>
<li><a title="[Summer Camp] Etape 5 : Mise en cache avec Varnish" href="http://madeinsyria.fr/2011/10/summer-camp-etape-5-mise-en-cache-avec-varnish/">Mise en cache avec Varnish</a></li>
<li>Pacemaker</li>
<li>Syslog</li>
<li>CADEAU : les classes Puppet (le tuto puppet est déjà disponible : <a href="http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/">http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/</a> )</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>HowTo Puppet : Administration et industrialisation de masse</title>
		<link>http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/</link>
		<comments>http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 23:19:12 +0000</pubDate>
		<dc:creator>MadeInSyria</dc:creator>
				<category><![CDATA[Tuto]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Warrior]]></category>

		<guid isPermaLink="false">http://madeinsyria.fr/?p=656</guid>
		<description><![CDATA[Il y a quelques semaines,  j’ai étais confronté à une problématique assez basique et pourtant ignoré jusque là. On m’a demandé d’exécuter un script sur quelque 300 machines *nix et de parser deux fichiers HTML générés. Jusqu’ici, c’est un travail d’admin système de base. Or voilà, moi, j’ai 300 machines réparties sur des réseaux qui [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques semaines,  j’ai étais confronté à une problématique assez basique et pourtant ignoré jusque là. On m’a demandé d’exécuter un script sur quelque 300 machines *nix et de parser deux fichiers HTML générés. Jusqu’ici, c’est un travail d’admin système de base. Or voilà, moi, j’ai 300 machines réparties sur des réseaux qui sont HERMETIQUEMENT fermés de ma station d’administration. Il a donc fallu scripter une partie et traiter l’autre manuellement en urgence.</p>
<p>&nbsp;</p>
<p>Tout cela m’a fait me pencher sur des solutions de gestion de configurations et d’administration de masse. Parmi toutes ces solutions, j’ai retenu celles proposées par PuppetLabs (<a href="http://www.puppetlabs.com/">http ://www.puppetlabs.com/</a>). La suite de trois outils est infaillible :</p>
<ol>
<li>Puppet permettant la gestion centralisée des services et configurations</li>
<li>MCollective qui permet l’administration et l’exécution de commandes centralisé</li>
<li>Facter qui permet de dresser une véritable fiche d’identité du server</li>
</ol>
<p>&nbsp;</p>
<p>Aujourd’hui je vous propose une petite initiation à Puppet et quelques tips qui vous feront gagner du temps.</p>
<p><span id="more-656"></span></p>
<h1>Prérequis :</h1>
<ul>
<li>Deux machines (OSEF de l’unix, ici il y aura une Debian 6 et une FreeBSD 8.2)</li>
<li>Une liaison sur le port 8140 (port de communication Puppet) entre les deux</li>
</ul>
<p>&nbsp;</p>
<h1>Installation du Server (Puppet Master) :</h1>
<p>Le serveur  tournera ici sous Debian 6. Pour installer, le très habituel :</p>
<pre lang="bash">
aptitude install puppetmaster
</pre>
<p>Une fois installer, il faut éditer le fichier fileserver.conf qui permet d’autoriser l’accès aux dépôt de fichier Puppet. Pour cela, voici la syntaxe :</p>
<pre lang="bash">
[files]
  #Chemin du partage
  path /etc/puppet/files
  #Machines autorisés
  allow *.madeinsyria.fr
  #Ici tout les réseau en 192.168.X.X sont autorisés.
  allow 192.168.0.0/16
</pre>
<p>&nbsp;</p>
<p>Il faut aussi créer le fichier /etc/puppet/puppet.conf et y ajouter :</p>
<pre lang="bash">
[master]
  certname=puppet.madeinsyria.fr
</pre>
<p>La valeur de certname est celle du hostname de la machine (obtenu via la commande « hostname »).</p>
<p>Pour finir, il faut éditer le fichier /etc/hosts/ afin de spécifier les noms et IP des machines clientes (à supposer que leur noms ne peut être résolu via DNS).</p>
<p>A ce niveau, je préconise un bon reboot de la machine. En effet, un simple restart ne prend pas très bien en compte le certname. Or cela peut devenir un gros problème, car comme nous allons le voir, les certificats permettant de communiquer ne pourront pas être transmis.</p>
<h1>Installation du client (Puppet Agent) :</h1>
<p>A ce niveau rien d’extraordinaire. On déploie l’agent Puppet avec un classique (oui, mon client est une FreeBSD) :</p>
<pre lang="bash">
pkg_add –r puppet
</pre>
<p>Le paquet est installé et un fichier de configuration /usr/local/etc/puppet/puppet.conf est généré. Je conseil de le vider entièrement et de remplacer son contenu par :</p>
<pre lang="bash">
[puppetd]
  server=FQDN-DU-SERVER-PUPPET

[main]
  logdir = /var/puppet/log
  vardir = /var/puppet
  ssldir = /var/puppet/ssl
  rundir = /var/run/puppet
  factpath = /var/puppet/lib/facter:/var/puppet/facts
  templatedir = /var/puppet/templates
</pre>
<p>En effet, par défaut le fichier contient TOUS les éléments de configuration aussi bien pour la partie cliente que serveur. Et comme je suis gentil comme tout, voici la même chose pour Debian :</p>
<pre lang="bash">
[puppetd]
  server=FQDN-DU-SERVER-PUPPET

[main]
  logdir=/var/log/puppet
  vardir=/var/lib/puppet
  ssldir=/var/lib/puppet/ssl
  rundir=/var/run/puppet
  factpath=$vardir/lib/facter
  templatedir=$confdir/templates
</pre>
<h1>Initialisation de la relation entre le maitre et l’agent :</h1>
<p>Puppet utilise le chiffrement SSL pour ses communications sur le port 8140. Or qui dit SSL, dit certificats. Le server maitre sera en fait une autorité de certification et permettra de délivrer des certificats aux agents. Ce processus se déroule en deux parties :</p>
<ol>
<li>L’agent demande un certificat via un CSR</li>
<li>Le maitre signe le client</li>
</ol>
<p>Pour faire la demande du coté de l’agent, il suffit de taper la commande :</p>
<pre lang="bash">
root@OAF-PRJ-SYSLOG:~# puppet agent --test
info: Creating a new SSL key for oaf-prj-syslog.madiensyria.fr
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for ca
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
info: Creating a new SSL certificate request for oaf-prj-syslog.madiensyria.fr
info: Certificate Request fingerprint (md5): 8A:03:E3:57:53:8B:91:FC:89:61:B8:A0:E0:F4:F0:EC
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
Exiting; no certificate found and waitforcert is disabled
</pre>
<p>Cette commande est celle que vous utiliserez le plus. Elle permet de demander un update manuel coté serveur. Si le client n’a pas de certificat, il demandera par la même son certificat.</p>
<p>Coté maitre, il ne reste plus qu’à signer le client. Pour visualiser les demandes en cours, il faut faire :</p>
<pre lang="bash">
root@puppet:~# puppetca --list
oaf-prj-syslog.madiensyria.fr
</pre>
<p>Puis pour signer le client :</p>
<pre lang="bash">
root@puppet:~# puppetca --sign --all
notice: Signed certificate request for oaf-prj-syslog.madiensyria.fr
notice: Removing file Puppet::SSL::CertificateRequest oaf-prj-syslog.madiensyria.fr at '/etc/puppet/ssl/ca/requests/oaf-prj-syslog.madiensyria.fr.pem'
</pre>
<p>Pour finir, l’agent va récupérer son certificat :</p>
<pre lang="bash">
root@OAF-PRJ-SYSLOG:~# puppet agent --test
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for oaf-prj-syslog.madiensyria.fr
info: Caching certificate_revocation_list for ca
info: Caching catalog for oaf-prj-syslog.madiensyria.fr
info: Applying configuration version '1306778426'
notice: Finished catalog run in 0.23 seconds
</pre>
<h1>Après la configuration, un petit déploiement test :</h1>
<p>Un exemple Puppet, est le déploiement NTP. Ce service si simple et pourtant crucial est l’exemple parfait du service à industrialiser et maitriser. Nous allons donc voir comment configurer tout ça.</p>
<h2>Création du module :</h2>
<p>D’un point de vu Puppet, le NTP ne sera qu’un simple module. Je ne vais pas entrer dans le détail de la structure des modules Puppet, c’est assez complexe d’un point de vu hiérarchique (mais simple fonctionnellement parlant). Pour plus d information sur le sujet, il existe : <a href="http://docs.puppetlabs.com/learning/modules1.html">http://docs.puppetlabs.com/learning/modules1.html</a>.</p>
<p>Dans un premier temps j’ajoute la commande suivante qui me permettra de créer toute l’arborescence d’un module en une commande à mon .bashrc :</p>
<pre lang="bash">
mkmod() {    
     mkdir "$1"     mkdir "$1/files" "$1/lib" "$1/manifests" "$1/templates" "$1/tests"
               }
</pre>
<p>Je me rends par la suite dans /etc/puppet/modules/ ou je crée ma hiérarchie de module avec ma nouvelle commande :</p>
<pre lang="bash">
root@puppet:/etc/puppet/modules# mkmod ntp
</pre>
<p>Puis je crée le fichier de module en lui-même (une class Puppet) dans le sous répertoire manifests avec un nom de fichier init.pp :</p>
<pre lang="bash">
root@puppet:/etc/puppet/modules# cd ntp/manifests
root@puppet:/etc/puppet/modules/ntp/manifests # vim init.pp
class ntp {
    #En fonction de l’OS, je defini des paramètres spécifiques
    case $operatingsystem {
        freebsd: {
            $service_name = 'ntpd'
            $conf_file = 'ntp.conf.bsd'
            $ntppath = '/etc/ntp/ntp.conf'
        }
        debian: {
            $service_name = 'ntp'
            $conf_file = 'ntp.conf.debian'
            $ntppath = '/etc/ntp.conf'
       }
    }
    #Je m’assure que le service NTP est installé sur la machine
    package { 'ntp':
        ensure => installed,
    }
    #Je m’assure que le service tourne, mais uniquement si le fichier ntp.conf est dispo
    service { 'ntp':
        name => $service_name,
        ensure => running,
        enable => true,
        subscribe => File['ntp.conf'],
     }
     #Je m’assure que ntp.conf existe, mais seulement si le service NTP est installé
     file { 'ntp.conf':
         path => $ntppath,
         ensure => file,
         require => Package['ntp'],
         #Le fichier est récupérable dans : /etc/puppet/modules/ntp/files/
         source => "puppet:///modules/ntp/${conf_file}",
      }
}
</pre>
<p>En cadeau, mon fichier NTP de démo à placer dans /etc/puppet/modules/ntp/files/ :</p>
<pre lang="bash">
root@puppet:~# cat /etc/puppet/modules/ntp/files/ntp.conf.bsd
serveur time.intrinsec.com
driftfile /var/db/ntp.drift
</pre>
<p>Il ne reste plus qu’à utiliser cette classe en l’appelant dans les fichiers de base de Puppet à savoir :</p>
<ol>
<li>/etc/puppet/manifests/modules.pp qui contient tout les modules utilisables</li>
<li>/etc/puppet/manifests/nodes.pp qui contient tout les agents et leur configuration</li>
<li>/etc/puppet/manifests/site.pp qui fait appel à nodes.pp et modules.pp</li>
</ol>
<p>&nbsp;<br />
Voici donc le contenu de modules.pp :</p>
<pre lang="bash">
root@puppet:/etc/puppet/manifests# cat modules.pp
import "ntp"
</pre>
<p>Celui de nodes.pp :</p>
<pre lang="bash">
root@puppet:/etc/puppet/manifests# cat nodes.pp
#n défini un ensemble de service de base
node basenode {
    include ntp
}

#Et on fait hérité mon agent de cet configuration
node 'oaf-prj-syslog.madeinsyria.fr' inherits basenode {
}

#Tout les agents non cité auront la configuration du default
node default inherits basenode {
}
</pre>
<p>Pour finir, on appel tout le monde dans site.pp :</p>
<pre lang="bash">
root@puppet:/etc/puppet/manifests# cat site.pp
import "modules.pp"
import "nodes.pp"
</pre>
<h2>Déploiement :</h2>
<p>Tout ce beau monde est prêt à déployer, alors testons tout cela ! Sur le client, executons notre commande magique :</p>
<pre lang="bash">
root@OAF-PRJ-SYSLOG:~# puppet agent --server puppet.madeinsyria.fr --test
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for oaf-prj-syslog.madiensyria.fr
info: Caching certificate_revocation_list for ca
info: Caching catalog for oaf-prj-syslog.madiensyria.fr
info: Applying configuration version '1306778426'
notice: /Stage[main]/Ntp/Package[ntp]/ensure: ensure changed 'purged' to 'present'
--- /etc/ntp.conf       2010-10-17 15:35:26.000000000 +0200
+++ /tmp/puppet-file20110601-1931-glkc6r-0          2011-06-01 15:28:22.000000000 +0200
@@ -1,55 +1,2 @@
-# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
-
+serveur time.intrinsec.com
driftfile /var/lib/ntp/ntp.drift
-
-
-# Enable this if you want statistics to be logged.
-#statsdir /var/log/ntpstats/
-
-statistics loopstats peerstats clockstats
-filegen loopstats file loopstats type day enable
-filegen peerstats file peerstats type day enable
-filegen clockstats file clockstats type day enable
-
-
-# You do need to talk to an NTP server or two (or three).
-#server ntp.your-provider.example
-
-# pool.ntp.org maps to about 1000 low-stratum NTP servers.  Your server will
-# pick a different set every time it starts up.  Please consider joining the
-# pool: &lt;http://www.pool.ntp.org/join.html&gt;
-server 0.debian.pool.ntp.org iburst
-server 1.debian.pool.ntp.org iburst
-server 2.debian.pool.ntp.org iburst
-server 3.debian.pool.ntp.org iburst
-
-
-# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
-# details.  The web page &lt;http://support.ntp.org/bin/view/Support/AccessRestrictions&gt;
-# might also be helpful.
-#
-# Note that "restrict" applies to both servers and clients, so a configuration
-# that might be intended to block requests from certain clients could also end
-# up blocking replies from your own upstream servers.
-
-# By default, exchange time with everybody, but don't allow configuration.
-restrict -4 default kod notrap nomodify nopeer noquery
-restrict -6 default kod notrap nomodify nopeer noquery
-
-# Local users may interrogate the ntp server more closely.
-restrict 127.0.0.1
-restrict ::1
-
-# Clients from this (example!) subnet have unlimited access, but only if
-# cryptographically authenticated.
-#restrict 192.168.123.0 mask 255.255.255.0 notrust
-# If you want to provide time to your local subnet, change the next line.
-# (Again, the address is an example only.)
-#broadcast 192.168.123.255
-# If you want to listen to time broadcasts on your local subnet, de-comment the
-# next lines.  Please do this only if you trust everybody on the network!
-#disable auth
-#broadcastclient
info: FileBucket adding /etc/ntp.conf as {md5}3e250ecaf470e1d3a2b68edd5de46bfd
info: /Stage[main]/Ntp/File[ntp.conf]: Filebucketed /etc/ntp.conf to puppet with sum 3e250ecaf470e1d3a2b68edd5de46bfd
notice: /Stage[main]/Ntp/File[ntp.conf]/content: content changed '{md5}3e250ecaf470e1d3a2b68edd5de46bfd' to '{md5}9b52a60a69ca6c82e9c8fdb96458e7cb'
info: /Stage[main]/Ntp/File[ntp.conf]: Scheduling refresh of Service[ntp]
notice: /Stage[main]/Ntp/Service[ntp]: Triggered 'refresh' from 1 events
notice: Finished catalog run in 1.13 seconds

root@OAF-PRJ-SYSLOG:~# /etc/init.d/ntp status
NTP server is running.

root@OAF-PRJ-SYSLOG:~# cat /etc/ntp.conf
serveur time.intrinsec.com
driftfile /var/lib/ntp/ntp.drift
</pre>
<p>C’est gagné et en moins de 2 seccondes ! Je posterai sous peu plein de classes de base pour déployer des Apache, PHP5, MySQL (et MySQL Cluster), NTP, etc.</p>
<p>J’espère que vous voyez mieux le potentiel d’une telle solution ! Pour info, j’ai déployé via Puppet un LAMP configuré et optimisé en 34 secondes…</p>
<p>N’hésitez à poser des questions ou à commenter si vous rencontrer des problèmes</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 0.588 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-28 11:11:51 -->

