まこと の ブログ

MaKoTo no burogu — Journal de bord…

Aller au contenu | Aller au menu | Aller à la recherche

informatique › Auto-Hébergement internet

Votre site perso, votre blog, vos mails, etc... tout çà chez vous, çà c'est internet !
Sinon vous faites du minitel 2.0

Historique de mon expérience sur un petit serveur web perso

Fil des billets - Fil des commentaires

lundi, 25 février 2013

Dotclear et le spam des commentaires

Le spam des commentaires est malheureusement une chose inévitable lorsque le blog commence à être bien référencé.

  • Les filtres de l'extension « Antispam » de dotclear sont assez efficaces, pour le peu qu'on enregistre suffisamment de mots clés dans le filtre : Bad Words, Liste de termes interdits.

C'est simple, il suffit d'entrer les termes anglais les plus usités, genre : That (80% de positif !) , quartz, hello, you, etc
Le seul inconvénient étant de chopper aussi les commentaires pertinents dont l'auteur aura voulu utiliser un anglicisme.

  • Au départ les spam étaient peu nombreux, pas un problème donc.

Puis de temps en temps un « chinois »[1] passait par ici et écrivait 500 fois le même commentaire toutes les 30 secondes, depuis la même IP.
Facile à bloquer avec une règle IP table du type :

iptables -I INPUT -s xxx.xxx.xxx.xxx -j DROP

Jusque là, ça reste gentillet, les filtres font leurs taf, on trie les faux-positifs, ça se gère tranquillement sans perte de temps (quelques vingtaines par semaines).
Puis ça se corse !

  • Ces mêmes « chinois » reviennent mieux armés, dans le sens où cette fois, après un ban iptables, ils reviennent avec une IP différentes, mais faisant partie de la même plage.

Un simple commande whois sur cette IP donne la plage dédiée au spammeur, et hop, un iptables manuel sur la plage… Oui c'est pas bien, mais ça défoule ^^; D'autant plus que d'autres viennent avec des plages différentes, et avec les contenu de spam et les fausse adresses mail utilisées on se doute que ce sont les mêmes gus.

iptables -I INPUT -p tcp --dport 80 -m iprange --src-range xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx -j DROP

Au bout de quelques ban manuel on finit par avoir la paix… Sauf que !
On se rend alors compte que ces salopiots ont cochés la case mise à disposition par le plugin dotclear bien pratique pour le visiteur humain, subscribeToComments 1.4-alpha1 servant à s'abonner au commentaire pour être prévenu par e-mail d'une réponse à ce commentaire.
Et là, c'est une autre affaire, car on se retrouve avec des tonnes d'abonnements bidons dans la page de gestion du plugin, et presqu'autant de mailer-daemon témoignant de l'échec d'envoi des e-mails de notifications… vu que les spammeurs rempilent derrière leurs propres spam, alors même qu'il se sont vu filtrés par le filtre Antispam et que donc leurs spam ne sont pas publiés.

  • Depuis quelques temps ces « chinois » me laissent tranquille, mais une nouvelle sorte de spammeur à débarqué… Les Zombies !

Vu la nature de ces spams, j'imagine qu'il s'agit de PC Windaube infectés de virus spammeur qui partagent une base de données avec mon IP publique dedans !
En effet, contrairement aux «chinois », ces spams débarquent du monde entier, avec des contenus plus ou moins du même genre, et des adresses e-mail dans un style différent et plus élaborées. Impossible ici de s'amuser à bannir les IP à la main avec dans les 60 spams par jours, ni à chopper les plages IP, car cette fois on est susceptible de réellement bloquer des visiteurs légitimes !
Ho, les filtres Antispam de dotclear font toujours bien le travail, mais il devient pénible de trier à la main les faux-positif et de nettoyer les abonnement aux commentaires… De fait et a regret, j'ai donc dû prendre la décision de désactiver subscribeToComments rendant le suivit des commentaires inexistant pour les visiteurs.
Voyous de publicitaires $#ø%@'&€…



Il est donc temps d'étudier une solution automatique pour bannir ces IP malignes.

Ça m'entrainera à écrire du script… L'idée ici est donc la suivante,

Toutes les 12 heures :

- Pour les 12 dernières heures écoulées, faire une requête sur la base de donnée de dotclear pour lister toutes les adresses IP des commentaires marqués indésirable par l'Antispam.
- Virer les doublons (car oui, ils reviennent, soit dans les minutes, soit les jours suivants)
- Bannir toutes les IP de cette liste avec iptables.
- Écrire un fichier de log horodaté.
- Envoyer le fichier de log par e-mail.

#!/bin/bash
 
###################################################
# BANNIR LES SPAMMEURS des commentaires DOTCLEAR #
# À programmer dans crontab toutes les 12h ################
###################################################
# ——————————— #
# Initilisation des variables #
# ——————————— #
 
login=utilisateur				# Le nom d'utilisateur ayant les droits sur la base de donnée.
password=motdepasse		# Le mot de passe associé.
base=blog					# Le nom de la base de donnée.
table=dc_comment			# La table des commentaires.
champ1=comment_spam_filter	# Le champ des commentaires marqués comme filtrés.
champ2=comment_ip			# Le champ de l'IP.
champ3=comment_dt			# Le champ de la date et heure.
condition=dcFilter% 			# Le filtre pour ne conserver que les lignes dont le champ1 commence par : dcFilter.
depuis=$(date -d "12 hour ago" "+%F %T") # La date moins 12 heures.
requete1="SELECT $champ1,$champ2,$champ3 FROM $base.$table WHERE $champ1 LIKE 'dcFilter%' AND $champ3 BETWEEN '$depuis' AND now()"
 
# ———— #
# Fonctions #
# ———— #
 
bannir () {					# Bannir l'adresse IP contenue dans la variable: ip2.
iptables -I INPUT -s $ip2 -j DROP
}
 
# ————————————————————— #
# Requête MYSQL pour réccupérer les IP à bannir #
# ————————————————————— #
 
# mysql -uutilisateur -pmotdepasse -e "SELECT comment_spam_filter,comment_ip,comment_dt FROM blog.dc_comment WHERE comment_spam_filter LIKE 'dcFilter%' AND comment_dt BETWEEN '2013-02-08 20:01:30' AND now()";
 
mysql -u$login -p$password -e "$requete1" | while read spamfilter ip date		# Lire la requête mysql ligne par ligne et récupérer les valeurs de chaque champs pour les affecter respectivement aux variables: spamfilter ip date.
						do
							if [ "$ip" = "comment_ip" ]; then		# Si la variable: ip, contient le mot: comment_ip, Alors.
								echo "comment_ip" > /dev/null	# L'envoyer au trou noir !
							else								# Sinon,
								echo  "$ip"					# Appeler successivement la valeur de la variable: ip.
							fi
						done | sort -u > /tmp/dc_spam.tmp		# Stocker les ip dans le fichier tmp en supprimant les doublons.
# —————————— #
# Bannir les IP récoltées #
# —————————— #
 
date '+%Y-%m-%d %X' >> /var/log/dc_BannedIP.log			# Écrit la date dans le fichier log: dc_BannedIP.log.
echo -e "\n" >> /var/log/dc_BannedIP.log						# Saute une ligne dans le fichier log: dc_BannedIP.log.
 
if [ -s /tmp/dc_spam.tmp ]; then								# Si le fichier tmp n'est pas vide.
	while read ip2										# Lire le fichier: tmp, ligne par ligne.
	do
		echo "$ip2"                  								# Appeler successivement la valeur de la variable: ip2.
		bannir   	 	                     							# Appeler la fonction: bannir.
	done < /tmp/dc_spam.tmp >> /var/log/dc_BannedIP.log		# Ajouter la liste des IP que l'on vient de bannir dans le fichier log: dc_BannedIP.log
	echo -e "———————————————————" >> /var/log/dc_BannedIP.log	# Écrit une ligne horizontale dans le fichier log: dc_BannedIP.log.
else
	echo "aucune IP à bannir" >> /var/log/dc_BannedIP.log		# Sinon, ne rien faire.
	echo -e "———————————————————" >> /var/log/dc_BannedIP.log	# Écrit une ligne horizontale dans le fichier log: dc_BannedIP.log.
fi
 
# ————————————— #
# Envoie d'un email avec le log #
# ————————————— #
 
mutt -s "IP Bannies pour Dotclear" admin@mondomaine.org -a /var/log/dc_BannedIP.log < /root/scripts/emailmessage.txt

Note

[1] le whois indique des IP depuis la Chine…

vendredi, 1 février 2013

interruption de service -3-

 Retour de mes sites après quelques jours off-line !!

En effet un problème de connectiques pourries a impacté depuis mardi midi la moitié des résidents de mon immeuble.

Pour les lecteurs hors « planète auto-hébergement » qui ne le saurait pas, cela fait trois ans maintenant que j'auto-héberge mes services internet.
Depuis lors, je n'ai eu à déplorer que deux coupures de longue durée, l'une de 1 journée car mon disjoncteur EDF avait sauté et la présente de 3 jours, due au câblage du FAI.

D'autres soucis mineurs lié à l'administration du serveur sont survenu en trois ans, notamment apache qui saturait la mémoire du serveur, et plantait la machine, un simple reboot du serveur suffisant à faire repartir la disponibilités de mes pages, et depuis ce problème est résolu en activant le multi-threading php.
Mais j'ai envie de dire que ce genre de panne surviendrait tout autant avec un hébergement payant et centralisé, donc ça compte pas :D

jeudi, 2 février 2012

Du bon usage de la sauvegarde de donnée -3- LiveBox2 n'est PAS un vrai routeur !

livebox.png Pour faire suite au billet précédent sur la sauvegarde de donnée à distance, avec mise en marche de l'ordinateur sur demande, voici la mise en pratique sur le site de sauvegarde.
Concernant le Wake On Lan, chez moi, les tests en local et via internet s'étaient bien passés…
Mais chez Orange c'est une toute autre affaire que je m'en vais vous conter de suite !

Pour les pressés, conclusion avant l'heure : WOL avec le FAI Orange (LiveBox2 sagem) et routeur Linksys DD-WRT (port forwarding) est impossible !

Tout aurait dû se dérouler tranquillement…

J'ai pourtant procédé exactement de la même manière que précédemment, mais pas moyen… impossible d'allumer ce satané ordi…
Il se trouve que ce bel outil qu'est Wireshark, m'indiquait que le paquet magique n'était simplement pas dirigé vers la bonne machine sur le réseau local… Port Unreachable.

  • J'indiquais bel et bien à la LiveBox2 de rediriger les paquets en provenance des ports 7-9 vers l'IP du routeur Linksys DD-WRT, et à ce dernier de rediriger ces paquets vers l'IP de l'ordi que je souhaitais réveiller… Mais rien… Paquets perdu dans la nature…

Lire la suite...

mardi, 27 décembre 2011

Apache2 en mode multi-thread

Depuis déjà 6 mois, comme cela s'était déjà produit, mon serveur plante de temps à autre…
Le démon Apache2 devient fou et déclenche les foudres d'anon, le killer de démon, qui vise à libérer de l'espace mémoire Ram+Swap, mais la Machine est à ce point submergée que rien n'y fait, il est impossible de prendre la main et le disque dur gratte comme un fou, jusqu'à ce qu'on veuille bien lui administrer les magic syst key (SEIUB)

En fait mon serveur s'est retrouvé non pas victime de son succès, mais de la coïncidence de plusieurs événements simultanés :
. scan par les robots de divers moteurs de recherche
+ scan de divers planet
+ consultation de visiteurs de mes deux sites
+ mon propre usage de TinyTinyRSS
= Autant de démon Apache2 qui se lancent que de requêtes html, php5, etc.

Bref, le temps de cerner le coupable et comprendre le problème, j'ai enfin décidé de tenter quelque chose… Apache2 en mode multi-thread

Il m'avait bien semblé voir passer un billet au titre intéressant, et en fouillant les tréfonds de ce cher TinyTinyRSS j'ai pu le retrouver et le mettre en œuvre !

Très clair, on y explique ce qui semble être la solution à mon problème, et la méthode fonctionne très bien !
Maintenant il y a très peu de lourd démon Apache2 et beaucoup de léger démon php.
On peut aussi vérifier la config en créant la fameuse page phpinfo.

Mais ayant eu quelques soucis avec ma config, je vais préciser certaines choses :

  • En premier lieux, si vous utilisez un accès https pour lire votre Webmail ou votre TinyTinyRSS, vous risquez de tomber sur une erreur de type :
ERROR : Wrong 'suhosin.session.encrypt' option value

Et effectivement, comme pour /etc/php5/cgi/php.ini, la config cgi de suhosin est elle aussi placée ailleurs.
Il faudra alors éditer /etc/php5/cgi/conf.d/suhosin.ini et dé-commenter puis mettre à off la ligne suhosin.session.encrypt

suhosin.session.encrypt = off
  • Seconde chose, l'upload de fichiers de plus de 130 kio au travers de php s'est révélé impossible (via Dotclear, Owncloud…) avec notamment des erreurs 500.

Et ceci alors même que la configuration dans le nouveau fichier /etc/php5/cgi/php.ini était correcte, c'est à dire :

file_uploads= On

ou Off permet d'autoriser ou non l'envoi de fichiers.

upload_max_filesize = 2M

permet de définir la taille maximale autorisée pour le fichier. Si cette limite est dépassée, le serveur enverra un code d'erreur.

post_max_size = 2M

indique la taille maximale des données envoyées par un formulaire. Cette directive prime sur upload_max_filesize, il faut donc s'assurer d'avoir post_max_size supérieure à upload_max_filesize.

En fait, c'est un autre fichier de config qui fixait la limite de 130 kio !
C'est donc /etc/apache2/mods-available/fcgid.conf qu'il faut amender d'une ligne MaxRequestLen

<IfModule mod_fcgid.c>
  AddHandler    fcgid-script .fcgi
  FcgidConnectTimeout 20
  MaxRequestLen 1073741824
</IfModule>

Ici j'ai donc mis 1 Gio, valeur configurée par défaut lorsqu'on utilise Apache2 en mode « pas multi-thread»
Ce qui au passage, explique enfin pourquoi avec Owncloud je ne pouvais pas uploader plus d'1 Gio par fichier ^^

Sources :
- http://www.commentcamarche.net/faq/889-php-upload-de-fichiers#configuration-de-php-pour-permettre-l-upload
- http://blog.philippklaus.de/2011/04/fix-mod_fcgid-http-request-length-xyz-so-far-exceeds-maxrequestlen-131072/
- http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidmaxrequestlen

- page 2 de 8 -