Um conjunto de regras iptables seguro e padrão para um servidor web HTTP (s) básico

15

Eu tenho tentado montar um script básico de iptables de servidor que funcionará para a maioria dos sites apenas executando um servidor web básico usando HTTP (S) e SSH (portas 80, 443, & 22). Afinal, a maioria dos VPS só precisa dessas regras de portas iniciais e pode adicionar e-mails ou portas de jogos mais tarde, conforme necessário.

Até agora eu tenho o seguinte conjunto de regras e fiquei me perguntando se alguém conhece um script melhor ou qualquer melhoria que possa ser adicionada.

*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

O iptables é uma das partes mais importantes de proteger sua caixa (veja também fail2ban) e ainda há muitas pessoas como eu que têm dificuldade em entender tudo o que é necessário para criar um firewall básico seguro para nossos servidores.

Qual é a maneira mais segura de abrir apenas as portas básicas necessárias para um servidor web?

Atualização: cyberciti.biz tem outro script iptables que parece muito bom.

Além disso, em vez de usar o Denyhosts ou o fail2ban, você pode usar iptables para bloquear tentativas repetidas de SSH .

    
por Xeoncross 01.10.2010 / 05:10

4 respostas

14

A maneira mais segura de trabalhar com o iptables é fechar tudo e abrir apenas o que você precisa. Estou meio distraído, então sempre tento ser o mais preguiçoso possível, por isso não cometo erros que podem levar o servidor a ficar inseguro.

Eu uso este, apenas um pouco de atribuição variável deve ser feita para que funcione.

  #!/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 :)

Estou usando isso há algum tempo, e qualquer tipo de modificação será muito apreciado se facilitar a administração.

    
por 07.02.2017 / 22:47
1

Isso parece muito bom, mas você pode apertar as coisas um pouco mais. O sinalizador -s é o nome de domínio ou IP de origem e você adiciona "-s 198.23.12.32" ou qualquer que seja seu endereço IP para permitir apenas o SSH do seu IP de origem. Você também pode escolher um intervalo de IPs de origem usando a notação de estilo CIDR .

Você deve ter cuidado ao registrar as chamadas negadas. O endereço IP do seu servidor será verificado por bots, script kiddies, etc, e o arquivo de log poderá ficar grande rapidamente. A menos que você esteja tentando diagnosticar um problema específico que possa estar relacionado a alguém que esteja tentando quebrar seu firewall, eu removerei essa opção.

Você também pode ligar fail2ban ao iptables para um pseudo-IDS. O fail2ban verificará seus arquivos de log e poderá bloquear um IP se eles tentarem invadir seu sistema. Por exemplo, se um determinado endereço IP não conseguir efetuar login no SSH 5 vezes, você poderá bloqueá-lo por um dia inteiro. Ele também funciona em FTP e muitos outros (incluindo bots defeituosos que atingem o Apache). Eu o uso em todos os meus servidores para fornecer uma proteção extra contra ataques de força bruta.

    
por 25.09.2010 / 19:49
1

Dê uma olhada no Shorewall. A configuração padrão de interface única seria um bom ponto de partida. É fácil de configurar e possui macros para coisas como SSH e acesso à Web. Pode ser configurado para bloquear o servidor para o nível desejado quando o firewall for desligado. Com o Shorewall-lite, você pode executar uma construção de firewall em outro servidor. O registro é fácil de configurar no nível desejado.

Para um servidor HTTP básico, você deseja abrir o acesso de entrada à porta 80 e à porta 443 se usar HTTPS. O acesso de entrada SSH de alguns endereços restritos é geralmente desejado. Você também pode querer bloquear o acesso de saída. Abra o firewall apenas para servidores e serviços necessários. NTP e DNS devem ser abertos, assim como um canal para buscar patches.

    
por 26.09.2010 / 03:00
1

Eu diria que esse é um firewall muito bom, exceto que ele é voltado para parar o tráfego de entrada e não se concentrar no tráfego de saída ou de saída. Em muitos casos, é tão importante se concentrar nas conexões de saída de uma caixa quanto aquelas de entrada. No infeliz caso de a máquina ser realmente explorada, seria bom evitar o download de rootkits adicionais ou conectar-se a nós de comando e controle, ou o que quer que seja.

BillThor começou a falar sobre isso acima, mas estou respondendo apenas com exemplos específicos. Uma das coisas boas sobre o iptables é que ele pode lembrar o estado da conexão, isso pode ter implicações de desempenho em sites com muito tráfego, mas você pode alterar seu acesso de entrada em http / https para permitir apenas respostas em conexões estabelecidas, por exemplo, ou especificamente limitar determinados privilégios usuários de ter acesso de saída a todos. Então, suas regras de saída teriam cláusulas RELACIONADAS, ESTABELECIDAS que impediriam uma série de ataques auxiliares e retardariam as que requerem um estágio secundário para realmente explorar uma caixa, o que é muito comum.

Finalmente, eu diria que é melhor definir sua política de iptables -P DROP ao invés de ter uma REJECT anexada no final. É principalmente uma questão de preferência, mas pode reduzir erros ao anexar cadeias com regras existentes em vez de inserir ou liberar / redefinir.

    
por 03.10.2010 / 20:30