Tuto: Bloquer les requêtes selon le pays

Ca marche toujours mais c’est crade : ça va checker uniquement chez mailfud, qui semble (ou prétend) MaJ avec une granulométrie plus fine.

Bon par contre va peut-être falloir tout recoder pour utiliser GeoIP2 => Retirement of GeoIP Legacy Downloadable Databases in May 2022

Bonjour,

Merci à tous pour vos contributions.
Désolé de ne pas avoir mis à jour plus tôt mais je suis un peu surbooké en ce moment et n’ai pas vraiment de temps à consacrer au forum. J’ai mis à jour le hook, j’en ai profité pour tout fusionner dans celui-ci, ça simplifie le processus avec un seul fichier à créer.

@kit: Oui j’ai vu que GeoIP Legacy était abandonné, il va falloir surveiller s’il faut mettre à jour le hook. Sur mailfud la mise à jour date du 12 juillet, je n’ai pas pris le temps de voir si c’était basé sur la dernière maj de maxmind ou si c’est une conversion des bases GeoIP2 en .dat, ce qui dans ce cas serait toujours compatible avec le hook actuel.
Pourquoi je n’utilise pas le pipe traditionnel? Certainement par habitude avec la forme grep motif fichier . Je crois qu’à la base il y avait une explication un peu plus rationnelle mais ça fait tellement longtemps que je l’utilise que je ne sais plus pourquoi. Pose la question sur un forum spécialisé, tu verras ce qu’on te répond. Si tu as la réponse, partage là.

@Qprq
Merci, nickel!

@Krakinou
Ta proposition est plus propre, mieux vaut vérifier sur chaque site respectif comme tu le proposes.

J’ai eu un retour :

[La version avec < ] est spécifique à bash et donc marchera pas sur les autres shells.
[La version avec | ] est la version en syntaxe POSIX/sh et est donc portable (et marche aussi sur bash, puisque bash est sh-compatible)

Edit : En plus technique : bash - Alternative for |(pipe) operator - Ask Ubuntu

<(..) turns the internal command output’s STDOUT into a file descriptor (that the command, grep in your example) opens. When you pipe, the reading command is reading directly from STDIN (which is being filled with the piped command’s STDOUT). Subtle differences but can be significant with commands that only know how to read STDIN.

Edit :


#!/bin/bash

# A placer dans /etc/cron.weekly/Geoipupdate
# Voir https://forum.yunohost.org/t/tuto-bloquer-les-requetes-selon-le-pays/9947


maj_geoip () {
cd /usr/share/GeoIP
if [ "$v6Test" != "" ]; then
        wget https://dl.miyuru.lk/geoip/maxmind/country/maxmind.dat.gz -O GeoIP.dat.gz #IPv4+IPv6
else
        wget https://mailfud.org/geoip-legacy/GeoIP.dat.gz #IPv4
fi
gunzip -f GeoIP.dat.gz
}

last=/usr/local/etc/last
v6Test=`ip -6 addr | grep 'inet6 [23]'` #Test si le serveur supporte l'IPv6

if [ "$v6Test" != "" ]; then
        update=`curl -s https://www.miyuru.lk/geoiplegacy | grep 'Maxmind : ' | sed -n 's,.*<li>Maxmind : \(.*\)</li>,\1,p'`
else
        update=`curl -s https://mailfud.org/geoip-legacy/ | grep 'Latest update' | sed -n 's,.*<b>\(.*\)</b>,\1,p'`
fi
[[ "$(<$last)" != "$update" ]] && (echo "$update" > "$last";maj_geoip)
exit 0

Pour la dernière ligne je suppose que ça signifie qu’on test si la date présente dans $last est différente à celle de la variable update ? Si oui, je crois que nous sommes condamnés à utiliser les doubles crochets et donc rester sur bash, ou créer une autre variable pour cat le fichier last

Pour la dernière ligne, c’est bien ça. Ce n’est pas bien gênant en fait car bash est le shell par défaut de Debian et yunohost a vocation à ne fonctionner qu’avec Debian. Si jamais l’utilisateur changeait de shell par défaut, le shebang permet de toute façon d’exécuter le hook en bash. Ce cas d’usage doit être rare avec yunohost, et si un utilisateur changeait son shell par défaut, il serait de toute façon suffisamment compétent pour se débrouiller.

H.S.

Merci pour les liens, ça confirme que la forme <(command) est directement reconnue comme fichier. J’ai fini par retrouver pourquoi je privilégie cette commande au pipe, elle est bien plus performante qu’un pipe et l’exécution se fait plus rapidement.

Fin du H.S.

1 Like

Je vois que t’as ajouté l’update des bases de données dans le hook.

J’ai fait un time des versions avec | et avec <, on est dans la marge d’erreur, a fortiori pour un truc lancé une fois par semaine (~0,05 seconde sur mon modeste i3 Nehalem). Avec < on perd en facilité de lecture et en transposabilité dans d’autres shell (cela dit bash doit être pré-installé sur toutes les Debian je pense), mais d’après ton lien on gagne en sobriété sur les child processes.

Je pense que ça pourrait être pas mal de commenter les différentes étapes, notamment la ligne au dessus du exit 0 qui peut être un peu tricky à lire pour un non initié (j’en fais partie), idem pour le test sur la présence d’IPv6. J’aime bien les commentaires dans le code :smiley:

C’est fait, j’ai commenté. D’ailleurs ça m’a permis de trouver des erreurs, la variable update n’était pas définie car je l’avais mise dans la fonction et non en dehors. J’ai apporté également quelques modifications mineures proposées par @Krakinou.
Ça devrait être bon comme ça jusqu’à une éventuelle mise à jour du hook liée à l’abandon de geoIP Legacy.

1 Like

Bien vu pour la variable update !

Pour le test du paquet geoip-database, pourquoi ne pas inclure en début de script un truc du style :

if ! dpkg -s geoip-database >/dev/null 2>&1; then
        echo "Installation du paquet geoip-database"
        apt install geoip-database
fi

Plop

Petite erreur de diag depuis ce matin :

=================================
Services status check (services)
=================================

[WARNING] Configuration is broken for service nginx!
  - nginx: [emerg] invalid number of the geo parameters in /etc/nginx/conf.d/country.conf:16
  - nginx: configuration file /etc/nginx/nginx.conf test failed

Vous avez ça chez vous aussi ?

Non. Je viens de relancer le diagnostic pour voir, je n’ai pas d’erreur.

**nginx version:** nginx/1.14.2

lsb_release -d
Description:	Debian GNU/Linux 10 (buster)

Nevermind, apparemment il y a eu un soucis avec mon update de GeoIP. J’ai regen-conf nginx (avec le hook qui va bien), c’est rentré dans l’ordre.

Correction du hook, j’ai ajouté l’ip de localhost 127.0.0.1 en liste blanche. Sans celle-ci il pouvait y avoir des dysfonctionnements comme les contacts inaccessibles dans snappymail par exemple.

1 Like

Bonjour, désolé de relancer ce topic deux ans après :sweat_smile:

Dans le hook du premier post, ne faut-il pas corriger la ligne ?

map \$geoip_country_code \$allowed_country {
  default no;
  # France
  FR yes;
  # Italie
  #IT yes;
}

en

map \$geoip_country_code \$allowed_country {
  default no;
  # France
  FR yes;
  # Italie
  IT yes;
}

Et j’ai une seconde question, comment peut-on appliquer cette configuration à l’un des noms de domaines uniquement d’une instance Yunohost ?

Merci ! :slight_smile:

Bonjour,

Pour la 1ère question, c’est simplement un exemple. Si c’est commenté, le pays n’est pas débloqué, si c’est décommenté, le pays est autorisé. Donc le script de base n’autorise que la France, dans ta correction, ça autorise France et Italie. C’est ce que je précise juste après le script.

Pour ta 2ème question, ça doit pouvoir se faire en modifiant le script et en mettant le block suivant dans un fichier à part en dehors de security.conf.inc

# allow local ip
if ($lan-ip = yes) {
  set $allowed_country yes;
}
# block the country
if ($allowed_country = no) {
  return 444;
}

Ensuite, ajouter un include du fichier dans le fichier de conf du domaine.

Oui et non, ça dépend si tu veux autoriser l’Italie (si oui, il faut en effet décommenter la ligne).

Pour ta question, regarde du côté du fichier de config Nginx security.conf.inc

De mémoire il faut jouer avec les locations. J’avais noté un truc dans ce goût là :

#blocage sur certaines url uniquement
location ~* /(sso) {
 if ($allowed_country = no) {
  return 444;
 }
}

Edit : Grillé le temps de répondre :slight_smile:

Bonjour,

J’ai essayé la manip’ principale hier soir, pour bloquer les requêtes à l’instance Yunohost et ce matin, pouf, plus d’accès depuis mon téléphone, en wi-fi, en réseau 4G, ni depuis mon ordinateur, internet ou réseau local.

Je suis dans une région qui crie son indépendance, mais je ne crois pas que ce soit au point d’être considéré comme un pays étranger :sweat_smile:

Pour le moment, j’ai supprimé le fichier générant le hook et redémarré afin de retrouver l’accès.

Étant une grosse quiche ne sachant que copier/coller des bouts de codes, je pense ne pas avoir compris la 7eme ligne du script :

#Attention, je ne suis pas certain que cette commande est universelle. Vous devez la tester au préalable. Si ce n'est pas le cas, vous pouvez trouver la réponse avec la commande ip route, celle-ci doit être de la forme 192.168.0.0/24 ou similaire. Remplacez alors la variable $network_address par celle-ci.
network_address=$(awk '{print $1}' <(grep src <(ip route)))

Que dois-je y faire ?

Merci beaucoup !

Que tu donnes cette commande? Et ip route ?
Par contre si c’est ça, ça ne devrait pas bloquer la connexion en 4G.