web-dev-qa-db-ja.com

基本的なHTTP(s)ウェブサーバー用の安全な標準iptablesルールセット

私は、HTTP(S)とSSH(ポート80、443、および22)を使用して基本的なWebサーバーを実行するだけで、ほとんどのサイトで機能する基本的なサーバーiptablesスクリプトをまとめようとしています。結局のところ、ほとんどのVPSはこれらの開始ポート規則のみを必要とし、必要に応じて後でメールまたはゲームポートを追加できます。

これまでのところ、次のルールセットがあり、誰かがより良いスクリプトや追加できる改善を知っているかどうか疑問に思っていました。

*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は、ボックスを保護する最も重要な部分の1つ(fail2banも参照)ですが、サーバーの安全な基本ファイアウォールを作成するために必要なすべてのことを理解できない私のような多くの人々がいます。

Webサーバーに必要な基本的なポートのみを開く最も安全な方法は何ですか?

更新:cyberciti.bizには別の iptablesスクリプト があります。

また、Denyhostsまたはfail2banを使用する代わりに、 iptables自体を使用して、SSHでの不正な繰り返し試行をブロックする を使用できます。

15
Xeoncross

Iptablesを操作する最も安全な方法は、すべてを閉じて、必要なものだけを開くことです。私は気を散らしているので、私は常にできるだけ怠け者になるようにしています。そのため、サーバーが安全でなくなる可能性のある間違いを犯しません。

私はこれを使用しますが、それを機能させるために、ほんの少しの変数の割り当てを行う必要があります。

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

私はこれをしばらく使用してきましたが、管理しやすくなるように修正を加えていただければ幸いです。

14
Marc Riera

これは見栄えは良いですが、もう少し引き締めることができます。 -sフラグはソースIPまたはドメイン名であり、「-s 198.23.12.32」またはソースIPからのSSHのみを許可するIPアドレスを追加します。 [〜#〜] cidr [〜#〜] スタイル表記を使用して、ソースIPの範囲を選択することもできます。

拒否された通話をログに記録するときは注意が必要です。サーバーのIPアドレスはボットやスクリプトキディなどによってスキャンされ、ログファイルはすぐに大きくなる可能性があります。ファイアウォールを破ろうとしている誰かに関連していると思われる特定の問題を診断しようとしているのでない限り、私はこのオプションを削除します。

fail2ban を疑似IDSのiptablesに関連付けることもできます。 fail2banはログファイルをスキャンし、システムに強制的に侵入しようとするとIPをブロックします。たとえば、特定のIPアドレスがSSHへのログインに5回失敗した場合、それらを1日ロックアウトすることができます。また、FTPや他の多く(Apacheを攻撃する悪いボットを含む)でも動作します。私はすべてのサーバーで使用して、ブルートフォース攻撃からの追加のクッションを提供します。

1
Alan Ivey

ショアウォールを見てください。単一インターフェースのデフォルト設定は、出発点として適しています。設定は簡単で、SSHやWebアクセスなどのマクロがあります。ファイアウォールのシャットダウン時にサーバーを目的のレベルにロックダウンするように構成できます。 Shorewall-liteを使用すると、別のサーバーでファイアウォールビルドを実行できます。ロギングは、必要なレベルに簡単に構成できます。

基本的なHTTPサーバーの場合、HTTPSを使用する場合は、ポート80およびポート443へのオープン着信アクセスが必要です。いくつかの制限されたアドレスからのSSH着信アクセスが通常望まれます。発信アクセスもロックする必要がある場合があります。必要なサーバーとサービスに対してのみファイアウォールを開きます。 NTPおよびDNSを開く必要があります。また、パッチを取得するためのチャネルも必要です。

1
BillThor

これは非常に優れたファイアウォールだと思いますが、受信トラフィックの停止に向けられており、下りトラフィックや送信トラフィックに重点が置かれていない点が異なります。多くの場合、ボックスからの接続と受信の接​​続に焦点を合わせることが重要です。マシンが実際に悪用されるという不幸なケースでは、追加のルートキットのダウンロード、コマンドおよびコントロールノードへの接続などを防ぐことができればいいでしょう。

BillThorはこれについて上記で話し始めましたが、私は特定の例で答えています。 iptablesの良い点の1つは、接続状態を記憶できることです。これは、トラフィックの多いサイトではパフォーマンスに影響を与える可能性がありますが、http/httpsへのインバウンドアクセスを変更して、たとえば確立された接続でのみ返信を許可したり、特定の非特権を具体的に制限したりできます。ユーザーはアウトバウンドアクセスをまったく持ちません。次に、アウトバウンドルールにはRELATED、ESTABLISHED句があり、補助的な攻撃のホスト全体を防ぎ、ボックスを実際に悪用するために第2段階が必要なものを遅くします。これは非常に一般的です。

最後に、最後にREJECTを追加するよりも、iptablesポリシー-P DROPを設定する方が良いと思います。これは主に好みの問題ですが、挿入やフラッシュ/リセットの代わりに既存のルールでチェーンに追加するときのミスを減らすことができます。

1
MattyB