déc 15

Introduction

After the success of last semester MDA (Magento Darwin Awards), we decided to publish the 2010 update.

The concept, for the new comers, is to elect the best « worst idea », the most unpredictable « victory of mind over matter », simply put, the best of the best failures we had to handle at our support desk. This is my community blog but I’m the CEO of a European hosting company called NBS System (our site will soon be available in English also).

We are currently handling managed servers in the E-commerce field, mainly for Magento. We are the biggest hosting company around Magento hosting in France with >400 hosted sites, so we have a lot, a very big lot of support requests and some are just « too big to be silently classified ».

As everyone, we also make mistakes, so we have our own entries in this MDA! One more thing, we never laugh with a bad spirit, we laugh because this is a way to lower the pressure, it’s never made in bad spirit, to « taunt » people or the make fun of them, it’s just for everyone to enjoy this little bestof ! As a matter of fact, in this issue, we ranked second, lucky us…

The concept is inspired of the world renowned « Darwin Award » which elects the people who were kind enough to clear the human gene pool from their flawed genome by dying in the most stupid possible way.

Enough of introduction, let’s make it directly to the Winners; here are the Winter 2010 “Magento Darwin Awards”!

Rank 1: Virtualization is Evil

Customer’s Tech Team: Boss, we should consider moving this App to a Virtual Machine.
Customer’s Boss: No. Virtualization consumes a lot of resources. We’ll use Cloud instead.
Customer’s Tech Team: But I think that Cloud is based on virt…
Customer’s Boss: I don’t care about your thinking’s, I said we’ll do Cloud!

/* Later */

Customer’s Tech Team: Okay, our boss had a brilliant idea; we won’t take the Virtual Machine but a Cloud instance.
Tech Team: ??? But the Cloud is…
Customer’s Tech Team: I know… But my boss doesn’t and, in a way, I think this is better like this. I bet he has seen a Microsoft ad yesterday…
Tech Team: So be it!

Rank 2: SEO Genius

As we previously did, I’d like to include our own, subtle but yet stupid mistakes. Everyone has failures and even with the best procedures good will and attention, well, you know the deal, shit happens…

SEO Provider: Hi Philippe. I’ve been doing a quick check around your site (www.nbs-system.com) and found some pretty unexpected results in your SEO.
Me: Like what?
SEO Provider: Have you made any special effort to be ranked on « expresso coffee machine » or « vacuum cleaner robot »…?
Me: Well not really, beside this is not really related to hosting or security, so… no.
SEO Provider: Well now you are ranked 3 on this! Cheers. With a sub domain being [test-customer].nbs-test.nbs-system.com
Me: No… Don’t tell me theses sub domains are publicly available for the bots?
SEO Provider: Okay, I won’t tell you.
Me: Damn, I think we should also be positioned on high heels, sex toys and running shoes since those are the customers actually using the test domain.
SEO Provider: Yep. But up to my statistics, you really are losing positions on sex toys…
Me: OMG…!

Rank 3: Wake me up!

Customer: Your 24×7 support service wasn’t reachable this morning at 6h50 am. I’m paying you every month for a « so called » 24×7 support and your guys aren’t reachable, shame on you.
Me: Well, let me dig into this problem and I’ll find the one responsible for this very sensible mistake and get back to you.
Customer: You’d better…

/* Later on */

Me: Guyz, give me your support cellphone logs. I want to know if someone missed a call this morning at 6h50 am, big issue there.
Support team: Okay boss, here is mine, pay a visit to the log, I never ever missed a call.
Me: I look in the log book and… There’s no incoming call at 6h50… I take a picture of the cellphone screen and send it back to the customer with some nice word around.

/* Later on */

Customer’s tech team member: I double checked my phone log and last monday at 6h50 am, I dialed 06.xx.77.xx.63 instead of your number 06.xx.77.xx.93. So yes, I didn’t had someone of your service but… It was barely undetectable on my end since the guy told me « Yes ? », I explained the problem about our servers being overloaded during 1 minute and a half and in the end he said « Yes no problem, I’ll take of that » !!! Sorry about that…

What happens in the JVM stays in the JVM

Customer: I had awful sales This Week End.
Support team: Well, we can’t really help in this do we ?
Customer: Oh yes you can, there’s only 3172 products available instead of 1.4 Millions Sku’s.
Support team: This can explain the sales were “limited”, let me have a look…
Support team: After we discussed a bit with you web agency, we found that SOLR servlet died while indexing your catalog, after just 3172 products were indexed.
Customer: And you didn’t detected anything ?
Support team: Well the JVM daemon was still there, and as we use to say “what happens in the JVM stays in the JVM”, so no, we weren’t able to see the problem.
Customer: Any way we can spot this for later safety?
Support team: Your web agency provided a test code to run with the crons to check if the servlet are healthy or not.

Phpinfo()

Customer: Is there a way on your systems to get informations like the one phpinfo() could provide ?
Support team: Well you can execute PHP on the servers so why not use phpinfo() ?
Customer: Oh, yes, brilliant… welllllll, sorry…

Wait, I’m looking for a solution…

Support team rookie: We didn’t found the problem yet but we are still looking for it and we’ll get back to you as soon as there is a solution to the problem you reported.
Support team Boss: Just tell me you didn’t send that mail to the customer…

Look, dady is on TV!

Customer (on a VPS server): I’m proud to announce I’ll be on a national TV show!
Support team: Well, nice success, are you planning to talk about your site?
Customer: Of course I will, this will attract a lot of customer to my site?
Support team: And what are you considering to handle the hundreds of thousands hits that your site will take ?
Customer: Uh why ?
Support team: Because you will get more that 50 times normal trafic so your server won’t take it?
Customer: No problem, do what’s needed, I’ll pay.
Support team: When is the show exactly?
Customer: In one hour and a half…
Support team: Praying will give you the best results!

My flash is beautiful

Support team: 4 films of 10 Mo per film streaming in Flash on the homepage is a lot.
Customer: Well this is not much actually, the advertising company made its best to lower the size of it.
Support team: Well compared to the average 1.8 Mo average surf session, this is still quite a sensible amount of data.
Customer: Could this explain our bandwidth consumption?
Support team: This is a serious lead J

We are hosting the NASA (returns)

Support team: Is this site really taking 300 000 Unique visitor per day?
Customer: No.
Support team: Well it seems the reverse proxy is counting this precise amount and your 4th web server just died under a 280 load… (12 cores => 12 is 100 % load without a process waiting to be handled). The second one is responding every odd minute.
Customer: Okay, I think someone made a small mistake in retargeting campaign, we take hits for anything. People are looking for chainsaws and get our retargeting ads about underwear.
Support team: Perhaps the retargeting algorithm thought that people usually interested in chainsaws leaving a site usually by underwear?
Customer: Sure dude, let me just hang the retargeting company, consider this a preemptive move.

700 000 mails sent for only 80 needed?

Support team: One of the mailer is dying!
Support team Boss: Why is it overloaded?
Support team: Someone is trying to send 700 000 mails…
Support team Boss: Shoot the queue, drop the incoming connections from this customer on the TCP/25, call Yoda and tell him to send reinforcements.
Support team: Ok Boss!

/* Later */

Support team (to customer): Why the hell did your site tried to send 700 000 mails in one hour?
Customer: I created a loop in PHP to send 80 mails. It was supposed to parse a file and send the mail to each line. I guess it failed…
Support team: In a way, yes… At least did the 80 persons got their mails?
Customer: No.
Support team: Failed. You’ll probably be in the MDA 2010 with this one.
Customer: Fair enough…

We commit to production this Week End

Customer: We will commit our preproduction to production this WE.
Support team Boss: No way. It will fail, you doesn’t have the 24/7 support option and your developers aren’t there, this is plain suicide.
Customer: No no, not a problem it’s just dropping my existing catalog and importing new products, I can handle that alone and beside, the dev team left me a script.
Support team Boss: This script has been tested?
Customer: I guess yes.
Support team Boss: No way.

/* Later */

Customer: The process failed, it’s Saturday and I can’t do anything, can you help?
Support team: Did someone told you that Week end migrations generally fail?
Customer: Well, yes…
Support team: This person was wrong, the correct sentence was « It always failllll the week end ».
Customer: So what do we do?
Support team: Well, we’ll try to fix that for you, but you’ll be billed.

(PS : My wife hate you, but this is only because she doesn’t like to be awaken at 4 am, nothing personal)

AND… Medal of honnor: The Slider O’ Death returns!

Live, in production, even more beautiful than the « project » which won the previous award.

(Excited) Customer: Hi NBS System team, I’d like to inform you that we’ll be on TV tomorrow!
Support team: Well glad you made it to people screens! We’ll watch your servers closely this evening and provide additional boosters if needed.

/* No…. come on, as usual, this was not the way things happened. What really happened */

(Annoyed) Customer: Hi, my servers are very very very slow.
Support team: I’ll have a look ASAP.

/* support guy working */

Support team: Well I found a hint. Part of the problem is that you have a lot of incoming connections, another part of the problem is that your site is consuming way more resources than before, especially the part called « Design your own xxxx ». Does those inputs help you, can you provide me with more information regarding this?

(Guilty voice) Customer:
Well, perhaps we should have informed you that we were on a major TV show tonight?

Support team:
Noooooo… this is not like if those nasty little TV appearance were quadrupling your incoming traffic, no why bother with those details? Sill this only explains about the overload, we will start a dozen virtual machines and your site will be taking the load in 5 to 7 minutes. But why is it consuming 10 times more resources, especially in the databases requests, that have made a peak to … WTF? …  37 000 SQL requests per seconds???

(still feeling guilty voice) Customer:
I don’t really know what you’re talking about, I’m not IT.
Support team: Did you put any new stuff online, like a new feature?
(Proud) Customer: Yes a very nice feature where you can design your own [customer_product].
Support team: Is it something where you can choose among ten types, 8 different sizes, 6 shapes, 10 colors and so on?
(Very proud) Customer: Yes, and it show you live your product among our full catalog of hundred thousands of articles.
Support team: OMG, The Slider O’ Death finally got its way online!!!

For those who didn’t know what the SOD concept was, they are the winner of last Magento darwin awards contest. You can find the full review of this wonderful concept here. Simply put, this is a way to interrogate the DB live, using AJAX requests, as soon as you move a cursor on a slider. 10 position, 10 colors, 6 shapes, etc… 10*10*6*8*… = thousands of requests per second, move your cursor faster, it makes thousands of requests per seconds.

You know, those little sliders, looking so cute (and loading live the products):

slider

NBS System Support team wish you a very good Xmas, wonderful end of year sales. We’d like to thanks every support cell around the world and especially the hoster’s one and Magento’s one, Cheers guy !

Emile aka « Imil », aka The_Boss

Photo Emile

Adrien aka « Ze »

Head with interrogation point. The intensity of the doubt.

Denis aka « Jawa »

DSC_0903

Christophe aka « Chris »

DSC_0889

Guillaume aka « Champitoad »

IMG_0141

Florent aka « Flo »

Head with interrogation point. The intensity of the doubt.

écrit par Philippe Humeau \\ tags: , , , ,

juil 01

Introduction

Q : Pourquoi maitriser le shell ?

R : Parce que ca fait gagner un temps fou, que c’est propre, pêrmbeau, systématique, rapide et quasi illimité en terme de possibilités.

Merci à Adrien Urban de NBS System pour la création de ce support. Il vous sera peut être utile pour dédoubloner un fichier de clients ou de commandes, peut être pour faire certains tris dans vos bases ou fichiers. Les hébergeurs comme NBS System ou d’autres fournissent des accès shell limités, mais qui permettent d’utiliser ces outils (ou une partie d’entre eux).

Ces outils seront d’ailleurs principalement utiles aux développeurs.

UNIX & son copain Posix, leurs vies, leurs œuvres

Voici un cour de shell bash/unix pour les gens qui ne sont pas à l’aise avec, essentiellement les développeurs. Ca fait gagner un temps fou.

C’est volontairement simplifié, le but c’est pas de faire des DEV des SR, c’est juste un manuel de survie, donc les SRS qui balanceront des « ouais mais en fait c’est pas tout à fait ca » :

cat /dev/urandom > /dev/tty_du_srs_en_question 2>&1 &

Il est important de noter que la première partie part du principe de base que les noms/mots/autres sont sans espace ou autres caractères spéciaux. Cet aspect est présente après le reste.

Les concepts de base

Les flux particuliers :

stdin (entrée standard) : ce n’est pas une commande, c’est un FD, file desciptor, spécial qui est le flux d’entrée. C’est le fd 0.
stdout (sortie standard) : celle que l’on utilise 90% du temps, FD, en résumé ce qui s’affiche en retour d’une commande. c’est le fd 1.
stderr : sortie d’erreur c’est le fd 2.

on en reparle après.

Les redirections :

| : celui qu’on appel « pipe » le plus régulièrement, permet de joindre la sortie standard d’une command à l’entrée standard d’une autre.
< : prend son entrée standard à partir fichier
> : redirige la sortie standard vers autre chose, un fichier par exemple ou /dev/null (dans l’espace)
(on peut préciser par exemple 2>&1 qui redirige la sortie d’erreur (2) vers la sortie standard (1))
>> : redirige en mode append, on ajoute les données à la fin du fichiers existant.

Cas concrets :

ls > toto.txt : redirige le contenu de la sortie de ls (les fichiers listés) dans le fichiers toto.txt
ls >> toto.txt : idem sauf que ca ajoute à la fin du fichier. WARNING la première (ls>toto.txt) détruit toto.txt si il existe déjà.
ls > /dev/null : renvoi la liste des fichiers dans l’espace (/dev/null = grosse poubelle géante de taille infinie)
ls | more : liste les fichiers et envoi le résultat à la commande more qui affichera page par page.
less < toto.txt : éjectera toto.txt dans l’entrée standard de less qui sortira un résultat page par page. (ceci dit ca revient au meme que faire directement less toto.txt mais j’avais pas d’exemple en tete)

Wilcards :

Comme sous Windows, on peut utiliser des jokers ou wildcards :

ls * affiche tous les fichiers (ceci dit c’est le comportement par défaut)
ls t?t?.txt : listera titi.txt toto.txt et tutu.txt enfin remplacera ? à la position voulu par n’importe quel lettre.
ls t*.txt : affichera tous les fichiers commencant par t et finissant par .txt
ls tata[1-3].txt affichera tous les fichiers commencant par tata suivi du chiffre 1, 2 ou 3 puis finissant par .txt
ls t[a-i]* affichera tous les fichiers commencant par t, suivi d’une lettre entre a et i
bien sur on combien à l’infini : ls t[1-3]abc?zz.t?t est donc une commande recevable

WARNING : Unix est TOUJOURS « case sensitive ». a n’est pas égal à A.
WARNING : Contrairement a Windows, le remplacement des wildcards est traité directement par le shell, indépendamment du programme appelé. Le programme reçoit donc directement la liste des fichiers qui correspondent, même s’il s’attendait a recevoir une expression qui contenait ces caractères la.

ls T* et ls t* retourneront donc des résultats différents ! C’est une règle valable pour TOUTES les commandes.
INFO : TAB complète dans le shell quand c’est possible, sinon propose des possibilités.

Les amis (commandes) :

ls : liste les fichiers et répertoire

ls liste les fichiers du répertoire courant
ls -l la même chose en mode colonne.
ls -l –color colore les fichiers en fonction de leurs droits et types
-r : récursif

cat : équivalent de type sous windows

cat toto.txt, affiche le contenu de toto.txt
cat toto.txt titi.txt > tutu.txt, concatene toto et titi dans le fichier tutu.txt
cat toto.txt titi.txt >> tutu.txt, concatene toto et titi à la fin du fichier tutu.txt
cat * : affiche le contenu de tous les fichiers du répertoire courant. donc cat * > tutu.txt, copie tout dans tutu.txt

On peut aussi s’en service pour écrire dans un fichier :

cat > test.txt, redirigera donc l’entrée standard vers test.txt, on tape ce qu’on veut au clavier puis à la fin on tape CTRL+d ce qui interrompt la saisie et stock le contenu dans le fichier. Très pratique pour creer un fichier rapidement. Si on veut écrire à la fin d’un fichier existant : cat >> test.txt

cut : coupe ce que l’on récupère en fonction d’un délimiteur précis

imaginons que le fichier toto.txt contienne :
abc.def.ghi test 123
zzz.aaa:bbb_456

pour afficher uniquement un des blocs séparé par un des séparateurs (en l’occurence . ou  »  » ou _) : cat toto.txt | cut -f 1 -d « . »

donnera en sortie :
abc
zzz
-f c’est le champs (field) et -d le séparateur.

donc pour obtenir uniquement 456 :
cat toto.txt | cut -f 3 -d « _ » par contre la ligne « abc.def.ghi test 123″ ne contenant pas d’underscore, n’a pas de troisièmes champs… et seule une ligne vide sera affiché, mais on verra plus loin comment éviter ca.

grep : affiche la pattern recherchée parmis des fichiers ou un flux

ls -l | grep toto.txt ne retournera que les lignes avec toto.txt parmis tout le résultat du ls.

cat toto.txt | grep « henri » n’affichera que les lignes du fichier toto.txt qui contiennent « henri »

cat toto.txt | grep « henri » | grep -v « IV » n’affichera que les lignes du fichier toto.txt qui contiennent « henri » mais pas celle contenant « IV »

le -v exclue le mot qui suit.
l’option -r fait un grep récursif,
l’option -i ignore la case (plus de distinction majuscule/minuscules),
l’option -n  affiche egalement les numeros des lignes : grep -nri henri . | grep -v « IV »

sortira tous henri de tous les fichiers du répertoire courant et des sous répertoire, peut importe que ce soit henri ou HENRI ou HeNrI, sauf les ligne contenant également « IV ». Chaque ligne aura le nom du fichier, le numero de la ligne, ainsi que le contenu de la ligne en question.

les options -A et -B sont pratique, c’est After et Before.

donc grep -A 2 -B 3 henri toto.txt sortira toutes lignes avec henri mais aussi les 3 lignes précédentes et les 2 lignes suivantes.

find : trouve des fichiers à partir d’un chemin précis et permet d’executer une commande dessus

find a plein plein d’options, je n’en montrerai ici que deux qui sont classiques et utiles
find . -name « *.txt » -print : trouvera récursivement tous les fichiers avec l’extension .txt à partir du répertoire courant « . »
find . -name « *.txt » -exec rm ‘{}’ \;

bon celle là elle est un peu funky en terme de synthaxe, mais :

le {} désign la liste de ce qui a été retourné par find et le -exec y applique une commande. En l’occurence rm qui efface les fichiers.

donc cette ligne de commande trouvera à partir du répertoire courant et dans tous les sous répertoire les fichiers avec extensions .txt, et les effacera.

find . -exec grep -q www.nbs.fr ‘{}’ \; -print

Afficher tous les fichiers contenant www.nbs.fr.On pourra ensuite y appliquer un autre traitement, par exemple avec sed pour remplacer www.nbs.fr automatiquement par www.nbs-system.com.

Note, il existe aussi l’option -iname qui fait comme -name, mais sans tenir compte de la case des noms de fichier.

locate : trouve des fichiers à partir d’une DB générée la nuit

le système linux, en général, fait tourner régulièrement un programme qui met à jour le contenu d’une base stockant tous les fichiers de toutes les partitions.

l’avantage par rapport à find c’est qu’au lieu de chercher en live, on a un « cache » donc ca va beaucoup plus vite.

locate *.txt donnera la localisation de tous les fichiers .txt partout sur le système instantannément sans faire la recherche. Le défaut c’est que si vous avez un nouveau fichier depuis le dernier uptade de la base, il ne sera pas montré. Pour forcer l’update de la base en live : updatedb

Note: afin d’eviter certain probleme de droits sur la base, il est conseille de ne pas lancer updatedb a la main directement. Le script (emplacement sous debian) /etc/cron.daily/find le lance avec les bons arguments.

sort : permet de trier un flux

Trie les lignes…

cat dictionnaire.txt | sort > dictionnaire_trié.txt
cela va trier par ordre alphabétique le dictionnaire « dictionnaire.txt » et écrire le résultat dans dictionnaire_trié.txt
-r ca le fera à l’envers (reverse), la commande est simple mais elle a pas mal d’options différentes à apprécier :)

uniq : permet de rendre unique les données qui sorte d’un flux

Supprime des lignes identiques qui se suivent…

cat fichier_plein_de_doublon.txt | sort |
uniq > fichier_dédoublonné_et_classé.txt

si le fichier contient :
titi
titi
toto
tutu
tata
tutu

ca donnera :
tata
titi
toto
tutu

sed : permet de remplacer des strings par d’autres dans un flux ou des fichiers

sed est un couteau suisse du traitement des flux. Il est capable de faire énormément de choses. Nous allons voir une toute petite partie de sed, la partie la plus utilisée.
sed permet surtout de remplacer une chaine par une autre
sed s/www.nbs.fr/www.nbs-system.com/g index.html

Affiche le contenu de index.html en remplacant toute les occurrence de www.nbs.fr par www.nbs-system.com

La syntaxe de base est s/chaine d’origine/chaine a mettre/options ou :
-        Le s au debut signifie substitution
-        Le / qui separe les differentes partie peux etre en fait n’importe quel caractere. Il faut le prefixer d’un backslash (\) si on souhaite utiliser le caractere en question ailleur.
-        La chaine d’origine est en fait une regex, tout comme les recherches avec grep.
-        Les options peuvent contenir:

o       g – remplace toutes les occurrences sur une meme ligne.
o       i -Cela permet de faire une recherché de chaine sans tenir compte de la case
o       p – affiche la ligne s’il y a eu une substitution

On a un code dans lequel il y a des requetes SQL qui n’ont pas tenu compte de la case des noms de tables ou de champs (mysql sous windows a tendance a s’en foutre de la case) et on veux le faire passer sous unix.

Dans un premier temps, on affiche uniquement les lignes qui changent (option -n pour ne pas afficher par defaut, et le p de la substitution), de facon a verifier que cela ne fait pas de betises :

sed -n ‘s/MaJoLiE_tAbLe/majolie_table/igp’ fichier.php

Une fois que la substitution s’effectue correctement :

mv fichier.php fichier.php.old &&
sed ‘s/MaJoLiE_tAbLe/majolie_table/ig’ fichier.php.old > fichier.php

A noter que l’on a plus ni le -n, li le p, de façon a bien afficher tout le fichier d’origine.

Les regex, explications complete :

  • X                 un caractere de base correspond a lui-meme
  • .                 le point correspond a n’importe quel caractere (comme ? en shell)
  • ^                 S’il est place au debut correspond au debut de ligne.
  • $                 s’il est place en fin, correspond a la fin de ligne
  • [aoeuiA-Z]   Les classes de caracteres. N’importe quel caractere qui correspond (voyelle en misucule, ou une majuscule)
  • [^0-9]         un caractere qui n’est PAS un chiffre
  • [0-9]*         * correspond a 0-n fois ce qui precede. Ici, rien ou une suite de chiffres.
  • S\?              \? Correspond a 0 ou une fois ce qui precede. Ici, rien ou un S.
  • \(abc\)        Les \(…\) permettent simplement de faire un groupe.

Par exemple : \(ta\)\* correspond a rien, ou une suite de ta.
-        X\|Y            correspondra X ou Y. Attention, il faut utiliser des () pour limiter l’etendu.

Dans la chaine de remplacement, le caractere & sera remplace par l’ensemble de la chaine d’origine (pratique pour la conserver, mais la commenter). D’autre part, \n ou n est un chiffre sera remplace par le texte correspondant au neme groupe (les parentheses).

Des exemples concrets :

Afficher toute les lignes commençant par une lettre minuscule
grep ‘^[a-z]‘
Ajouter un premier argument a toute les appels d’une fonction : sed ‘s/ma fonction(/&1, /g’

Commenter tous les appels a la fonction prettylog (ne doit pas avoir de () dans les arguments:
sed ‘s#prettylog([^()]*)#/* & */#g’

remplacer les fonction log_database(, log_engine( par log(« database »,  ou log(« engine », :
sed ‘s/log_\(database\|engine\)(/log(« \1″, /g’

Bien evidement, on reste dans l’optique du : sed ‘s/…/…/g’ fichier1 > fichier2

tail : permet de voir la fin d’un fichier

tail toto.txt, affiche (par défaut) les 10 dernières lignes du fichier toto.txt

si vous avez à faire à un fichier qui change et qui grossit (genre fichier de log) et que vous voulez le suivre en continu :

tail -f toto.log : la commande ne s’arretera pas et continuera à vous montrer le fichier au fur et à mesure qu’il grossit.

head : permet de voir le début d’un fichier

comme tail mais pour montrer les lignes du début du fichier. (pas la peine d’essayer head -f)

chmod : permet de changer les droits d’un fichier ou répertoire

les droits sont cumulables, il existe read, write, execute. On va simplifier tout ca, mais il existe trois groupes à qui appliquer ces droits : le propriétaire du fichier, le groupe du fichier (généralement le groupe auquel appartient le propriétaire du fichier (voir chown)) et le propriétaire du fichier en lui même.

read vaut 4
write vaut 2
execute vaut 1

  • chmod 400 toto.txt donne les droits en lecture à root. chmod 444 toto.txt donne les droits en lecture à tout le monde.
  • chmod 555 c’est chmod 444 + chmod 111 soit les droits en lecture et en éxecution à tout le monde.
  • chmod 777 c’est lecture, écriture, exécution à tout le monde. (4+2+1 pour le propriétaire, le groupe et les autres).
  • chmod 000 enlève tous les droits à un fichier (notez que root bypass de toute façon ces droits)

Droits généralement utilisé :

600 – fichier normal, en lecture/ecriture uniquement pour son proprietaire
644 – pareil, et lecture pour les autres
700 – executable, en lecture/ecriture/execution uniquement pour son proprietaire
755 – pareil, et lecture/execution pour les autres

Note : un repertoire doit etre executable pour pouvoir aller dedans

Les droits peuvent egalement etre donner sous forme de modifications.

u – user
g – group
o – other
a – all

r – read
w – write
x – execute
X – execute si déjà present quelque part

chmod u+rw,go-w+rX

Ajoute les droits de lecture ecriture au proprietaire, enleve les droits d’ecriture au groupe et aux autres, leur donne le droit de lecture, ainsi que le droit d’execution si c’est un executable.

chown : permet de changer le proriétaire d’un fichier ou répertoire

Pour changer le proprietaire d’un fichier, il est necessaire d’etre root.

chown philippe:www-data toto.txt donne la propriété du fichier à philippe et l’affilie au groupe www-data.
chown xxx:yyy fichiers : xxx = user, yyy = groupe.

Donc si je veux donner la propriété et les droits à philippe et à tous les membres du groupe admin :
chown philippe:admin toto.txt

et avec un chmod 640 toto.txt je donne tous les droits de lecture/ecriture à philippe, la lecture au groupe admin, et aucun droits aux autres.

WARNING : un fichier en 777 est dangereux, tout le monde peut y écrire, a éviter en Web.
le truc classique en web qui passe (presque) dans tous les cas :
chown -R www-data.www-data *
chmod -R go-w+rX *

le -R dans ces commandes les rends récursives sur tous les fichiers et sous répertoires.

touch

touch crée un fichier vide s’il n’exite pas et change la date / heure à l’heure actuel si il existe.
touch toto.txt crée un fichier de toto.txt de 0 octets s’il n’existe pas et lui donne date/heure
au moment auquel commande est lancé s’il existe. Il existe d’autres options pour fixer une
date/heure précise entre autre.

mv / rm :

mv : c’est move.
mv toto.txt titi.txt renome toto.txt en titi.txt (attention, l’écrase s’il existe)

Note : mv permet egalement de renomer un repertoire, ou de deplacer plusieurs fichiers/repertoire vers un repertoire de destination.

rm toto.txt : efface le fichier toto.txt.
rm -r le fait récursivement. rm -f force l’effacement sans poser de question…

comme dans la plupart des commandes, on peut cumuler les switchs :

rm -rf * : efface récursivement tous les fichiers et répertoires situé sous le répertoire courant sans poser de question.

WARNING : guess why…

Lorsque vous utilisez mv ou rm de facon interactive, et que vous n’etes pas certain a 200% de votre ligne de commande (par exemple si c’est un via des variables, ou de l’expansion, …), utilisez l’options -i. Elle vous demandera confirmation avant d’écraser de façon irrémédiable des informations.

less / more :

Comme le dit régulièrement notre directeur technique, less can more. Donc less peut faire tout ce que fait more et plus.

Techniquement c’est bien aussi de connaitre more qui est en général plus utilisé dans les scripts ou les unix plus anciens (la ou il n’y a pas less)

less toto.txt va afficher le contenu (si il est en ascii, sinon en binaire il met un warning) du fichier toto.txt et bien sur ca se pipe :

grep henri toto.txt | less

pendant l’execution de more ou less vous pouvez appuyez sur / vous allez pouvoir rechercher dans le texte le mot qui vous intéresse.

echo :

echo affiche ce qui est en paramètre. echo est utile pour signaler quelque chose à l’utilisateur dans un script par exemple

(echo « Hello World »). echo peut aussi afficher le contenu d’une variable par exemple : echo $a ou encore se substituer à un ls en faisant echo * ou même à écrire dans un fichier echo YO > toto.txt.

la commande accepte beaucoup de switch, voir le manuel. (man echo)

man : les manuels des commandes

man ls
man awk (il fait mal à la tête celui la)

etc…

souvent sont aussi donné des références à d’autre man en pied de page du man.

par ailleurs man -k keyword recherche les pages de manuel qui parle de « keyword ».

Il existe plusieurs catégorie de man (1 à 8) de mémoire qui sont plus ou moins spécialisés. Généralement les commandes sont en man 1 (ce qui est le mode par défaut).

si vous voulez le man plus orienté programmation C d’une chose précise : man 3 sigpause man 2 c’est plus orienté sur les syscall. Bref vous c’est plutot le 1 donc man [commande].

Par défaut man vous affiche son contenu avec un pager (less), pendant l’exécution de man, vous pouvez donc appuyez sur / vous allez pouvoir rechercher dans le texte le mot qui vous intéresse également.

sudo / su : des commandes qui permettent de passer ou de lancer des commande en tant que Super Utilisateur (root quoi)

Arreter apache… : sudo apachectl stop

va prendre les droits root temporairement pour stopper apache, si vous êtes habitilité par le fichier sudoers à la lancer cette commande.

si c’est le cas, il vous suffit de retaper le mot de passe de votre utilisateurs sur le système pour lancer la commande.
su : permet de passer root en tapant le mot de passe du compte root de la machine.
sudo -s : permet de passer root, sans connaitre le mot de passe de root, si on y est autorisé par le fichier sudoers.

WARNING : root à TOUS les droits sans aucune limite de portée. Si vous demander au système d’écrire de la merde dans la ram, il le fera sans broncher, tout comme si vous lui demander de s’effacer lui même.

wc : compte les caractères, lignes ou les mots

wc -l toto.txt compte le nombre de ligne du fichier toto.txt
cat toto.txt | wc -l ca revient au même.
-m ou -c pour les charactères
-w pour les mots

awk : permet d’appliquer un traitement avancé de formatage à un flux ou d’un fichier

awk est un langage avec un synthaxe à part entière, pas simple de surcroit. C’est très puissant et très pénible. Personnellement je m’en sers que pour une chose, reformater une sortie standard.

Pour l’exemple, un fichier contenant :

tcpmux         1/tcp # TCP port service multiplexer
echo           7/tcp
echo           7/udp

les séparateurs de colonnes sont des tabulations (il y en a 2)… La joie…

Je veux afficher la colonne 1 et la colonne 3 en admettant que mes séparateurs sont des tabulations :

cat toto.txt | awk -F « \t » ‘{ print $1 $3 }’

le -F « \t » c’est pour dire que tabulation est le séparateur de champs. print $1 $3 affiche la premiere valeur et la 3°, selon ce séparateur.

bon le résultat est que j’ai :
tcpmux1/tcp
echo7/tcp
echo7/udp

si je veux y ajouter des espaces pour rendre ca lisible :

cat toto.txt | awk -F « \t » ‘{ print $1 «       » $3 }’

Évidemment, ca peut se séparer selon un autre séparateur, par exemple le « / » :

cat toto.txt | awk -F « / » ‘{ print $1 «      » $2 }’

retour de la commande :

tcpmux         1    tcp    # TCP port service multiplexer
echo           7    tcp
echo           7    udp

il a enlevé le séparateur au passage et l’a remplacé par 4 espaces.

Pour le moment c’est flou mais le jour où vous en aurez besoin, awk vous sauvera la vie ;-)

Dans le doute, man [nom de la commande]. Tous les admins lisent les mans, meme les SR/CQ expérimentés. Ca sert à rien de connaitre par coeur tous les switchs (options) d’une commande, le man est donc une référence régulièrement utilisée par tous.

Bash – gestion des commandes :

& : laisse un processus s’executer en tache de fond, et vous permet de continuer a travailler sur le shell

Genre find ca peut être long, donc mettre un find qui redirige son résultat dans un fichier et le laisser en tache de fond c’est parfois une bonne idée :

find /var/www -name ‘*.php’ > ~/find.log 2> ~/find.err &
fg / bg : met un processus en foreground (fg) ou background (bg).
fg %n : n étant le numéro du job si vous avez mis plusieurs jobs en background.
jobs : liste les jobs (en background ou suspendu)

Lorsque vous etes en train d’executer une commande, Contrôle-Z la suspend.
Foreground – repasse une commande suspendu ou en background au premier plan
Background – pareil que de l’avoir lancee avec &, la tache continue en fond.

ps aux : liste tous les processus

Une commande a un code de sortie. Ce code est presque toujours correspondant a la facon dont le processus c’est termine. Si ca c’est bien passé c’est 0 sinon c’est autre chose.

&& : permet de linker deux commandes, et de n’exécuter la deuxième que si la première a échouée.

rm toto.txt && echo « ok fichier effacé »

« ok fichier effacé » s’affichera que si le fichier toto.txt a été effacé.

|| : Inversement, ||  permet de n’executer la deuxieme partie que si la premiere n’a pas fonctionner.

rm toto.txt || echo « Erreur lors de la supression du fichier »

; : le point virgule est un délimiteur permettant d’enchainer les commandes mais sans vérifier que le retour de la précédente s’est bien passé. ls *; echo titi > toto.txt; cat toto.txt enchaine les 3 commandes.

export : plusieurs fonction, mais on va surtout utiliser export pour exporter une variable. (La rendre visible pour des programmes que vous lanceriez apres)

export a= »toto » (stock toto dans a, et exporte a)
ou export a=’ls’   (stock le retour stdout de la commande ls dans a et exporte a)

‘commande’ : c’est la quote (‘) inverse (alt-gr 7 sur un azerty, la touche au dessus de tab sur un qwerty). backquoté une commande ou expression force son évaluation, et utilise sa sortie standard a l’endroit de la commande.

a=ls stock ls dans a. Si on veut stocker le résultat d’une commande ls dans a :
a=’ls’

Quoting

\ : n’interprête pas le caractère suivant le backslash. utile pour plein de truc.

exemple : « cd mon truc » ne marche pas. Il faut taper « cd mon\ truc » pour que l’espace entre mon et truc ne soit pas perçu par la commande comme étant deux paramètre distincts.

Il est également possible d’utiliser, de façon complètement équivalente :

cd mon\ truc
cd mon » « truc
cd « mon truc »
cd ‘mon truc’
cd mon’ truc’ »

«  : double quotes. Entre double quotes, il n’y a pas de separation de mot, les variables ($a), double quotes, backquotes et backslash sont interprété. A utiliser de facon generale lorsque l’on utilise des variables, et que l’on ne veux pas avoir de separation de mot, ou de risque d’expansion. Essayez les commandes suivantes :

a=*
echo $a
echo « $a »

‘ : simple quotes. Entre simple quotes RIEN n’est interprete. Un autre simple quote met fin a la sequence sequence. Il n’y a AUCUN moyen de backslashe un simple quote dedans. Tres pratique quand on veux une chaine avec plein de double quotes, $ et autre qui reste exactement tel quel.

for : super important. Un exemple concret vaut mieux qu’un long discour. Je veux appliquer un traitement à tous les fichiers .txt du répertoire courant pour les renommer en .old :

for i in *.txt ; do mv -i « $i » « $i.old » ; done

on prend une variable i pour faire une boucle sur les mots que represente * (l’ensemble des fichiers du repertoire), ensuite on applique (do) avec $i qui est en fait une des valeurs de *, et on finit par done.

TRESSSS pratique…

Autre cas, d’utilisation : for ((i=0 ; i < 10 ; ++i)) ; { echo $i ; }

Affiche les chiffres.

Generalites

/etc/init.d/ :

c’est ici qu’on stock les scripts lançant ou stoppant les démons du système.

Par exemple sur apache :
/etc/init.d/apache start
/etc/init.d/apache stop
/etc/init.d/apache restart

pareil pour mysql et plein d’autres démons, la plupart accept stop, start, restart.

généralités :

–help donne de l’aide sur une commande
-v : en général rend la commande « verbose » (affiche plus d’info sur son execution)
-q : en général rend la commande quiet

C’est quasi toujours vrai pour –help pour -v et -q c’est fréquent mais pas systématique.

faire un script :

un script bash commence toujours par (sur sa premiere ligne) :

#! /bin/bash

C’est ce qui permet au système de savoir qu’il faut utiliser bash pour interpreter ce script.

un script de base :

cat > script_de_base.sh (on met « .sh » à la fin en général pour savoir que c’est un script bash mais c’est pas obligatoire)

#!/bin/bash

echo $1

(Contrôle-D pour finir)

ensuite on le rend exécutable: chmod +x script_de_base.sh
puis pour le lancer : ./script_de_base.sh toto

vous noterez le « ./ » au début c’est pour signaler qu’on lance le fichier depuis le répertoire courant « . » puisque, par sécurité, le répertoire courant n’est pas intégré à la variable PATH.

ca affichera $1 qui vaut en l’occurrence toto puisque $1 $2 $3 $4 etc… sont les paramètres dans l’ordre sur la ligne de commande, $0 étant le nom du programme en lui même, ici : ./script_de_base.sh

pour se faciliter la vie on met en général le path standard des binaires utiles dans le début du script :

PATH=/bin:/usr/bin:/sbin:/usr/sbin

et puis un commentaire sur ce qu’il fait le machin, c’est mieux pour les copains et les lendemains de cuites.

Quelques exemple de synthaxes un peu évoluées et utiles :

grep die *.php | grep -v « // » | grep -v « /\* » | grep -v « \*/ »

ca devrait vous retourner le nom des fichier php, avec le contenu après un : qui contienne un die mais qui n’est pas commenté (sur la ligne elle-meme).

si vous voulez tous les effacer :

Pour ne garder que les fichiers qui correspondent

grep die *.php | grep -v « // » | grep -v « /* » | grep -v « */ » |
cut -f 1 -d « : »

donc si on assigne le contenu de cette commande à une variable et qu’on fait une boucle dessus :

a=’grep die *.php | grep die | grep -v « // » | grep -v « /* » | grep -v « */ » |
cut -f 1 -d « : »‘

On commence par verifier qu’on a le bon resultat escompter avec un echo, histoire de ne pas effacer n’importe quoi : for i in $a; do echo $i; done

une fois que c’est bon : for i in $a; do rm -f $i; done

sinon ca passait bien aussi avec un find :-)

Allez, une autre, on reformat un CSV :

le contenu original du fichier ORIGINAL.CSV :

toto:1:2222:toto is a star:20
titi:2:2222:bruno en str:4
tititt:2:2222:bruno en str:4
tutu:3:1122:denis b:8
tata:4:1112:thibault loves printers:12
tata2:4:1112:thibault loves printers:12
tata42:4:1112:thibault loves printers:12

on veut le sortir avec des séparateur qui soit des ; et pas des : et seuls les champs 1 et 5 nous intéressent et seul les tata* et titi* nous sont utiles :

Avec awk :
cat ORIGINAL.CSV | awk -F « : » ‘{ print $1 « ; »  $5 }’ | grep t[ai]t[ai] > FINAL.CSV

Pareil, mais avec cut :
cat ORIGINAL.CSV | cut -d: -f 1,5 –output-delimiter « ; » | grep t[ai]t[ai] > FINAL.CSV

Redémarrer apache et mysql en une ligne en ignorant l’affichage normal et d’erreur (pas conseillé), mais au moins en ne démarrant mysql que si apache s’est bien lancé :

{ /etc/init.d/apache restart && /etc/init.d/mysql restart ; } > /dev/null 2>&1

écrit par Philippe Humeau \\ tags: ,

déc 30

Allez, fin d’année, on se fait quand même un post pour relater deux évènements non négligeables en matière de sécurité, à savoir deux failles de sécurité. Il en sort régulièrement, sur tout un tas d’applications, alors je ne cite que ces deux là mais beaucoup d’autres mériterai le droit de citation également.

Mes camarades de NBS System ont repéré une faille de D.O.S sur Magento qui est en cour de traitement chez Varien et qui ne sera donc rendu publique que lorsqu’elle sera patchée. Nous allons ici nous intéresser à Os commerce et Memcached.

Faille OS-commerce

Pour ceux qui tournent encore en OS-commerce, Milworm reporte une méchante faille de sécurité sur le célèbre framework. L’auteur (Flyh4t) propose un exploit effectif sur les version 2.2 RC2a au moins. Il est probable que d’autres versions soient vulnérables. Ca date du 31/08 mais bon, vu la vitesse à laquelle se patch le parc Français quand il y a une vulnérabilité… (cf la vulnérabilité sur le DNS de Kaminsky ou on a encore 8% du parc en non patché). Plus d’info ici.

Faille Memcached

On continue en musique avec un bon gros trou de sécurité qui fait mal, sur Memcached. Alors là, c’est plus critique car nombreuses, très nombreuses, sont les plateformes qui utilisent Memcached, sur Magento comme ailleurs, ce système de cache est populaire.

Et pan le memcached :  http://www.securityfocus.com/bid/35989

C’est goutu, frais, long en bouche et fruité, mais non ce n’est pas un bourgogne, c’est memcached qui a un bon overflow… Wahouuu le pire du pire, l’overflow et pas qu’un seul. La faille date du 7/08 à l’origine mais elle a été mise en jour le 14/12 pour être beaucoup plus générique.

Ça ne touche cependant « officiellement » que les distribution Linux suivantes (à ce jour) : les suze, redhat, parus, mandrake et danga. En général, un overflow dans un code en C, ce n’est pas fondamentalement lié à la distribution mais plus au code que la distribution a compilé pour son usage. Cela signifie globalement que le code source de memcached est susceptible de contenir des overflows et donc qu’avoir son propre système au dessus pour protéger votre infrastructure, ca ne fera pas de mal.

Les personnes sérieuses en infogérance installent GRsec & Pax quand ils mettent des serveurs Linux en visibilité sur Internet, notamment parceque PHP contient pas mal d’overflow et que tout démon est susceptible d’en connaitre, comme une fois de plus le montre cette faille de Memcached.

Grsecurity, l’anti Overflow

Je ne serai donc trop vous recommander d’utiliser GRsec sur vos environnement de production puisque c’est la seule façon de se protéger à 99% contre les heap & stack overflow, off by one et autres « boundary check errors ».

Rappelons que quelqu’un qui réussit une attaque par overflow va prendre le contrôle de la zone d’exécution  du programme ainsi que ses droits pour ouvrir un shell à distance. Une fois cela fait, même si le démon tournait en www-user ou avec un autre utilisateur non privilégié, l’escalade vers le compte root prend 90% du temps moins de 5 minutes. Les overflows sont donc l’une des plus grande menace possible sur un système si ce n’est la plus grande puisqu’ils mènent quasi tout le temps à une compromission totale du serveur.

Pour ceux qui découvrent GRsec : vous pouvez voir un (très) vieux howto que j’avais écris il y a 5 ans ici mais qui vous expliquera déjà au moins la base. Sinon le site de Grsecurity.net vous donnera de l’info aussi.

Sincèrement, exposer un serveur linux sur le net sans le protéger contre les overflows c’est un peu comme aller se faire une partie échangiste « thaïlando-congolaise » sans capote, disons qu’il existe un risque…

écrit par Philippe Humeau \\ tags: , ,

déc 11

Un ennemi à part !


Le problème est, ma foi, assez simple :

En sécurité informatique, on sait de nos jours parer à la grande majorité des menaces. Si on se concentre sur la partie serveur et sur Linux, Grsex / Pax, un coup de hardening, un kernel statique et optimisé, du chroot et ma foi on est déjà pas mal…

Les démons comme apaches et Mysql, ainsi que les interprêteurs comme PHP ou Perl, sont protégés contre leurs ennemis intimes : les overflows. Les droits séparés, les arborescences protégées, les connexions filtrées, que peut on faire de plus ? Par exemple séparer le back office sur un autre vhost pour ajouter un htaccess afin de le protéger, auditer le site contre les vulnérabilités classiques, XSS, SQL injection etc…

Well… Que reste t’il, un ou deux mécanismes à protéger mais… Le D.D.O.S, c’est fatal.

Know your ennemy !


La D.D.O.S – Distributed Denial Of Services – c’est la grande frayeur de n’importe quel E-commerçant, de n’importe quel site gagnant de l’argent en ligne et surtout, de votre infogérant…

Un déni de service distribué consiste à envoyer des milliers, des dizaines de milliers, des centaines de milliers de requêtes simultanément. Si l’on limite la réflexion aux sites Web, il suffit, en général, de faire 10 à 50 000 connexions simultanées pour mettre à genou un serveur et/ou la connexion Internet des serveurs.

Ces innombrables connexions arrivent, en général, depuis des machines compromises, de partout dans le monde. Ces machines sont compromises par des vers, par exemple Confliker ou d’autres plus discrets, qui sommeillent dans des PC depuis des mois, à l’écoute des ordres. Ces machines, appelées Zombies, font partie de réseaux nommés Botnets.

Ensuite, c’est malheureusement d’une simplicité diabolique. Un script kiddy (ou même un vrai hacker) paye quelques poignées de dollars et loue tout simplement la puissance d’un botnet. Combien de machines, combien de temps, quelles commandes doit être lancée. Simple, terriblement efficace, imparable…

Les machines reçoivent les ordres et en quelques minutes, des centaines milliers de connexions pleuvent sur le site ciblé.

Comment éviter une D.D.O.S ?


Une D.D.O.S se base, pas essence, sur des machines compromises, la plupart du temps des bêtes PC de particuliers.

Evidemment, nous ne pouvons avoir une action sur ces machines directement. Les désinfecter à distance n’est pas possible, pas plus que cela ne serait autorisé du reste.

Ensuite, bloquer ces machines une par une dans un firewall est aussi inutile qu’impossible. Impossible à cause du volume, inutile car bloquer ces connexions n’empêchera pas le pirate d’en envoyer d’autres, d’en envoyer plus et de toute façon, si ce ne sont pas les serveurs qui craquent, ca sera la connexion Internet des serveurs.

Damned, we are done ?

Non. Plutôt que d’étudier le problème sous l’angle de ce qu’on ne peut pas faire, voyons plutôt ce que nos assaillants ne peuvent pas faire :

Il n’est pas possible pour le pirate de réellement patcher le noyau des machines Windows compromises. Si un ver se comportait de cette façon, il serait beaucoup moins efficace (capté par des anti virus) et beaucoup moins portable (selon les versions de Windows). Donc, les vers tournent en général au dessus, dans la couche logicielle. Résultat, ils sont obligés de faire ce que la couche du dessous demande…

Et c’est là que ce situe la faille de ces attaques, de ces vers. Si l’on arrive à forcer les machines à arrêter d’envoyer des paquets en utilisant une subtilité du protocole TCP, le driver de la carte réseau sera obligé d’agir et cet ensemble est lui directement au niveau noyau, donc prioritaire sur la couche logicielle :)

Voila un début solution semble t’il…

Tarpit : du goudron et des plumes !

Règle number one du Blog : plus c’est long, moins c’est lu… Je vais donc faire court et je ne vais pas non plus vous expliquer comment paramétrer un noyau linux et le compiler, de même pour le binaire iptables. Vous trouverez le noyau ici : ftp.kernel.org et pas mal de guide de survie en googlant.

Sinon j’en ai écris un il y a longtemps, mais ca devrait vous aider, ca se trouve ici. il y a des choses tout à fait dépassées, des choses inexactes dans les exemples de firewall mais je n’ai pas eu le temps de le corriger. Ceci étant, vous pouvez partir de là. vous aurez besoin de  recompiler aussi le binaire iptables en passant par la patch-o-matic, tout est expliqué ici.

Mais pourquoi Iptables et Tarpit sont nos amis ?

La règle TARPIT, et il existe d’autres moyens de faire cela évidemment, permet d’informer nos gentils PC zombies qu’ils sont priés d’attendre qu’on les recontacte avant de nous envoyer le prochain paquet réseau. Les machines Windows, comme la plupart des OS récents du reste, respecte le « window resizing ».

Quand on règle la fenêtre (window) de communication à une taille de zéro, la machine distante reste dans un état d’attente, jusqu’à ce que l’on remette une taille normale à la window TCP.

Mais que se passe t’il si l’on ne remet jamais la fenêtre à une taille normale ? Eh bien la machine reste en attente… Et c’est là que la solution se situe. La connexion se bloquera jusqu’à ce que l’OS fasse le ménage dans ses connexions inertes !

Ca peut prendre du temps… pas mal de temps en fait, quand bien même notre machine distante s’acharnerait en refaisant une connexion, à chaque nouvelle tentative, elle bloquera un peu plus sa propre « stack tcp », son propre système de gestion du réseau… Ca va prendre un peu de temps mais ca va bien ralentir l’attaque, d’autant plus que la plupart des machines ne réessayeront pas puisque la connexion n’est pas morte, elle est juste « en pause ».

Comment et à qui appliquer le Tarpit ?

Simplement en 1° scotchant la connexion attaquante 2° en dropant le paquet pour ne pas nous encombrer inutilement. Histoire de faire simple, on va se créer une règle qui fait ca en une fois.

iptables -N TARPIT_DROP
iptables -A TARPIT_DROP  -j TARPIT
iptables -A TARPIT_DROP  -j DROP

Ok mais si on fait un tarpit de tout le trafic entrant avec un iptables -I INPUT -P TARPIT_DROP ou la même chose en FORWARD, on va perdre tout le trafic entrant, y compris les vrais clients du site… C’est peut être un peu désagréable pour les personnes qui n’y sont pour rien.

Afin de trier le bon grain de l’ivraie, il va nous falloir être plus malin que les « bots », les zombies, qui nous attaquent. Il est possible de faire un peu de trie avec des IDS comme Snort par exemple ou sinon d’analyser les logs et les requêtes, ou encore même le rythme des connexions.

Quand on y réfléchit, il est assez simple de reconnaitre un bot car il fait toujours la même chose en général (par exemple un get /blabla.php) et/ou utilise une fréquence précise (par exemple toutes les 5 secondes).

Si l’on utilise un IDS, c’est lui qui pilotera les règles de firewalling (flex rules) directement quand il détecte un comportement anormal. Si l’on souhaite utiliser un parser de logs, il est très simple de lui donner la « pattern » de l’attaque (par exemple un get /blabla.php toutes les 5 secondes) et d’interdire toutes les machines utilisant cette pattern.

Si c’est une page spécifique qui est visée (blabla.php par exemple) il est aussi possible de détecter dans le contenu du paquet (sauf en https) le mot blabla et d’interdire, en fait de tarpiter les machines l’appelant. Certes, les personnes appelant réellement pour de bonnes raisons la page blabla vont être déçues, mais les autres vont être bloquées aussi. Si ca a lieu sur la homepage, cette méthode n’est pas applicable, mais sinon :

iptables -I INPUT -p tcp -s 0.0.0.0/0 –dport 80 -m string –string « blabla » –j TARPIT

Il nous reste d’autres possibilités, avec les mod geoip par exemple ou encore en tarpitant les connexions entrantes qui sont des réseaux similaires (49.230.xxx.xxx par exemple)

Il est possible de limiter en fonction du nombre de paquets et du type de paquets reçus par secondes. Iptables en fait est une usine à idées sans limite. Les attaques peuvent prendre plusieurs formes mais la réponse peut aussi être assez polymorphe à sa manière avec Iptables !

-m limit –limit 2/second –dport 80 –syn -j ACCEPT

Utiliser un mélange subtile des parameters limit et burst-limit peut permettre d’enrayer les flots de paquets réseau trop « soutenu ».

Mélanger subtilement –string pour identifier le contenu et –limit pour le rythme, –state pour l’état de la connexion et d’autres tests, cela peut aussi permettre des résultats intéressants en terme de détection :

iptables -I INPUT -p tcp –dport 80 –m string –string “blabla” –m limit –limit 1/6s –limit-burst 1 –m recent –name DDOSbot –set
iptables –I INPUT FORWARD -p tcp –dport 80 -m recent –name badguy –set -j TARPIT_DROP

iptables –I INPUT -m state –state NEW –m limit –limit 1/6s –limit-burst 1-j TARPIT_DROP

Là par contre, on a beaucoup limité les personnes qui sont tarpitées, en fait à celle faisant une nouvelle connexion plus souvent que toutes les 6 secondes ou si elles appellent la chaine blabla à la même fréquence. Encore une variante ?

iptables -I INPUT -m state –state NEW -m recent –update –seconds 20 –hitcount 4 -j DROP

iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j RETURN
Le parametre “Syn cookie” dans le noyau permet aussi de s’assurer qu’un petit malin ne nous flood pas à coup de SYN uniquement car s’il ne donne pas suite à sa connexion, elle ne sera pas maintenue, c’est un élément de protection indispensable. Et si notre assaillant est très « vieux jeu » et votre réseau très vétuste, qu’il utilise un ping flood, iptables -A INPUT -p icmp -m limit --limit  1/s --limit-burst 1 -j ACCEPT, devrait limiter se velléités. 
Si vous vous passez d’un IDS, vous aurez à analyser vous-même l’attaque, sa méthode et sa forme afin de déterminer la méthode la plus adaptée pour y répondre.  
L’analyse est un point vital et Tarpit une réponse fatale. 

More fun with Tarpit ?

Bon soyons clairs, on peut aller plus loin dans le fun.

Par exemple une personne qui scanne les machines va utiliser un scanner qui va soit utiliser des séquences TCP connues (SYN scan, Xmas Scan etc..) ou même un enchainement de ports, linéaire (1,2,3 etc…), spécifique croissant (21,22,23,25,80 par exemple) ou aléatoire (443,22,53,80,21 par exemple).

Dans tous ces cas, on peut utiliser un démon comme knocked par exemple, un démon de port knocking, pour identifier une séquence de scan. Une fois qu’on l’a identifié, le port knocker est censé ouvrir la connexion pour la personne qui a fait la bonne séquence. Faisons l’inverse puisque c’est un pirate, interdisons lui l’accès et au passage tarpitons le un petit coup…

Le plus drôle c’est qu’on va maintenir son IP en Tarpit et donc provoquer une connexion bloquée par port scanné et là… assez rapidement… sa machine va sévèrement bloquer du coté réseau :)

Alors, au final, Tarpit, c’est fun non ? Il existe de nombreuses autres options que vous pourrez trouver dans le kernel ou dans la patch-o-matic, toutes peuvent donner lieu à des mélanges très utiles.

écrit par Philippe Humeau

déc 01

Problématique


Les grandes marques sont de plus en plus présentes sur Internet par l’entremise de leurs sites web marchands. Ces marques sont capables de générer des trafics colossaux sur une journée, tout particulièrement pendant des périodes particulières comme les soldes.

De plus, les grands rendez vous sont souvent les mêmes pour les sites de E-commerce ce qui fait que tous consomment beaucoup de ressources en même temps.

Les trois grands types de ressources consommées pendant ces pics de charge sont les suivants : réseau (bande passante), processeur, RAM.

Que faire lors de ces soldes, lors de ces pics et surtout pour ces grandes marques ?

Passer de 100 000 Visiteurs uniques par jour à 500 000 relève du possible pour ces grands compte. En contrepartie, passer de 3 serveurs frontaux à 15, juste pour des pics temporaires, semble couteux et peu pertinent dans le long terme, sans compter le gachis de ressources.

Le Cloud (computing)


Le cloud computing est une solution technique qui permet l’usage de ressources de type CPU / RAM, Bande passante « au compteur ». Vous payez ce que vous consommer. Il y a un coût rémanent pour l’hébergement de fichiers sur le Cloud mais il est très réduit.

Cette solution de payement à la ressource réellement consommée est donc un moyen très adapté de ne mettre en place des ressources que quand cela est nécessaire et de ne facturer que ce qui est consommer.

Plusieurs Cloud existent, Amazon S3, Rackspace etc…

Du simple C.D.N à l’infrastructure


Le C.D.N veut dire Content Distribution Network. En résumé, les données statiques, images, films, css, html simple peuvent vous être fournit depuis un lieu proche de vous plutôt que depuis l’autre coté de l’océan. Ceci améliore la rapidité de chargement mais également déleste les serveurs centraux en les allégeant du travail « idiot » de distribution de fichiers.

La première utilisation des Clouds a été ce CDN, les pionniers du décentralisé étant par exemple Akamaï. Mais de nos jours, les ténors comme Amazon ou Google ont rationalisé des infrastructures beaucoup plus vastes et complexes que ce qui avait été conçu jusque là. Ils ont mis en place des systèmes spécifiques, allant parfois même jusqu’à faire développer leur propre hardware.

Une fois la puissance rationalisée et déployable à loisir, il est devenu simple pour ces ténors de « revendre » leur capacité d’accueil. Nous sommes alors passé du simple CDN à de la capacité d’accueil réelle avec, notamment, l’ajout de systèmes de base de donnée.

E.T.C (*) : Extend to Cloud, le cloud pour Magento


Chez NBS System, on a dû très tôt trouver des solutions à ce problème. Les grands comptes étant de plus en plus nombreux à basculer sous Magento et il était indispensable de proposer une solution rationnelle pour les accueillir.

Les éléments étant réunis, le projet E.T.C : Extend To Cloud était lancé. Une discussion avec Yoav Kutner, pas mal de test et de R&D et voici E.T.C.

Le concept est, dans le principe, simple. Au moment où un site monte en volume de trafic, on instancie des parcelles du cloud pour accueillir une partie du trafic qui « déborde » de la capacité d’accueil physique, réelle. Si l’infrastructure physique permet d’accueillir 100 000 Visiteurs uniques par jour, l’E.T.C permet de multiplier par 4 à 5 cette capacité d’accueil.

Une fois les tests menés et les systèmes de déploiement / rétractation au point, il devient possible d’automatiser également la mise en place d’une extension vers
le Cloud (ETC) quand cela est nécessaire.

Conclusion


Évidemment, présenté comme cela, E.T.C c’est assez simple.

En pratique il existe pas mal de contraintes et de tests à mener. Les outils pour être complètement « élastique » sont assez technique à réaliser. Pour être francs, la R&D est « un peu » coriace mais le résultat est à la hauteur du boulot fournit !

Une capacité unique d’accueil, sans multiplier les serveurs à l’infini, mais qui peut, de manière élastique, s’auto dimensionner pour répondre à des très fortes charges temporaires. Bien évidemment il y a un coût de setup assez minime et ensuite subsiste uniquement un coût d’usage qui est très très nettement plus intéressant que le fait de multiplier les serveurs ;)

L’offre est disponible dès ce mois de décembre  2009.

(*) E.T.C (Extend To Cloud) est une marque et une technologie NBS System.

écrit par Philippe Humeau

juin 12

Introduction

Donne une commande unix à un développeur, il corrigera son problème. Apprend lui à utiliser l’essentiel, tu diviseras par deux ton support niveau 1.

Vous aurez probablement reconnus la sagesse originale : « Donne un poisson à un homme il aura a manger un jour, apprends lui à pêcher, il aura à manger toute sa vie ».

Eh bien je pense que pour les commandes unix de base, c’est pareil. En plus bash et ses copains peuvent vous faire gagner un temps incroyable sur certains traitements. Le but de cet article est donc de présenter quelques commandes très utiles, quelques petits outils et des exemples pragmatiques réutilisables ou adaptables facilement.

Je ne pense pas faire de vous des administrateurs (car ce n’est pas votre but) mais seulement vous faire gagner du temps. Tous les développeurs n’ont pas forcément une affinité naturelle avec unix mais tous seront d’accord pour gagner du temps en général.

Lire la suite »

écrit par Philippe Humeau \\ tags: , ,

mai 22

Introduction


Cet article est le premier d’une série de 3 sur la configuration d’un infrastructure Magento complète, comprenant pour l’exemple un serveur qui sera Firewall/Reverse proxy/Load Balancer, deux autres qui seront des Serveur Web frontaux et un quatrième qui sera en charge de la base de données.

Plan des posts

1/3 : Configuration du firewall, du load balancer et du Rproxy
2/3 : Configuration des serveurs Web (APC / Apache / PHP)
3/3 : Configuration de la base de données (Mysql)

Le setup de l’infrastructure Magento

archi de baseInternet, routeurs et hop, on tombe sur quoi ?

Le Firewall, reverse proxy, load balancer.

Le premier élément réellement intelligent et puissant sur lequel on va pouvoir travailler, le premier serveur quoi. Parfois l’élément Firewall est séparé et repose sur une appliance en amont mais dans le principe, si vous faites dans le full opensource, vous aimez netfilter et donc le firewall de Linux.

C’est par ailleurs un excellent Firewall, je vais donc l’intégrer à ce petit tuto et même démarrer par là !

Pour cet exemple et le paramétrage des fichiers de configuration, le firewall/RP/LB est en 192.168.1.1, les serveurs Web sont en 192.168.1.2 et .3 et la DB est en 192.168.1.4 et le magasin « virtuel » s’appel www.demostore.fr.

Enfin, cote ip publique, j’ai utilisé 33.44.55.66 comme étant celle de demostore.fr et 88.77.111.222 comme étant celle des admins. Vous trouverez ces paramètres dans les fichiers de configuration du firewall, du reverse proxy et du load balancer, il faudra les modifier pour vos besoins.




Points non couverts dans ces 3 articles

Je vais me la jouer un peu à la Ruquier, donc ce soir, on ne recevra pas, euh pardon, dans cette série de 3 articles, on ne verra pas :

  • Comment faire de la redondance mutli datacenter avec BGP et les synchros de sites & de DB
  • Comment séparer les flux de bases de données en écriture & lecture sur deux DB
  • Comment faire du Master/Master Master/Slave ou du Cluster en Mysql
  • Comment isoler le backoffice en terme de performances sur les serveurs frontaux
  • Comment isoler le backoffice en terme d’accès aux bases de données

On ne verra pas tout cela car :
D’une part parce que cela serait très long et très complexe à expliquer et que les compétences nécessaires pour faire le tour du sujet sont très vastes. D’autre part parce que ca va déjà faire un bon volume à rédiger et donc que ca va prendre du temps. Et enfin parce que ces points sont très critiques sur le terrain commercial et qu’ils sont actuellement des avantages en faveur de ma société vis à vis de ses concurrents.

Vu que la concurrence dans le milieu de l’infogérance Magento est assez active, ma société NBS System ne peux pas se permettre de révéler ses tous derniers tricks ou ses toutes dernières optimisations pour l’infogérance ou l’hébergemnt de Magento, mais ce qui sera décrit dans les 5 articles correspond à ce que nous utilisions fin décembre 2008, donc des configurations tout à fait décentes et efficaces.

En plus mes collègues bossent en ce moment même avec Zend pour faire un papier très complet sur les performances et l’optimisation avec ZAS (Zend Application Server), je ne vais donc pas dévoiler de secrets avant la publication officielle au Bargento 2.

Préambule sur GRSEC/PAX

Autre point, c’est peu décrit dans cet article mais plus dans un autre dont je donne le lien et aussi sur le net : GRSEC + PAX c’est l’assurance vie de vos serveurs. Ce n’est pas une option : c’est un pré-requis. Grsec/Pax impose de recompiler le kernel, tache un peu complexe quand on a pas l’habitude mais le couple vous protège à 99,999% contre tous les overflow, les off by one et autres cochonneries de ce genre. Que ce soit apache, mysql, php, squid, memcached, apc etc… tous ces applicatifs peuvent avoir un jour une faille de sécurité. Grsec c’est l’assurance que même si ca se produit (et ca se produira), vos serveurs ne seront pas compromis.

Le Firewall


Configuration simple

J’ai réalisé, il y a (très) longtemps de cela, un petit tutoriel pour prendre Iptables & Netfilter en main. Il est incomplet, très vieux, contient des erreurs ou des abbérations que je n’ai pas eu le temps de corriger dans les scripts mais les explications et schémas sont corrects. Vous remarquerez au passage ma maîtrise considérable dans la création de page Web, celle-ci à faillit avoir de nombreuses récompenses pour l’utilisation audacieuse des CSS, mais finalement le jury a préféré un autre site (curieusement).

Ceci étant, ce que l’on souhaite faire ici est assez simple :
- Interdire tout par défaut (comme tout firewall décent)
- Authoriser spécifiquement les connexions d’administration depuis nos IP
- Permettre d’accéder directement aux serveurs derrière également depuis nos IP

Attention, il existe de très nombreux tricks à mettre en place pour avoir le top du top, dans le /proc/sys/net/ipv4, afin d’ajouter des règles anti DOS, d’ajuster la stack IP pour la gestion des connexions demi ouvertes, gérer la réduction des timeouts, et puis aussi par des règles pour loger les attaques, ajouter des systèmes de sondes/IDS etc…

C’est un firewall assez basique que je vais exposer ici. Pour de très fortes charges, il faudra également vérifier les capacités de NAT de la machine qui repose sur un système de buckets, lui même calculé en fonction de la RAM de la machine. Il faudra également redonder la machine, etc… (Mais avant que vous en soyez là, vous pourrez largement vous payer les services de personnes qui voient très bien de quoi je parles)

Préparation du Kernel :

  1. On télécharge les patchs de GRSEC ici, ici (et en option le patch pour iptables ici)
  2. On télécharge le kernel qui va avec la version de grsec ici
  3. On détar/dézip les archives et on applique les patchs (bzip2 -d kernel*; tar xvf grsec*;patch -p0 < gr*.patch)
  4. On ajoute deux ou trois tools qui risque de manquer : install libncurses-dev ncurses-dev make gcc paxtest gradm2 chpax
  5. On configure le kernel (make menuconfig), voici l’ultra minimum :
    - Pas de support des modules, tout en statique (ca évite l’insertion de backdoor)
    - networking/networking options/netfilter/ip:netfilter configuration/activer la majorité des options
    - Security options / Grsec: activez tout sauf dans kernel auditing juste les relocations et forks, dans Pax mettez tout.

C’est une config ultra minimaliste. Pour plus d’info de nombreux sites parle de la compilation du noyau, le howto iptables est un peu plus précis aussi mais c’est trop long à expliquer pour avoir une place ici. Après, de nombreuses petites ou grands optimisations peuvent être effectuées au niveau du noyau, les résultats, du coté performances, comme du coté sécurité s’en ressentiront. Disons que si vous avez correctement configuré votre kernel avec pax et grsec, normalement les autres options par défaut sont rarement débiles.

Pour le firewall à proprement parler, on va faire simple dans un premier temps :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/bin/bash
# short, simple, incomplete, not really commented iptables script for Debianed firewalls/rproxy/load balancers by Philippe Humeau (c) 2009 NBS System, lord Rusty forgive me, amen
 
IPTABLES="/sbin/iptables" 
 
case "$1" in
start) 
 
date=`date +'%b %d %k:%M:%S'`
ADMIN_IP="88.77.111.222" # &lt;-------------- Change me !
SERVERS_IP="192.168.1.0/24"
SERVERS_WEB1="192.168.1.2"
SERVERS_WEB2="192.168.1.3"
SERVERS_DB="192.168.1.4"
INET="eth0"
SERVERS="eth1"
 
echo "$date -- Starting Firewall --" &gt;&gt; /var/log/kern.log
 
echo -e "-&gt; \033[40m\033[1;31mSetting Default Policies to DROP \033[0m &lt;-"
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP 
 
echo -e "-&gt; \033[40m\033[1;33mFlushing all rules &amp; tables \033[0m &lt;-"
$IPTABLES -F
$IPTABLES -X
$IPTABLES -Z
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -t nat -F
$IPTABLES -t nat -Z
$IPTABLES -t nat -X
$IPTABLES -N LOG_DROP
$IPTABLES -A LOG_DROP -m limit --limit 6/h --limit-burst 1 -j LOG --log-tcp-options --log-prefix 'Dropped: '
$IPTABLES -A LOG_DROP -j DROP
$IPTABLES -N syn-flood
$IPTABLES -A syn-flood -m limit --limit 10/s --limit-burst 10 -j RETURN
$IPTABLES -A syn-flood -j DROP 
 
echo -e "-&gt; \033[40m\033[1;34m Set kernel networking tweaks \033[0m &lt;-"
echo 0 &gt; /proc/sys/net/ipv4/ip_forward
echo 1 &gt; /proc/sys/net/ipv4/ip_dynaddr
echo 0 &gt; /proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 &gt; /proc/sys/net/ipv4/tcp_timestamps
echo 1 &gt; /proc/sys/net/ipv4/tcp_syncookies
echo 0 &gt; /proc/sys/net/ipv4/conf/all/accept_redirects
echo 2 &gt; /proc/sys/net/ipv4/conf/all/rp_filter
echo 1 &gt; /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo 16384 &gt; /proc/sys/net/ipv4/ip_conntrack_max
echo 1 &gt; /proc/sys/net/ipv4/conf/all/log_martians
echo 30 &gt; /proc/sys/net/ipv4/tcp_fin_timeout
echo 2400 &gt; /proc/sys/net/ipv4/tcp_keepalive_time
echo 0 &gt; /proc/sys/kernel/printk
echo 1800 &gt; /proc/sys/net/ipv4/tcp_keepalive_time
echo 0 &gt; /proc/sys/net/ipv4/tcp_window_scaling
echo 0 &gt; /proc/sys/net/ipv4/tcp_sack
echo 64 &gt; /proc/sys/net/ipv4/ip_default_ttl
echo 2048 &gt; /proc/sys/net/ipv4/ip_queue_maxlen
echo 1 &gt; /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo 1 &gt; /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 1 &gt; /proc/sys/net/ipv4/tcp_ecn
 
echo -e "-&gt; \033[40m\033[1;33m INPUT RULING \033[0m &lt;-"
$IPTABLES -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -i $INET -s $ADMIN_IP -j ACCEPT
$IPTABLES -A INPUT -i $SERVERS -p tcp --dport 11211 -j ACCEPT # memcached
$IPTABLES -A INPUT -i $SERVERS -s $SERVERS_IP -j ACCEPT        # accept très (trop) générique pour les requêtes des serveurs au rp/lb/fw
$IPTABLES -A INPUT -p ICMP -i SERVERS -s $SERVERS_IP -j ACCEPT
$IPTABLES -A INPUT -p ICMP -i lo -j ACCEPT
$IPTABLES -A INPUT -i $INET -s $SERVERS_IP -m limit --limit 3/m -j LOG_DROP # "Spoofed packet: "
$IPTABLES -A INPUT -f -m limit --limit 3/m --limit-burst 1 -j LOG_DROP # "Frag packet: "
$IPTABLES -A INPUT -i $INET -p icmp -m limit --limit 12/hour --limit-burst 1 -j LOG --log-prefix "ICMP: "
$IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 3/m --limit-burst 2 -j LOG_DROP # "SSH loggin attempt"
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth XMAS scan"
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m limit --limit 3/m --limit-burst 5 -j LOG_DROP --log-prefix "Stealth XMAS-PSH scan"
$IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth XMAS-ALL scan"
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth FIN scan"
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth SYN/RST scan"
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth SYN/FIN scan(?)"
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -m limit --limit 3/m --limit-burst 5 -j LOG_DROP # "Stealth Null scan"
$IPTABLES -A INPUT -p tcp --dport 0 -m limit --limit 6/h --limit-burst 1 -j LOG_DROP # "Port 0 OS fingerprint"
$IPTABLES -A INPUT -p udp --dport 0 -m limit --limit 6/h --limit-burst 1 -j LOG_DROP # "UDP port 0 OS fingerprint"
$IPTABLES -A INPUT -p tcp --sport 0 -m limit --limit 6/h --limit-burst 5 -j LOG_DROP # "TCP source port 0"
$IPTABLES -A INPUT -p udp --sport 0 -m limit --limit 6/h --limit-burst 5 -j LOG_DRop # "UDP source port 0"
$IPTABLES -A INPUT -p tcp -m multiport --sports 20,21,22,23,80,110,143,443,993,995 -m limit --limit 6/h --limit-burst 1 -j LOG_DROP # "Napta/smurfing/Drd/Dos"
$IPTABLES -A INPUT -i $INET -p tcp ! --syn -m state --state NEW -j DROP # "drop TCP connexion wich doesn't start by a syn"
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -i $INET -p tcp --syn -j syn-flood 
 
echo -e "-&gt; \033[40m\033[1;32m FORWARD RULING \033[0m &lt;-"
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $INET -o $SERVERS --dport 80 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i $INET -o $SERVERS --dport 443 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 20 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 21 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 22 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 25 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 80 -p tcp -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -o $INET -i $SERVERS --dport 443 -p tcp -m state --state NEW -j ACCEPT 
 
echo -e "-&gt; \033[40m\033[1;32m OUTPUT RULING \033[0m &lt;-"
$IPTABLES -A OUTPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p ICMP -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 20 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 21 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 22 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 25 -j ACCEPT
$IPTABLES -A OUTPUT -p UDP --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 80 -j ACCEPT
$IPTABLES -A OUTPUT -p UDP --dport 123 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 123 -j ACCEPT
$IPTABLES -A OUTPUT -p TCP --dport 443 -j ACCEPT
 
echo -e "-&gt; \033[40m\033[1;33m Masquerading \033[0m &lt;-"
$IPTABLES -t nat -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$IPTABLES -t nat -A POSTROUTING -i -o $INET -j MASQUERADE
 
echo -e "-&gt; \033[40m\033[1;32m Firewall Setup complete, activating Forward \033[0m &lt;-"
echo 1 &gt; /proc/sys/net/ipv4/ip_forward 
 
echo -e "------------------------&gt; \033[40m\033[1;32mEOF : End of Firewall \033[0m&lt;-----------------------"
;; 
 
stop)
echo -e "\033[40m\033[1;31m----------------------&gt; Shutting down Firewall ! &lt;----------------------\033[0m"
echo " "
IPTABLES="/sbin/iptables"
$IPTABLES -F
$IPTABLES -X
$IPTABLES -Z
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -t nat -F
$IPTABLES -t nat -Z
$IPTABLES -t nat -X
echo 0 &gt; /proc/sys/net/ipv4/ip_forward
echo "-&gt; DONE ! &lt;-"
;;
 
*)
echo "Usage: /etc/init.d/firewall {start|stop}"
exit 1
;;
 
esac
exit 0


Quelques points :
- N’oubliez pas de durcir tous vos noyaux de serveurs, tout spécialement celui-ci, avec le patch GRSEC pour le kernel Linux. (ca doit aussi être décrit dans le howto de mémoire).

- Si on veut être plus méchant, au lieu de DROP on peut utiliser TARPIT si on a compilé iptables avec, ca fait un bel effet sur la machine attaquante !

- Si le scipt ne charge pas c’est que j’ai fais un faute de frappe quelque part, corrigez là :-) Si il ne charge pas parcequ’il manque des target, ajoutez les dans le noyau au moment de sa compilation.

Le Reverse Proxy


Introduction

Le Firewall est une fonction en soit est très peu consommatrice car, sur un noyau linux, c’est embarqué. Netfilter et son application de pilotage iptables sont des outils très puissants et très économes.

Dans le cas qui nous préoccupe, c’est d’autant plus vrai qu’on va filtrer très peu de chose, ce n’est pas non plus le firewall du pentagone, on va juste protéger les accès d’administration. Sur notre beau serveur, on a dépensé 0,000001% de la capacité CPU, que faire du reste ?

Hummmmm du folding@home, du calcul de Pi, un serveur Quake 3, du Seti project : non !

On va faire un reverse proxy et un load balancer qui eux peuvent commencer à occuper un peu la machine sur ses 99,999999 % de temps CPU restant.

Le reverse proxy, c’est une histoire un peu plus complexe. Si on part sur une solution simple, Squid est très capable. Pour de la dentelle, qui nécessite aussi une optimisation du code pour en tirer le plein partit, Varnish est une solution plus costaud mais réellement plus longue à mettre en place. On va donc ici s’atteler à concevoir un Squid correcte.

Rôle

Le rôle du reverse proxy c’est ca :
rp stats

Réduire les accès aux serveurs Web en les allégeants de tout ce qui n’a pas de valeur ajouté, tout ce qui n’est pas généré. J’ai pris volontairement une page très lourde pour la démonstration.

En l’occurence on va cacher :

  • Le HTML
  • Les CSS
  • Les images
  • Les fichiers Javascript

et forcément, le serveur Web, ca lui fait du bien. En résumé, il se concentre sur les requêtes Ajax et le PHP, il laisse les transferts « de base » au Rproxy. Evidemment, un tour de magie de ce type, ca consomme un maximum en RAM car il faut tout stocker en RAM pour aller vite. Si on doit charger chaque éléments depuis le disque dur, c’est plutôt lent. Un bon reverse proxy a donc beaucoup de RAM et un processeur correct, sans plus puisque la charge processeur est faible.

Au final, même si l’exemple ici, un peu exagéré, montre un gain de 97%, on gagne quand même en général au minimum 75% de trafic en moins vers le ou les serveurs Web. Donc qu’on ait un serveur Web ou plusieurs, le reverse proxy est in-dis-pen-sable.

Une autre optimisation intelligente sur ce point est à faire au niveau du code. Un fichier JS, un fichier CSS et pas des millions, ca change des choses. Du coup, concaténer tout cela intelligemment, c’est un plus non négligeable. Un gars s’est pris la tête à faire le boulot pour vous et encore mieux, il en a fait un plugin Magento, que demande le peuple ? Au fait ca s’appel Fooman speedster module et, depuis l’invention de la fénéantise, c’est un des outils les plus indispensable pour optimiser sans se fatiguer.

Installation de Squid

Vous êtes des gens biens, vous avez une Debian.

Vous pouvez aussi être des gens bien et ne pas avoir de Debian mais dans ce cas vous savez installer une tarball ou un package. Il y a même des gens bien qui travaillent avec OpenBSD par exemple, ils ont toute ma considération mais je ne ferai pas de howto pour ;) (Il n’y a plus de gens bien sous HPUX rassurez moi ?)

Le coté « à la main », je sais faire aussi mais, personnellement, j’adore APT et DPKG :)

Attention, on se concentre, installer Squid ce n’est pas simple sous debian :

~> su (on passe root car on est jamais loggé en root par défaut)
~> apt-get install squid

Ok on respire, on a fait le plus dur. Un petit café pour se récompenser s’impose, bravo, vous avez bien bossé ! (merci aux gars de Gnu aussi). Ca c’est fait, Squid est installé, on souffle, on respire, c’était dur mais la vie est dure parfois.

Configuration de squid en reverse proxy Magento

Phase 2, on essaye de faire croire aux patrons qu’on est payé à faire quelque chose de balaise et incompréhensible, qui mérite probablement une augmentation énorme mais qu’on va se contenter de 10% et une voiture de fonction : on édite le fichier de configuration.

Bon Squid c’est un proxy et un reverse proxy. En gros ca permet dans un cas comme dans l’autre de gérer un cache pour que les fichiers régulièrement demandés soient dans un cache rapide, mémoire de préférence, plutot que redemandés voir ré interprétés par le serveurs Web. Ca allège énormément les serveurs dans le cas du reverse proxy. Le proxy cache les réponses des serveurs Web aux browsers http pour les acheminer au client sans les redemander. Le reverse proxy lui fait l’inverse (d’où le reverse), il stocke les réponses les plus souvent envoyées par le serveurs aux clients afin de servir ceux-ci sans demander quoique ce soit aux serveurs Web.

Bref Squid c’est complexe, énorme, un fichier de conf de base ca fait dans les 7000 lignes avec les commentaires, je vous livre donc ici une version expurgée des commentaires, juste préparer pour du reverse proxy et dont toutes les fonctions ne sont pas activées, juste les principales. Encore une précision, quand vous utilisez un reverse proxy, n’oubliez pas que votre serveur Web ne verra plus toutes les requêtes… Eh oui, c’est bien le but d’ailleurs. Donc ce qui est intercepté doit être minutieusement loggé pour pouvoir avoir des stats et compléter celles des serveurs Web sous Apache.

Allez, voici la configuration :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# Squid sooooo basic configuration for Magento, by Philippe Humeau &amp; Adrien Urban (c) 2009 NBS System
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80		# http
acl Safe_ports port 443		# https
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
icp_access deny all
htcp_access deny all
 
http_port 192.168.1.1:80 transparent name=proxy_int_IP
http_port 33.44.55.66:80 transparent name=ip_demostore
hierarchy_stoplist cgi-bin ?
 
cache_mem 6144 MB
maximum_object_size_in_memory 8 MB
memory_replacement_policy heap lfuda
cache_dir null /tmp
 
 
access_log /var/log/squid3/access.log squid
access_log /var/log/squid3/access-apache.log combined
refresh_pattern (cgi-bin|\?)	0	0%	0
refresh_pattern .		0	20%	4320
icp_port 3130
 
acl localhost src 127.0.0.1/8
acl localnet src 192.168.1.0/24
 
acl debianUpdate dstdomain ftp.fr.debian.org              # pour les updates Debian
acl debianUpdate dstdomain security.debian.org          # pour les updates Debian
acl dstOutAllowed dstdomain ws.mperf.com                # pour le mailing, remplacer mailperf par votre fournisseur
acl dstOutAllowed dstdomain chart.apis.google.com      # pour les beaux graphs à la google style
acl dstOutAllowed dstdomain www.magentocommerce.com     # devinez
acl dstOutAllowed dstdomain connect.magentocommerce.com # devinez v2.0
acl dstOutAllowed dstdomain pear.php.net                           # devinez v3.0
acl dstOutAllowed dstdomain schemas.xmlsoap.org                # pour les wsdl, soaperie et autres webservices
 
http_access allow localnet debianUpdate
http_access allow localnet dstOutAllowed
 
acl IpInternal myportname proxy_int_IP
acl IpExternal myportname ip_demostore
acl dstdemostore dstdomain www.demostore.fr
acl dstdemostore dstdomain demostore.fr
never_direct allow dstdemostore
 
# demostore
cache_peer 192.168.1.2 parent 80 0 no-query round-robin sourcehash
cache_peer 192.168.1.3 parent 80 0 no-query round-robin sourcehash
cache_peer_access 192.168.1.2 allow dstdemostore
cache_peer_access 192.168.1.3 allow dstdemostore
 
cache_peer_access 192.168.1.2 deny all
cache_peer_access 192.168.1.3 deny all
 
http_access allow dstdemostore
 
http_access deny all
 
access_log /var/log/squid3/demostore-squid.log squid demostore
access_log /var/log/squid3/demostore-apache.log combined demostore

Dans cet exemple, votre serveur dispose de 8 Go de Ram et on en prend 6 pour le cache de squid. C’est évidemment à ajuster en fonction de votre configuration. (cache_mem 6144 MB) On a aussi une taille maximal de fichier à 8 Mo pour cacher les gros objets et on interdit le cache sur disque pour ne pas gréver les performances. On a paramétré le service Squid pour gérer www.demostore.fr et demostore.fr et donné l’accès aux serveurs vers d’autres hosts comme Magento connect ou les updates de Debian.

Le load balancer

Bonne nouvelle : c’est déjà fait !

Eh oui en donnant deux peers vous avez dit à Squid qu’il avait deux serveurs Web dont il devait s’occuper. Vous pourriez vouloir donner un poids différent (ici dans l’exemple c’est du 50/50) si vous avez des serveurs de puissance différentes. Il faudra alors ajouter Weight comme directive dans la déclaration des peers.

Le piège serait de faire du load balancing IP. Netfilter sait le faire, c’est même assez simple à mettre en oeuvre et pour tout vous dire c’est ce qu’on faisait à NBS System avant. Mais cela posait des problèmes quand le client arrivait d’une IP qui changeait en cour de session (gros firewall corporate qui nat par une autre connexion ou même simplement une adsl en ip variable). Du coup il vaut mieux passer par cette solution qui est plus propre.

Memcached


Introduction

Nous y voila, la fin de l’aventure Firewall / Load Balancer / Reverse Proxy est proche…

Si je finis par ce point c’est aussi parce que c’est le plus facile quelque part.

On peut mettre memcached un peu partout dans l’infrastructure, sur le proxy, sur les serveurs Web ou même sur les serveurs de base de données. L’idée c’est de garder les sessions des surfers non pas en fichiers mais en mémoire. D’un point de vue performance, c’est très préférable et c’est simple à réaliser alors pourquoi s’en passer…

Installation

On peut le mettre dans plusieurs endroit ce fameux memcached mais je préconise un serveur qui est unique et accédé / accessible par tous comme la base de données (si on a qu’un serveur de DB) ou le reverse proxy mais, si possible, pas sur les serveurs Web. En effet si l’un tombe, autant que l’autre puisse bosser et reprendre ses sessions. Evidemment, il vaut mieux que le dit serveur soit redondant ou bien costaud pour ne pas tomber sinon c’est toutes les sessions qu’on perd mais vu que le site tombera avec, ca sera un moindre problème :)

Oui, je sais, toujours un peu douleureuse cette phase sous Debian :
~> su (on passe root car on est plus loggé en root, normal)
~> apt-get install memcached php5-memcached

Allez, ca va aller, c’est finit… On respire lentement, le rythme cardiaque redescend !

Configuration

Dans le fichier local.xml de Magento, vous devriez pouvoir ajouter :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<global>
  <cache>
    <backend>memcached</backend>
    <memcached>
      <compression/>
      <cache_dir/>
      <hashed_directory_level/>
      <hashed_directory_umask/>
          <file_name_prefix/>
          <servers>
             <default>
              <host>192.168.1.1</host>
              <port>11211</port>
             <persistent>1</persistent>
           </default>
          </servers>
      </memcached>
  </cache>
<session_save><![CDATA[memcache]]></session_save>
<session_save_path><![CDATA[tcp://192.168.1.1:11211?persistent=1]]></session_save_path>
</global>

On peut aussi mettre memcached en dehors de Magento et de sa configuration, tout simplement en installant le démon avec une configuration dans le /etc/memcached.conf :

1
2
3
4
5
6
7
# memcached ultra simplistic config file by philippe Humeau (c) 2009 NBS System
-d
logfile /var/log/memcached.log
-m 1024
-p 11211 
-u nobody
-l 192.168.1.1


Conclusion


  1. Vous méritez un café après tout ce travail
  2. Je mérite un café après ce travail de rédaction
  3. Il est incompréhensible que les producteurs de café soient pauvres
  4. La personne qui monte un site Magento entièrement dédié au café, il va se faire du blé

Oui… Je sais… J’ai toujours un petit soucis sur les conclusions mais bon, vous commencez à être habitués depuis le temps et puis je me soigne.

Prochain exercice de style, l’article 2/3 : Configuration d’un serveur Web pour Magento !

PS : N’oubliez pas de vous inscrire pour Bargento 2, il reste encore quelques places et après on est complet, ce qui implique que même en arrivant à l’improviste sur place, on ne pourra pas vous faire rentrer pour rester dans les capacités d’accueil de la salle.

De plus, le papier sur Zend Application Server et les performances de Magento devrait apporter un jour nouveau et pas mal de complément sur ce mini tuto / howto.

Par manque de temps, je n’ai pas eu le temps de tout tester sur un serveur donc si il y a des boulettes dans les fichiers de configuration, n’hésitez pas à me les signaler, je modifierai l’article.

écrit par Philippe Humeau \\ tags: , , , , , , , ,

fév 25

La méthode est un peu « rustre », très système et réseau et pas réellement dans les méthodes des développeurs mais parfois, elle peut faire gagner un temps phénoménale…

Mais de quoi il parle…?

Appliquer une modification dans des pages de code. Par exemple remplacer un mot par un autre ou même appliquer le patch de Gabriel contre les XSS de Magento super rapidement dans tout le code de Magento. Si si c’est possible, Adrien (un collègue en charge des infrastructures Magento), nous offre un peu de ligne de commande qui colle aux dents mais qui rend bien service. Bon, vous avez besoin d’un shell sous unix avec des droits décents et quelques utilitaires qui sont installés par défaut sous presque tous les BSD et Linux. (Avec la remise en forme du texte par WordPress, je ne sais pas si ca se copie/collera correctement, mais voici les synthaxes, les quotes ‘ vont probablement mal passer en CTRL C/CTRL V)

find /var/www/htdocs -type f -print0 | xargs -r -0 sed SED_EXPRESSION

On va chercher avec la commande « find » dans le répertoire qui nous intéresse (ici /var/www/htdocs), les fichers uniquement et envoyer tout cela à « sed ». Pour ceux qui ne sont pas familier de la ligne de commande unix et de bash en général, c’est un peu abstrait, ca fait peut mais c’est pas bien méchant.  (pour les connaisseurs, on pourrait aussi utiliser –exec) Il faut découper :

find /var/www/htdocs -type f -print0

touve moi tous les fichiers dans le répertoire /var/www/htdocs et ses sous directory et affiche le résultat.

| (prononcer païpe, comme un tuyau en anglais)

et passe le résultat de tes recherches (donc la liste de tous les fichiers) à  :

xargs -r -0

qui est un programme qui reformatte les lignes de commandes (en l’occurence pour son copain sed)

sed SED_EXPRESSION

et lance sed avec l’expression qui va bien, sans effectuer les modifications (il faut ajouter -i pour cela)

Justement… L’expression. C’est là que se situe la magie de ces syntaxes de barbares. Car avec la bonne expression, on va appliquer un traitement à tous les fichiers !!! Si on trouve l’expression cherché, on va la remplacer par une autre, c’est ca le boulot de sed. On cherche et on remplace avec ce que l’on appel une Regexp (pour régular expression), c’est une grammaire descriptive pour décrire une chaine de caractère. Je n’ai pas réellement le temps de vous l’expliquer en détail, googlez un peu et vous trouverez.

Allez, on applique le patch de Gabriel à tout ce qui ressemble de prêt ou de loin à un retour d’erreur non filtrée.

si on cherche ça : « <?php echo $* ?> » et qu’on veut le remplacer par ça : « <?php echo htmlentities($*) ?>« 

l’expression c’est ça : ‘s/<?php echo $\([a-zA-Z0-9_]\+\) ?>/<?php echo htmlentities($\1) ?>/g’
(et on ne touche pas à *, en gros au nom de la variable)

donc sed 's/<?php echo $\([a-zA-Z0-9_]\+\) ?>/<?php echo htmlentities($\1) ?>/g' ou si on réinsère ca dans notre recherche avec find :

find /var/www/htdocs -type f -print0 | xargs -r -0 sed ‘s/<?php echo $\([a-zA-Z0-9_]\+\) ?>/<?php echo htmlentities($\1) ?>/g’

Le petit inconvénient, c’est que la synthaxe est stricte, à l’espace pret. Donc si c’est écrit différemment à deux endroits du code, ca ne remplacera pas tout. Deuxième chose, si le paramètre remplacé est un tableau ou une fonction, la synthaxe sera peut être différente. Pour ne pas avoir de doute, on peut utiliser ou grep -ro pour vérifier avant que tout est bon, ceci affichera ce qui va être traiter avant de faire quoique ce soit :

grep -hro ‘<?php echo $\([a-zA-Z0-9_]\+\) ?>’ /var/www/htdocs

Pour le cas de l’url du downloader (le XSS en GET pas beau) voici la synthaxe sed :

find /var/www/htdocs -type f -print0 | xargs -r -0 sed ‘s/\$this->set(‘return_url’, \$_GET[[]‘return’[]])/\$this->set(‘return_url’, htmlentities(\$_GET['return']));/

Et vous savez quoi ?

L’inconvénient, c’est que le patch de Gabriel est efficace mais il n’est pas persistent (lorsque vous mettrez à jour Magento, les correctifs vont sauter alors que Varien n’aura peut être pas patché les vulnérabilité.

Le deuxième défaut, c’est que seul 3 failles ont été révélées, si ca se trouve, il en existe d’autres.

La bonne nouvelle c’est que la méthode de bourrin proposée, elle ne fait pas de quartier. Elle trouve, elle remplace que ce soit sur les fichiers et failles identifié ou non. Elle vous remplacera donc potentiellement aussi des failles non encore dévoilées ;)

Deuxième avantage, si vous montez de version, vous pouvez relancer la même commande, elle refera le boulot sans que vous ayez à éditer quoique ce soit. Vu le rythme de publication des versions de Magento, ca peut être confortable.

Merci à Adrien pour les regexp ;)

écrit par Philippe Humeau \\ tags: