基本的なHTTP Webサーバー用の安全な標準iptablesルールセット


15

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での不正な繰り返し試行をブロックできます。


あなたはそれがVPSだと言います。LAN IPもあると思いますか?サブネット上のすべてのマシンを信頼していますか?ここにどれほど偏執的になりたいですか?OUTPUTフィルタリングを使用して、マシンをさらに保護できます。お知らせください。使用することをお勧めします。
-hobodave

良い点は、ほとんどのVPSがVM内にあり、LANからアクセスできる可能性のある他のVMがあることを考えると、それらを信頼しないことが賢明な出発点になると思います。追加のVPSがある場合は、後でルールを追加してそれらにアクセスできます(つまり、Webサーバーからデータベースへ)。
Xeoncross

1
警告:前述のcyberciti.bizスクリプトを実行してmodprobeインストールされていない場合(またはポート22を開く前に他のエラーがある場合)、サーバーからロックアウトされます。
-EoghanM

回答:


14

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 :)

私はしばらくそれを使用してきましたが、管理が容易になる場合は、あらゆる種類の変更が非常に高く評価されます。


SNMP(161)over TCPを使用する一般的なツールはありますか?これらのルールはUDP / 161である必要があると思います。
クバンチク

1

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

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

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


fail2banで15MB程度節約できるので、実際にはDenyHostsを使用します。ただし、fail2banはより強力で、多くのアプリケーション(DenyHostsのようなSSHだけでなく)で動作します。攻撃者が禁止されていることを考えると、ログファイルがすぐにいっぱいになることを心配する必要がありますか?ファイルがいっぱいになったときにファイルをローテーションする方法はありますか?fail2banでログを無効にした場合、Denyhosts / Fail2banにはまだスキャンするログエントリがありますか?また、ソースオプションは一部の人々にとっては良いでしょう-しかし、私はデフォルトのルールセットを目指しているので、自分のように動き回る人はそのオプションを使用できません。
Xeoncross

@Xeoncross:DenyHostsは蒸し暑い山です。中国からの侵入の試みを常に受け​​ていた1台のマシンで実行していました。数か月の間に/etc/hosts.denyに数千のIPが含まれるようになり、その時点でsshdがボックスのリソースを使い果たし、単一のCPUマシンで最大60+の負荷を引き起こしました。fail2banに切り替えて、振り返ることはありませんでした。
hobodave

@hobodave DenyHostsで始めたばかりなので、これが問題になったときに最初に切り替えることをこの心に留めておきます。
Xeoncross

1
@Xeoncrossでは、iptablesログをローテーションする場合、独自のlogrotate.dスクリプトを作成できます。/etc/logrotate.dを見て、別のファイルをコピーし、ログファイル名を変更すると、他のログファイルと共にローテーションされます。logrotateのマニュアルページでは、さまざまなオプションについて説明しています。
アランアイビー

1

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

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


1

これは、着信トラフィックを停止することを目的としており、出トラフィックまたは発信トラフィックに焦点を合わせていないことを除いて、非常に優れたファイアウォールと言えます。多くの場合、ボックスからのアウトバウンド接続をインバウンド接続と同様に重視することが重要です。マシンが実際に悪用されるという不幸なケースでは、追加のルートキットのダウンロード、コマンドおよびコントロールノードへの接続などを防ぐことができると便利です。

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

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


だから私はに変更-A INPUT -j REJECTする必要があり-A INPUT -P DROPますか?
Xeoncross
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.