% Bannissement de toute connection à un port donné

# Introduction

L'objectif est que toute IP qui se connecte à un port donné (par exemple le port 22) se retrouve bannie via `iptables` avec `ipset`.

# Installation

## `ipset`

```bash
sudo apt update
sudo apt install ipset
```

## Création d'un set d'IP bannies

```bash
sudo ipset create banned_ips hash:ip
```

## Création d'une règle IP tables pour bloquer les IP du set

```
sudo iptables -I INPUT -m set --match-set banned_ips src -j DROP
```

## Règle pour le bannissement à la première connexion

```bash
sudo iptables -I INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name SSH_BLOCK --rsource
sudo iptables -I INPUT -p tcp --dport 22 -m recent --update --hitcount 1 --name SSH_BLOCK --rsource -j SET --add-set banned_ips src
```



### Persistence `iptables`



# Persistence `ipset`

## Non automatisée

### À l'extinction de la machine

```bash
sudo ipset save banned_ips > /etc/ipset_banned_ips.save
```

### Au démarrage

```bash
sudo ipset restore < /etc/ipset_banned_ips.save
```


## Script automatisé


On met ce script dans `/usr/local/bin/ipset-ban-persist` :

```bash
#!/bin/bash

# Nom du set
SET_NAME="banned_ips"
SAVE_FILE="/etc/ipset_banned_ips.save"

# Fonction pour créer le set s'il n'existe pas
init_set() {
    if ! ipset list "$SET_NAME" >/dev/null 2>&1; then
        if [ -f "$SAVE_FILE" ]; then
            ipset restore < "$SAVE_FILE"
        else
            ipset create "$SET_NAME" hash:ip
        fi
    fi
    iptables -I INPUT -m set --match-set "$SET_NAME" src -j DROP
}

# Fonction pour ajouter une IP au set
ban_ip() {
    local IP="$1"
    ipset add "$SET_NAME" "$IP"
}

# Fonction pour enregistrer le set
save_set() {
    ipset save "$SET_NAME" > "$SAVE_FILE"
}


# Exécution
case "$1" in
    start)
        init_set
        ;;
    stop)
        save_set
        ;;
    ban)
        if [ -n "$2" ]; then
            ban_ip "$2"
        else
            echo "Usage: $0 ban <IP>"
        fi
        ;;
    *)
        echo "Usage: $0 {start|stop|ban <IP>}"
        ;;
esac
```



On le rend exécutable:

```bash
sudo chmod +x /usr/local/bin/ipset-ban-persist
```

## Démarrage automatique avec systemd

On crée le fichier `/etc/systemd/system/ipset-ban-persist.service` avec ce contenu :

```
[Unit]
Description=IPSet Ban Management
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/ipset-ban-persist start
ExecStop=/usr/local/bin/ipset-ban-persist stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl enable ipset-ban-persist
```

## Vérification

Il semble nécessaire de le démarrer et arrêter pour créer effectivement le fichier:

```
sudo systemctl start ipset-ban-persist ; sudo systemctl stop ipset-ban-persist
```

Vérifier que le fichier `/etc/ipset_banned_ips.save` soit présent.



# Gestion des bannissements

## Lister les IP bannies

```bash
sudo ipset list banned_ips
```

## Supprimer une IP bannie

```bash
ipset del banned_ips 1.2.3.4
```


## Ajouter une IP manuellement

```bash
sudo ipset add banned_ips 1.2.3.4
```


# Persistence du firewall

## `ufw` (non recommandé)

Mettre la règle suivante avant la règle `*filter`

```conf
#Bans ipset banned_ips
-A INPUT -m set --match-set banned_ips src -j DROP
#Bans ipset banned_ips (END)
```

Ce qui donne:

```conf
# Don't delete these required lines, otherwise there will be errors
*filter
#Bans ipset banned_ips
-A INPUT -m set --match-set banned_ips src -j DROP
#Bans ipset banned_ips (END)
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
```


