IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sécurité Discussion :

script iptables supréme


Sujet :

Sécurité

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 6
    Points
    6
    Par défaut script iptables supréme
    Bonjour
    En farfouillant sur le net , j'ai récupérer un bon paquet de regles iptable , que je me suis "amusé" à résumer en un seul script pour obtenir le graal du script de firewalling .
    Voila le contexte :
    Un serveur debian avec une ip Fixe contenant un depot svn ( port 3690 ) et git ( basé sur ssh ) .
    Avec en plus un portsentry et fail2ban .

    J'ai testé une majorité de régles , mais je ne suis pas sur de la pertinence de chacune .


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
     
    #!/bin/bash
    # 
     
    # Création de différentes variables.
    IPT="/sbin/iptables"
    SPAMLIST="blockedip"
    SPAMDROPMSG="BLOCKED IP DROP"
     
    # Interface connectée à Internet.
    PUB_IF="eth0"
    # IP fixe.
    IPNET="X.X.X.X"
     
    # Variables des classes privées.
    LOOPBACK="127.0.0.0/8"
    CLASS_A="10.0.0.0/8"
    CLASS_B="172.16.0.0/12"
    CLASS_C="192.168.0.0/16"
    CLASS_D_MULTICAST="224.0.0.0/4"
    CLASS_E_RESERVED_NET="240.0.0.0/5"
    BROADCAST="192.168.1.255"
     
     
     
    #creation fichier d'ip à bannir .
    cd /var/scriptdepot/
    route -n | grep "\!H" | awk '{print $1}' > portsentry.txt
     
    $IPT -L | grep DROP > fail2banTmp
     
    grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' fail2banTmp > fail2ban.txt
     
    cat  fail2ban.txt portsentry.txt | sort | uniq > blocked.ips.txt
    rm -f /var/scriptdepot/fail2banTmp
    rm -f /var/scriptdepot/portsentry.txt
    rm -f /var/scriptdepot/fail2ban.txt
     
    [ -f /var/scriptdepot/blocked.ips.txt ] && BADIPS=$(egrep -v -E "^#|^$" /var/scriptdepot/blocked.ips.txt)
     
     
     
    # flush tout
    $IPT -F
    $IPT -X
    $IPT -Z
    $IPT -t filter -F
    $IPT -t filter -X
    $IPT -t nat -F
    $IPT -t nat -X
    $IPT -t mangle -F
    $IPT -t mangle -X
     
     
     
    # On remet la police par défaut à ACCEPT
    $IPT -P INPUT ACCEPT
    $IPT -P FORWARD ACCEPT
    $IPT -P OUTPUT ACCEPT
     
     
    # On remet les polices par défaut pour la table NAT
    $IPT -t nat -P PREROUTING ACCEPT
    $IPT -t nat -P POSTROUTING ACCEPT
    $IPT -t nat -P OUTPUT ACCEPT
     
    # Politiques par défaut, on DROP tout.
    $IPT -P INPUT DROP
    $IPT -P OUTPUT DROP
    $IPT -P FORWARD DROP
     
    if [ -f /var/scriptdepot/blocked.ips.txt ];
    then
    # -N, --new-chain chaîne Crée une nouvelle chaîne définie par l'utilisateur avec le nom indiqué. Il ne doit pas déjà exister de cible de même nom.
    $IPT -N $SPAMLIST
     
     
    for ipblock in $BADIPS
    do
    $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
    $IPT -A $SPAMLIST -s $ipblock -j DROP
    done
     
    $IPT -I INPUT -j $SPAMLIST
    $IPT -I OUTPUT -j $SPAMLIST
    $IPT -I FORWARD -j $SPAMLIST
     
    fi
     
     
     
     
    # Les états de connexions :
    # --state NEW
    # Une nouvelle connexion est établie. (elle contient le flag SYN)
    #
    # --state ESTABLISHED
    # La connexion analysée a déjà été établie, elle ne devrait pas contenir de SYN ni de FIN.
    #
    # --state RELATED
    # La connexion est en relation avec une autre connexion déjà établie.
    #
    # --state INVALID
    # la connexion n'est pas conforme, elle contient un jeu de flags anormal.
     
    # SYN-FLOODING PROTECTION
    $IPT -N syn-flood
    $IPT -A INPUT -i $PUB_IF -p tcp --syn -j syn-flood
    $IPT -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
    $IPT -A syn-flood -j DROP
     
     
    # Pour être sur que les nouvelles connexions TCP sont des paquets SYN.
    $IPT -A INPUT -i $PUB_IF -p tcp ! --syn -m state --state NEW -j DROP
     
    # Refuse les paquets venant des réseaux privés de classe A,B et C.
    $IPT -A INPUT -i $PUB_IF -s $CLASS_A -j DROP
    $IPT -A INPUT -i $PUB_IF -s $CLASS_B -j DROP
    #$IPT -A INPUT -i $PUB_IF -s $CLASS_C -j DROP
    # Refuse les paquets d'adresses multicast (classe D).
    $IPT -A INPUT -i $PUB_IF -s $CLASS_D_MULTICAST -j DROP
    # Refuse les paquets d'adresses réservées de classe E.
    $IPT -A INPUT -i $PUB_IF -s $CLASS_E_RESERVED_NET -j DROP
     
    #hashlimit limite à 3 connections sur le port ssh par ip  
    $IPT -I INPUT -m hashlimit -m tcp -p tcp --dport 22 --hashlimit 3/min --hashlimit-mode srcip --hashlimit-name ssh -m state --state NEW -j ACCEPT 
     
    # Block Fragments
    $IPT -A INPUT -i PUB_IF -f -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets"
    $IPT -A INPUT -i PUB_IF -f -j DROP
     
    # Block bad stuff
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
     
    # NULL packets
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets"
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags ALL NONE -j DROP 
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
     
    #XMAS
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets"
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP 
     
    # FIN packet scans 
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan"
    $IPT -A INPUT -i PUB_IF -p tcp --tcp-flags FIN,ACK FIN -j DROP
     
     
    #antispoofing
    if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
    then
    for filtre in /proc/sys/net/ipv4/conf/*/rp_filter
    do
    echo 1 > $filtre
    done
    fi
     
     
    #autorise les requetes locales (interface loopback)
    $IPT  -A INPUT -i lo -j ACCEPT
    $IPT  -A OUTPUT -o lo -j ACCEPT
     
    # Accepter les packets  relatifs à des connexions déjà  établies 
    $IPT -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPT -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
     
     
    # allow incomming ICMP ping pong stuff
    $IPT -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    $IPT -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
     
     
    ##### DEBUT OUVERTURE DE PORT
     
    iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
    iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
     
    iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
     
    iptables -A INPUT -i eth0 -p tcp --dport 3690 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport 3690 -m state --state ESTABLISHED -j ACCEPT
     
     
    ##### FIN  
     
     
    exit 0
    Une discussion sur certaines régles serait le bienvenue . Particulierement les régles syn , XMAS , antispoofing, Block Fragments ,hashlimit ,null packet ... , sur lesquelles j'ai un gros doute .
    Tout avis sera le bienvenu (si autre que "Pourquoi t as mis le port 22 pour le ssh " )

    En remerciant par avance

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    Bon je vous mets les commentaires de PascalHambourg sur ce script d'un autre fofo

    C'est mauvais. Je serai impitoyable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # Variables des classes privées.
    1) Les classes A, B et C sont abandonnées depuis 15 ans.
    2) Ce commentaire ne correspond pas à la liste qui suit : loopback, multicast et réservées ne sont pas des plages privées.
    3) Que vient faire une soi-disant adresse de broadcast (certes privée mais déjà comprise dans une des plages, et non utilisée dans le reste du script) dans cette liste ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # flush tout
    $IPT -F
    $IPT -X
    $IPT -Z
    $IPT -t filter -F
    $IPT -t filter -X
    Redondant. "filter" est déjà la table par défaut si on ne spécifie pas d'option -t.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # On remet la police par défaut à ACCEPT
    1) La "politique" (policy), pas la "police".
    Quel intérêt à part ouvrir une fenêtre de vulnérabilité puisque le script remet les politiques à DROP un peu plus loin ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for ipblock in $BADIPS
    do
    $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
    $IPT -A $SPAMLIST -s $ipblock -j DROP
    done
    Il serait plus économe de créer une chaîne logdrop contenant ces deux règles, cela diviserait le nombre de règles quasiment par deux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # Les états de connexions :
    # --state NEW
    # Une nouvelle connexion est établie. (elle contient le flag SYN)
    #
    # --state ESTABLISHED
    # La connexion analysée a déjà été établie, elle ne devrait pas contenir de SYN ni de FIN.
    #
    # --state RELATED
    # La connexion est en relation avec une autre connexion déjà établie.
    #
    # --state INVALID
    # la connexion n'est pas conforme, elle contient un jeu de flags anormal.
    Tout est faux.
    Ne pas confondre paquet et connexion. Les règles traitent des paquets, pas des connexions. L'état d'un paquet est défini par rapport à l'état de la connexion à laquelle il appartient, mais ce sont deux choses différentes. A noter que l'état de la connexion est mis à jour avant que l'état du paquet soit défini, donc l'état du paquet tient compte du fait qu'il a été vu.

    - NEW : paquet qui crée une nouvelle connexion ou appartient à une connexion existante qui n'a eu du trafic que dans un sens (pas de réponse). Il n'a pas forcément de flag SYN, qui est spécifique au protocole TCP. Un état de connexion est géré pour tous les protocoles, pas seulement TCP.

    - ESTABLISHED : paquet appartenant à une connexion existante qui a vu du trafic dans les deux sens (y compris ce paquet). Il peut contenir le flag SYN ou FIN.

    - RELATED : paquet lié à une connexion existante. C'est typiquement un paquet d'erreur ICMP ou un paquet qui crée une connexion liée dans les protocoles dits "complexes" : FTP, TFTP, SIP, RTP... Le second cas est géré par des modules spécialisés qu'il faut charger : nf_conntrack_ftp, nf_conntrack_sip...

    - INVALID : tous les autres cas. Typiquement, ce sont les paquets d'erreur ICMP faisant référence à une connexion existante, ou les paquets TCP dont les flags ou le numéro de séquence ne correspondent pas à l'état de la connexion. Il ne faut pas confondre l'état INVALID, qui est défini par rapport à l'état de la connexion, avec une combinaison invalide des flags, qui est propre au paquet indépendamment de l'état de la connexion.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    # SYN-FLOODING PROTECTION
    $IPT -N syn-flood
    $IPT -A INPUT -i $PUB_IF -p tcp --syn -j syn-flood
    $IPT -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
    $IPT -A syn-flood -j DROP
    Une demande de connexion par seconde, je n'appelle pas ça un flood. Avec un seuil aussi bas, j'appelle ce genre de règles un auto-déni de service. Ce type de limitation doit servir à protéger les ressources du serveur, or je pense qu'il doit être capable d'avaler plus d'une connexion par seconde.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # Refuse les paquets venant des réseaux privés de classe A,B et C.
    $IPT -A INPUT -i $PUB_IF -s $CLASS_A -j DROP
    $IPT -A INPUT -i $PUB_IF -s $CLASS_B -j DROP
    #$IPT -A INPUT -i $PUB_IF -s $CLASS_C -j DROP
    Pourquoi avoir commenté la plage des classes C privées ? Laisse-moi deviner : le sous-réseau de de la machine est dans cette plage ? Mais le sous-réseau ne couvre pas toute la plage /16, c'est généralement un /24, donc tu devrais bloquer toute la plage /16 sauf le /24. J'admets que c'est plus compliqué à réaliser, il faut créer une chaîne utilisateur avec un RETURN au début pour la plage à ne pas bloquer.

    1) Bloquer tous les fragments est une erreur. La fragmentation est une fonction utile du protocole IP. Certes il vaut mieux s'en passer mais parfois on n'a pas le choix, c'est ça ou rien.
    2) De toute façon, l'utilisation du suivi de connexion (chargé par la correspondance "state" et la table "nat") force la défragmentation à l'arrivée avant que les paquets traversent les chaînes iptables qui ne voient que des paquets complets. Donc en pratique cette règle est sans effet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # Accepter les packets  relatifs à des connexions déjà  établies
    $IPT -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPT -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    "NEW", tu considères que c'est des connexions déjà établies ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # allow incomming ICMP ping pong stuff
    $IPT -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    $IPT -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
    1) echo-request ou echo et echo-reply, c'est plus parlant que 8 et 0.
    2) Les paquets echo-request sont normalement dans l'état NEW, rarement ESTABLISHED (je ne me souviens plus dans quelle condition) et jamais RELATED.
    3) Les paquets echo-reply sont dans l'état ESTABLISHED, donc déjà acceptés par une règle du bloc "Accepter les packets relatifs à des connexions déjà établies" si l'interface est eth0. Attends-tu du ping sur une autre interface ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ##### DEBUT OUVERTURE DE PORT
     
    iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
    iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
     
    iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
     
    iptables -A INPUT -i eth0 -p tcp --dport 3690 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport 3690 -m state --state ESTABLISHED -j ACCEPT
    La règle en entrée avec --sport constitue une brèche de sécurité car l'émetteur du paquet contrôle le port source ; cette règle lui permet d'accéder à n'importe quel port UDP de ta machine. Les règles en sortie avec --sport n'apportent rien. Dans les deux cas, les paquets de réponse sont déjà acceptés par les règles du bloc "Accepter les packets relatifs à des connexions déjà établies".

Discussions similaires

  1. Problème de logging dans un script iptables
    Par UbNeBe dans le forum Réseau
    Réponses: 5
    Dernier message: 18/09/2014, 17h57
  2. Réponses: 2
    Dernier message: 02/01/2014, 11h22
  3. script IpTables : explications
    Par troumad dans le forum Sécurité
    Réponses: 0
    Dernier message: 30/03/2010, 21h59
  4. Vos avis concernant mon script iptables
    Par inesenis dans le forum Réseau
    Réponses: 1
    Dernier message: 26/03/2010, 13h59
  5. Script Iptables
    Par Jimmy_S dans le forum Réseau
    Réponses: 15
    Dernier message: 19/12/2005, 13h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo