web-dev-qa-db-fra.com

Un ensemble de règles d'IPTables Secure et standard pour un serveur Web de base HTTP (S)

J'ai essayé de rassembler un script d'iptables de serveur de base qui fonctionnera pour la plupart des sites qui utilisent simplement un serveur Web de base à l'aide de HTTP (S) et SSH (ports 80, 443 et 22). Après tout, la plupart des VPS n'ont besoin que de ces règles de démarrage des ports et peuvent ajouter des ports de courrier ou de jeu plus tard à titre nécessaire.

Jusqu'à présent, j'ai le peu de règles suivant et je me demandais si quelqu'un connaît un meilleur script ou des améliorations pouvant être ajoutées.

*filter

#  Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allows all outbound traffic
#  You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allows SSH connections (only 4 attempts by an IP every 3 minutes, drop the rest)
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

iPTABLES est l'une des parties les plus importantes de la sécurisation de votre boîte (voir également Fail2Ban) et il y a pourtant de nombreuses personnes comme moi qui ont du mal à comprendre tout ce qui va faire un pare-feu de base sécurisé pour nos serveurs.

Quel est le moyen le plus sûr de ne pas ouvrir les ports de base nécessaires à un serveur WebServer?

Mise à jour: CyberCiti.biz a un autre script iptables qui semble très bien.

De plus, plutôt que d'utiliser des dénonhostes ou de l'échec1Ban, vous pouvez utiliser Iptable lui-même de bloquer de mauvaises tentatives répétées de SSH .

15
Xeoncross

Le moyen le plus sûr de travailler avec IPTABLES est tout près tout et ouvre ce dont vous avez besoin. Je suis un peu distrait, alors j'essaie toujours d'être aussi paresseux que possible, alors je ne fais pas d'erreurs pouvant conduire le serveur à ne pas sécuriser.

J'utilise celui-ci, seul un peu de mission variable doit être fait afin de le faire fonctionner.

  #!/bin/bash +x

  # first author: marcos de vera
  # second: joan marc riera

  ip=/sbin/iptables
  mriera="xx.xx.xx.xx"
  nsancho="yy.yy.yy.yy"
  admins="$mriera $nsancho "
  sshers=""
  mysqlrs="zz.zz.zz.zz/23"
  snmprs="uu.uu.uu.uu"
  tcpservices="80 443 22"
  udpservices=""

  # Firewall script for servername

  echo -n ">> Applying iptables rules... "

  ## flushing...
  $ip -F
  $ip -X
  $ip -Z
  $ip -t nat -F

  # default: DROP!
  $ip -P INPUT DROP
  $ip -P OUTPUT DROP
  $ip -P FORWARD DROP

  # filtering...

  # localhost: free pass!
  $ip -A INPUT -i lo -j ACCEPT
  $ip -A OUTPUT -o lo -j ACCEPT

  # administration ips: free pass!
  for admin in $admins ; do
      $ip -A INPUT -s $admin -j ACCEPT
      $ip -A OUTPUT -d $admin -j ACCEPT
  done

  # allow ssh access to sshers
  for ssher in $sshers ; do
      $ip -A INPUT -s $ssher -p tcp -m tcp --dport 22 -j ACCEPT
      $ip -A OUTPUT -d $ssher -p tcp -m tcp --sport 22 -j ACCEPT
  done

  # allow access to mysql port to iReport on sugar

  for mysql in $mysqlrs ; do
      $ip -A INPUT -s $mysql -p tcp -m tcp --dport 3306 -j ACCEPT
      $ip -A OUTPUT -d $mysql -p tcp -m tcp --sport 3306 -j ACCEPT
      $ip -A INPUT -s $mysql -p udp -m udp --dport 3306 -j ACCEPT
      $ip -A OUTPUT -d $mysql -p udp -m udp --sport 3306 -j ACCEPT
  done


  # allowed services
  for service in $tcpservices ; do
      $ip -A INPUT -p tcp -m tcp --dport $service -j ACCEPT
      $ip -A OUTPUT -p tcp -m tcp --sport $service -m state --state RELATED,ESTABLISHED -j ACCEPT
  done
  for service in $udpservices ; do
      $ip -A INPUT -p udp -m udp --dport $service -j ACCEPT
      $ip -A OUTPUT -p udp -m udp --sport $service -m state --state RELATED,ESTABLISHED -j ACCEPT
  done

  $ip -A INPUT -j LOG --log-level 4
  # VAS and VGP
  #88 tcp udp
  #389 tcp ldap queries , udp ldap ping
  #464 tcp upd kerberos
  #3268 tcp global catalog access
  for dc in ip.ip.ip.ip ; do # our dc servers for some ldap auth
      vas=88
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $vas -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $vas -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $vas -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $vas -j ACCEPT
      ldap=389
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $ldap -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $ldap -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $ldap -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $ldap -j ACCEPT
      kpasswd=464
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $kpasswd -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $kpasswd -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $kpasswd -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $kpasswd -j ACCEPT
      gca=3268
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $gca -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $gca -j ACCEPT
      vgp=445
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $vgp -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $vgp -j ACCEPT
  done


  # allow the machine to browse the internet
  $ip -A INPUT -p tcp -m tcp --sport 80 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
  $ip -A INPUT -p tcp -m tcp --sport 443 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT

  $ip -A INPUT -p tcp -m tcp --sport 8080 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT


  # don't forget the dns...
  $ip -A INPUT -p udp -m udp --sport 53 -j ACCEPT
  $ip -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
  $ip -A INPUT -p tcp -m tcp --sport 53 -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 53 -j ACCEPT

  # ... neither the ntp... (hora.rediris.es)
  #$ip -A INPUT -s 130.206.3.166 -p udp -m udp --dport 123 -j ACCEPT
  #$ip -A OUTPUT -d 130.206.3.166 -p udp -m udp --sport 123 -j ACCEPT

  $ip -A INPUT -p udp -m udp --dport 123 -j ACCEPT
  $ip -A OUTPUT -p udp -m udp --sport 123 -j ACCEPT


  # and last but not least, the snmp access
  for monitor in $snmprs ; do
      $ip -A INPUT -s $monitor -p tcp -m tcp --sport 161 -j ACCEPT   # monitoring service
      $ip -A OUTPUT -d $monitor -p tcp -m tcp --dport 161 -j ACCEPT  # monitoring service
  end
  # outgoing SMTP
  $ip -A INPUT -p tcp -m tcp --sport 25 -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT


  # temporary backup if we change from DROP to ACCEPT policies
  $ip -A INPUT -p tcp -m tcp --dport 1:1024 -j DROP
  $ip -A INPUT -p udp -m udp --dport 1:1024 -j DROP


  echo "OK. Check rules with iptables -L -n"

  # end :)

Je l'utilise depuis un certain temps et tout type de modification sera très apprécié si cela facilite l'administration.

14
Marc Riera

Jetez un coup d'œil à Shorewall. La configuration par défaut de l'interface unique serait un bon point de départ. Il est facile à configurer et possède des macros pour des choses comme SSH et un accès Web. Il peut être configuré pour verrouiller le serveur au niveau souhaité lorsque le pare-feu est arrêté. Avec Shorewall-Lite, vous pouvez exécuter une boîte de pare-feu sur un autre serveur. La journalisation est facile à configurer au niveau souhaité.

Pour un serveur HTTP de base, vous souhaitez un accès entrant ouvert au port 80 et au port 443 si vous utilisez HTTPS. L'accès SSH entrant à partir de quelques adresses restreintes est généralement souhaité. Vous voudrez peut-être bien enfermer l'accès sortant. Ouvrez le pare-feu aux serveurs et services requis uniquement. NTP et DNS doit être ouvert, ainsi qu'un canal pour récupérer des correctifs.

1
BillThor

Je dirais que c'est un très bon pare-feu, sauf qu'il est orienté vers l'arrêt de l'arrêt du trafic entrant et ne s'est pas concentré sur la sortie de la sortie ou du trafic sortant. C'est dans de nombreux cas tout aussi important de se concentrer sur les connexions sortantes d'une boîte comme celles entrantes. Dans le cas malheureux que la machine soit effectivement exploitée, il serait agréable de pouvoir prévenir le téléchargement de kits racines supplémentaires ou de se connecter aux nœuds de commande et de commande, ou autre.

Billthor a commencé à parler de cela ci-dessus, mais je ne suis que de répondre avec des exemples spécifiques. L'une des bonnes choses sur les iptables est qu'elle puisse se souvenir d'un état de connexion, cela peut avoir des implications de performance sur des sites fortement victimes de la traite, mais vous pouvez modifier votre accès entrant sur http/https pour permettre uniquement la réponse des connexions établies, par exemple, ou spécifiquement limiter certaines non privilégiées. les utilisateurs d'avoir accès sortant du tout. Ensuite, vos règles sortantes auraient des clauses établies, qui empêcheraient toute une foule d'attaques auxiliaires et ralentiraient celles qui nécessitent une étape secondaire pour exploiter réellement une boîte, ce qui est très courant.

Enfin, je dirais qu'il est préférable de définir votre stratégie IPTABLES -P Baisse plutôt que d'avoir un rejet annexe à la fin. C'est principalement une question de préférence, mais peut réduire les erreurs lors de l'adhésion aux chaînes avec les règles existantes au lieu d'insérer ou de rincer/réinitialiser.

1
MattyB