Filtrage IP automatisé

Msappdem

Nouveau membre
5 Novembre 2022
12
2
8
Bonjour,

J'utilise Unifi OS Server hébergé sur une VM de mon Synology

Tuto ici :

actuellement en version 5.0.6 (Network 10.2.105). Avant j'utilisais une image Docker (linuxserver/unifi-network-application) mais de ce que j'ai compris ce n'est plus supporté.

Je me suis aperçus que je subissais beaucoup de tentative d'intrusion malgré mes petites règles et je suis tombé sur un article de Korben (https://korben.info/data-shield-ipv4-blocklist.html) au sujet de Data-Shield (https://github.com/duggytuxy/Data-Shield_IPv4_Blocklist).
J'aurais bien voulu pouvoir automatiser l'intégration directement dans le routeur, mais ce n'est pas prévu donc j'ai fait plusieurs essaie et j'ai fini par regarder comment fonctionnait l'API.

Je ne sais pas si ça peut servir, mais j'ai fait un petit script (aidé par l'IA) pour mettre à jour mes règles de par feu pour blacklister des adresses ip.

Ce que fait le script :

Le script va télécharger un fichier de référence plein d'adresse IP, va le découper en plusieurs fichiers texte si besoin puis va créer deux règles de filtrage (blocage) nommées : IP Ban 01 - Ext-Gat et IP Ban 01 - Ext-Int
Le chiffre est incrémental en fonction du nombre de fichier.
Le but étant de bloquer une liste d'adresse IP de la zone Externe vers Gateway et Interne.

Prés-requis :
  • Créer une API Key (https://ip: Port/network/default/integrations)
  • Avoir un serveur pour programmer l'execution du script (moi j'ai du Synology)
Limite(s) :
  • Une règle de parfeu est limitée à 10000 entrées
Utilisation :

Le script requiert trois paramètres obligatoires :

Il est également possible de préciser :

Pour lancer le script :

Bash:
script.sh <IP> <PORT> <APIKEY> [<URL_FICHIER> <MAX_LIGNES> <LIMIT>]

Programmation :

Mon script est placé dans un dossier sur le NAS : /NetBackup/NAS/Scripts/ubiquiti_blocklist_ip/ip.sh
puis executé dans une tâche planifiée en tant qu'utilisateur root (mais ça doit fonctionner en tant qu'utilisateur) avec la commande :

Bash:
bash /volume1/NetBackup/NAS/Scripts/ubiquiti_blocklist_ip/ip.sh 192.168.0.10 443 qsdsqdxwcdcqsdqsdsqdsqd

Le script :

Bash:
#!/bin/sh

IP="$1"
PORT="$2"
APIKEY="$3"
IPS="${4:-"https://cdn.jsdelivr.net/gh/duggytuxy/Data-Shield_IPv4_Blocklist@refs/heads/main/prod_critical_data-shield_ipv4_blocklist.txt"}"
IPMAX="${5:-9998}"
LIMIT="${6:-20}"

if [ -z "$IP" ] || [ -z "$PORT" ] || [ -z "$APIKEY" ] || [ -z "$IPS" ] || [ -z "$IPMAX" ] || [ -z "$LIMIT" ]; then
    echo "Usage: $0 <IP> <PORT> <APIKEY> [<URL_FICHIER> <MAX_LIGNES> <LIMIT>]"
    exit 1
fi

echo "Verification de l'acces API..."

INFO_JSON=$(curl -sk "https://$IP:$PORT/proxy/network/integration/v1/info" \
  -H "Accept: application/json" \
  -H "X-API-Key: $APIKEY")

if [ $? -ne 0 ] || [ -z "$INFO_JSON" ]; then
    echo "Erreur : impossible de joindre l'API"
    exit 1
fi

echo "$INFO_JSON" | grep -q "applicationVersion"
if [ $? -ne 0 ]; then
    echo "Erreur : reponse API inattendue"
    exit 1
fi

echo "Connexion API OK"

echo "Recuperation de la liste des sites..."
SITE_JSON=$(curl -sk "https://$IP:$PORT/proxy/network/integration/v1/sites" \
  -H "Accept: application/json" \
  -H "X-API-Key: $APIKEY")

if [ $? -ne 0 ] || [ -z "$SITE_JSON" ]; then
    echo "Erreur : impossible de recuperer les sites"
    exit 1
fi

SITE_ID=$(echo "$SITE_JSON" | sed -n 's/.*"id"[ ]*:[ ]*"\([^"]*\)".*/\1/p' | head -n 1)

if [ -z "$SITE_ID" ]; then
    echo "Erreur : aucun site ID detecte"
    exit 1
fi

echo "Site ID detecte : $SITE_ID"

echo "Suppression des fichiers .txt existants..."
rm -f *.txt

echo "Telechargement du fichier source..."
curl -sk "$IPS" -o filtreperso.txt
if [ $? -ne 0 ] || [ ! -s filtreperso.txt ]; then
    echo "Erreur : impossible de telecharger le fichier"
    exit 1
fi

echo "Decoupage du fichier en blocs de $IPMAX lignes..."
split -l "$IPMAX" filtreperso.txt filtreperso_

echo "Nettoyage des fichiers generes..."
for f in filtreperso_*; do
    # Supprimer la dernière ligne si elle est vide
    sed -i '${/^$/d;}' "$f"

    # Ajouter extension .txt
    mv "$f" "$f.txt"
done

echo "Suppression du fichier source filtreperso.txt..."
rm -f filtreperso.txt

echo "Comptage des fichiers generes..."
NB_FICHIERS=$(ls filtreperso_*.txt 2>/dev/null | wc -l)

echo "Nombre de fichiers generes : $NB_FICHIERS"

echo "Recuperation des zones firewall..."

ZONES=$(curl -sk "https://$IP:$PORT/proxy/network/integration/v1/sites/$SITE_ID/firewall/zones" \
  -H "Accept: application/json" \
  -H "X-API-Key: $APIKEY")

if [ -z "$ZONES" ]; then
    echo "Erreur : impossible de recuperer les zones firewall"
    exit 1
fi

ZONE_EXTERNAL=$(echo "$ZONES" | grep -o '{"id":"[^"]*","name":"External"[^}]*}' | sed 's/.*"id":"\([^"]*\)".*/\1/')
ZONE_INTERNAL=$(echo "$ZONES" | grep -o '{"id":"[^"]*","name":"Internal"[^}]*}' | sed 's/.*"id":"\([^"]*\)".*/\1/')
ZONE_GATEWAY=$(echo "$ZONES" | grep -o '{"id":"[^"]*","name":"Gateway"[^}]*}' | sed 's/.*"id":"\([^"]*\)".*/\1/')

echo "Zone External : $ZONE_EXTERNAL"
echo "Zone Internal : $ZONE_INTERNAL"
echo "Zone Gateway  : $ZONE_GATEWAY"

echo "Verification des regles de pare-feu..."

# On récupère toutes les policies une seule fois
POLICIES=$(curl -sk "https://$IP:$PORT/proxy/network/integration/v1/sites/$SITE_ID/firewall/policies?filter=name.like('IP%20Ban*')&limit=$LIMIT" \
  -H "Accept: application/json" \
  -H "X-API-Key: $APIKEY")

echo "Suppression des anciennes policies :"

echo "$POLICIES" | jq -c '.data[]' | while read -r POLICY; do
    ID=$(echo "$POLICY" | jq -r '.id')
    NAME=$(echo "$POLICY" | jq -r '.name')

    echo " - $NAME  (ID: $ID)"

    POLICIEDELETE=$(curl -sk -X DELETE "https://$IP:$PORT/proxy/network/integration/v1/sites/$SITE_ID/firewall/policies/$ID" \
      -H "Accept: application/json" \
      -H "X-API-Key: $APIKEY")

done

echo "Création des policies :"

i=1
for f in filtreperso_*.txt; do
    # echo "Traitement du fichier : $f"

    SUFFIX=$(printf "%02d" "$i")

    RULE1="IP Ban $SUFFIX - Ext-Gat"
    RULE2="IP Ban $SUFFIX - Ext-Int"

    ITEMS=$(awk 'NF {printf "{\"type\":\"IP_ADDRESS\",\"value\":\"%s\"},", $0}' "$f")
    ITEMS="[${ITEMS%,}]"

BODY1=$(cat <<EOF
{
  "enabled": true,
  "name": "$RULE1",
  "description": "Auto-generated $(date +"%Y-%m-%d %H:%M:%S")",
  "action": { "type": "BLOCK" },
  "source": {
    "zoneId": "$ZONE_EXTERNAL",
    "trafficFilter": {
      "type": "IP_ADDRESS",
      "ipAddressFilter": {
        "type": "IP_ADDRESSES",
        "matchOpposite": false,
        "items": $ITEMS
      }
    }
  },
  "destination": {
    "zoneId": "$ZONE_GATEWAY"
  },
  "ipProtocolScope": {
    "ipVersion": "IPV4"
  },
  "loggingEnabled": false
}
EOF
)

BODY2=$(cat <<EOF
{
  "enabled": true,
  "name": "$RULE2",
  "description": "Auto-generated $(date +"%Y-%m-%d %H:%M:%S")",
  "action": { "type": "BLOCK" },
  "source": {
    "zoneId": "$ZONE_EXTERNAL",
    "trafficFilter": {
      "type": "IP_ADDRESS",
      "ipAddressFilter": {
        "type": "IP_ADDRESSES",
        "matchOpposite": false,
        "items": $ITEMS
      }
    }
  },
  "destination": {
    "zoneId": "$ZONE_INTERNAL"
  },
  "ipProtocolScope": {
    "ipVersion": "IPV4"
  },
  "loggingEnabled": false
}
EOF
)

    echo " - $RULE1"
    echo "$BODY1" > body1.json

    POLICIECREATE1=$(curl -sk -X POST \
      "https://$IP:$PORT/proxy/network/integration/v1/sites/$SITE_ID/firewall/policies" \
      -H "Accept: application/json" \
      -H "Content-Type: application/json" \
      -H "X-API-Key: $APIKEY" \
      --data @body1.json)

    rm -f body1.json

    echo " - $RULE2"
    echo "$BODY2" > body2.json

    POLICIECREATE2=$(curl -sk -X POST \
      "https://$IP:$PORT/proxy/network/integration/v1/sites/$SITE_ID/firewall/policies" \
      -H "Accept: application/json" \
      -H "Content-Type: application/json" \
      -H "X-API-Key: $APIKEY" \
      --data @body2.json)

    rm -f body2.json

    i=$((i+1))
done

echo "Operations terminees."

Voila je voulais juste partager quelque chose qui fonctionne chez moi et qui pourrait servir.
 
Dernière édition:
  • J'aime
Réactions: morgyann
Bonjour,

Merci pour l'info et le script.

J'utilise Unifi OS Server hébergé sur une VM
Questions (je n'ai jamais utilisé Unifi et complètement néophite) :

1. Faut-il avoir du matériel Unifi ?
2. Si non, l'OS est-il libre d'utilisation ?
3. Et peut-on l'installer sur une machine en début de réseau (pour tout le réseau et machines) ?
 
Bonjour,

Merci pour l'info et le script.


Questions (je n'ai jamais utilisé Unifi et complètement néophite) :

1. Faut-il avoir du matériel Unifi ?
2. Si non, l'OS est-il libre d'utilisation ?
3. Et peut-on l'installer sur une machine en début de réseau (pour tout le réseau et machines) ?
Bonjour,

oui, il faut du matériel Unifi. J'ai un UXG Fiber sans firmware, cet OS permet l'administration.