tcpdump : Géolocaliser

On a maintenant :

  • Une table TBIPPORT qui contient toutes les tentatives de connexions, dont les IP
  • Une table TBIPCOUNTRY vide.

Il faut la remplir au fur et à mesure de la venue de nouvelles IP et renseigner les champs COUNTRYCODE et COUNTRYLIB.

Géolocaliser sous-entant, interroger un service web pour chaque ip : ce peut-être un processus long donc on ne va pas intégrer cette fonctionnalité au service. Mais on va utiliser un nouveau script qui sera lancé régulièrement en crontab.

1ère étape : compléter au fur et à mesure la liste des IP uniques ayant chercher à étable un contact avec notre serveur.

Il faut réaliser un INSERT des IP qu’on n’a pas encore. Et il faut qu’aucune IP ne soit doublé (par le champs IP est uné clé primaire). Ce code doit pouvoir être relancé de manière identique à chaque passage du traitement, même si on a déjà certaines IP.

En SQL c’est très simple à faire : un INSERT par SELECT avec un jointure gauche et un GROUP BY

INSERT INTO MYTCPSTAT.TBIPCOUNTRY (IP) 
SELECT A.IP FROM MYTCPSTAT.TBIPPORT AS A 
LEFT JOIN MYTCPSTAT.TBIPCOUNTRY AS B ON A.IP=B.IP 
WHERE B.IP IS NULL 
GROUP BY A.IP;

2ième étape : identifier les cas : IP locales ou externes ?

Maintenant que TBIPCOUNTRY contient toutes les IP, il faut les géolocaliser. Deux cas sont possibles :

  • soit on a affaire à une IP externe (publique) : et on la géolocalisera
  • soit on a affaire à une IP sur le réseau locale et on ne pourra pas la géolocaliser. Pour celles-ci je vais considérer que leur pays est le même que celui de l’IP publique du serveur.

Donc d’abord je vais trouver l’IP publique de mon serveur , il existe de nombreuses façons de la faire, en voici une :

ippublic=$(curl ipinfo.io/ip)
echo $ippublic
77.206.127.130

Je dois savoir maintenant si les IP contenues dans TBIPCOUNTY sont locales ou externes. Il y a bien une définition stricte, mais j’ai décider de ne pas me prendre la tête : j’ai choisis de prendre celles dont les 2 &ers chiffres sont les mêmes que l’adresse locale de chaque interface.

Donc il faut faut l’adresse locale de chacune des interfaces actives dans ma base de données, pour cela :

  1. on décharge le contenu de la table TBIFACE là ou ACTIF=’Y’ dans un fichier
  2. on lit se fichier ligne à ligne et pour chaque interface, on interroge ifconfig pour obtenir l’ip locale
  3. et stocker tout cela dans un nouveau fichier en y ajoutant (parce que c’est facile à ce niveau), le début de l’ip (A.B. pour A.B.C.D)
rm -f /tmp/listeifacetcpstat.txt
sql="SELECT IFACE FROM MYTCPSTAT.TBIFACE WHERE ACTIF='Y' INTO OUTFILE '/tmp/listeifacetcpstat.txt'"
mysql --user="$mysqluser" --password="$mysqlpass" -e "$sql"

Lecture ligne à ligne

touch /tmp/listeifacetcpstatlocal.txt
while IFS="|" read myiface
do
   iplocal=$(ifconfig "$myiface" | grep -m1 inet | awk '{printf $2}')
   ret=$?
   if [ $ret -eq 0 ]; then
      sublocal=$(echo $iplocal | cut -d. -f1-2)
      echo "$myiface""|""$iplocal""|""$sublocal""." >> /tmp/listeifacetcpstatlocal.txt
  fi
done < /tmp/listeifacetcpstat.txt

/tmp/listeifacetcpstat.txt contient 3 colonnes et séparées par un pipe (|) et autant de ligne que d’interfaces, ces 3 colonnes sont :

  • nom de l’interface (ex : eth0 ou enp2s0)
  • sont ip locale (192.168.20.254 par exemple)
  • le début de l’ip locale (ici 192.168) : “sublocal”

Pour chaque IP de TBIPCOUNTRY, si elle commence par “sublocal” alors je dit que c’est un ip locale et je mettrai le même Pays que celui de l’ip publique de mon serveur

3ième étape : géolocaliser son propre serveur :

Ca peut paraître idiot, mais si j’installe le même service sur un serveur à l’étranger, ça m’évitera d’oublier un paramétrage. Et puis c’est un bon exercice pour la suite.

Donc pour ça, on a besoin de geoiplookup qui s’installe partout, très simplement

si ippublic contient mon ip public, voici l’ordre à exécuter :

mycountry=$(geoiplookup $ippublic)
echo $mycountry

On obtient donc en sortie : un libellé et une valeur, séparés par “:” ==> on va utiliser cut avec délimiteur “:”

La valeur contient un espace, le code pays, une virgule, un espace et le nom de pays ==> on va utiliser cut avec délimiteur, mais comme il y a aussi des espaces, on va ajouter xargs pour s’en débarrasser :

mycountry=$(geoiplookup $ippublic|cut -d: -f2 | xargs)
echo $mycountry
FR, France

mycountrycode=$(echo $mycountry | cut -d, -f1 | xargs)
echo $mycountrycode
FR

mycountrylib=$(echo $mycountry | cut -d, -f2 | xargs)
echo $mycountrylib
France

Il faut penser aussi à ce qui se passe si geoiplookup ne trouve pas :

geoiplookup 193.169.252.69| cut -d: -f2 | xargs
IP Address not found

Donc si on tombe là-dessus, il ne faudra pas chercher à mettre à jour notre table.

4ième étape : mettre le pays pour les ip locales

Donc si l’IP est locale, je mets le Pays de l’ip publique de mon serveur. L’ip locale va dépendre de l’interface que je traite donc je fais ce traitement pour chaque ligne de /tmp/listeifacetcpstatlocal.txt.

Pour trouver les ip qui commence par xxxx, on fait WHERE IP LIKE ‘xxxx%’ (le %  final est impératif !)

while IFS="|" read myiface myip mysub
do
   sql="UPDATE MYTCPSTAT.TBIPCOUNTRY SET COUNTRYCODE='""$mycountrycode""', COUNTRYLIB='""$mycountrylib""' WHERE IP LIKE '""$mysub""%';"
   mysql --login-path=local -e "$sql"
done < /tmp/listeifacetcpstatlocal.txt

Ca y est, mes IP locales sont géolocaliser, je n’ai plus qu’à m’occuper des autres : celles que je n’ai pas encore géolocalisé (donc celles dont COUNTRYCODE est NULL)

5ième étape : mettre le pays pour les ip externes

On va mettre dans un fichier, toutes les IP de TBIPCPOUNTRY pour lesquelles COUNTRYCODE est NULL

  rm -f /tmp/listeifacetcpstatexterne.txt
  sql="SELECT IP FROM MYTCPSTAT.TBIPCOUNTRY WHERE COUNTRYCODE IS NULL INTO OUTFILE '/tmp/listeifacetcpstatexterne.txt'"
  mysql --login-path=local -e "$sql"
  ret=$?
  if [ $ret -ne 0 ]; then
	  echo "Pb ""$sql"
	  exit 99
  fi

On va lire ce fichier ligne à ligne, géolocaliser chaque IP pour mettre à jour les champs de TBIPCOUNTRY COUNTRYCODE et COUNTRYLIB

while iFS= read myip
do
   mycountry=$(geoiplookup $myip |cut -d: -f2 | xargs)
   ret=$?
   notfound=$(echo "$mycountry" | grep -i " not ")	  
   if [ $ret -eq 0 -a "$notfound" == "" ]; then 
      mycountrycode=$(echo $mycountry | cut -d, -f1 | xargs)
      mycountrylib=$(echo $mycountry | cut -d, -f2 | xargs)
      sql="UPDATE MYTCPSTAT.TBIPCOUNTRY SET COUNTRYCODE='""$mycountrycode""', COUNTRYLIB='""$mycountrylib""' WHERE IP='""$myip""';"
      mysql --login-path=local -e "$sql"
   fi
done < /tmp/listeifacetcpstatexterne.txt

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.