web-dev-qa-db-ja.com

iptablesのヒントとコツ

Linuxシステム管理者はiptablesnetfilter パケットフィルタリングフレームワークへのユーザーランドインターフェイスに精通していると思います。

さて、この「質問」は、iptablesの知恵のさまざまなビットn個をまとめるためのコミュニティWikiであることを意図しています。あまりにも一般的または不明瞭なものはありません。他の人がiptablesを最大限に活用するのに役立つと思う情報を投稿してください。

61
pepoluan

ipsetを使用してnetfilterのパフォーマンスを最適化する

単なるIP、ポート、またはその両方に基づいて同様のルールのlotを記述する場合は、ipsetを使用してnetfilterのパフォーマンスを最適化することを検討してください。

例えば:

iptables -s 192.168.1.11 -j ACCEPT
iptables -s 192.168.1.27 -j ACCEPT
iptables -s 192.168.1.44 -j ACCEPT
... hundreds of similar rules ...
iptables -s 192.168.251.177 -j ACCEPT

つまり、送信元アドレスが192.168.251.177のパケットは、ACCEPTの判定を得る前に、最初に何百のルールを通過する必要があります。

もちろん、経験豊富なシステム管理者は、ルールをサブネットごとに分割します。しかし、stillは何百ものルールを意味します。

ipset救助に!

最初に、ipmapタイプのIPセットを定義します。

ipset -N Allowed_Hosts ipmap --network 192.168.0.0/16

次に、アドレスを入力します。

for ip in $LIST_OF_ALLOWED_IP; do ipset -A Allowed_Hosts $ip; done

最後に、上記の何百ものiptablesルールをoneルールに置き換えます。

iptables -m set --match-set Allowed_Hosts src -j ACCEPT

パケットが到着すると、netfilterはAllowed_Hosts IPセットに対してパケットのソース(src)IPの非常に速いビットマップ検索を実行します。 192.168.0.0/16からのすべてのパケットはoneルールを経験します。そして、ビットマップの検索は、何百ものiptablesルールチェックを実行するよりも少なくとも2桁速いと私は信じています。

ipsetはIPアドレスに限定されません。また、ポート、IPポートタプル、ネットワーク/サブネットアドレス、IP-MACタプルなどに基づいて照合することもできます。また、ソースまたは宛先、または両方の組み合わせ(タプルの場合)として、これらの基準に一致できます。

そして最後に、ipsetを使用すると、IPアドレスを自動的にブラックリスト/ホワイトリストに入れることができます。これらのブラックリスト/ホワイトリストは「エージング」することもできるため、構成可能な時間が経過するとIPアドレスが自動的に削除されます。

詳細は ipsetのmanページ を参照してください。

非常に重要な注意:

一部のLinuxディストリビューションはnotipsetをすぐに使用できるようにサポートしている場合があります(たとえば、Ubuntu 10.04にこの問題がありました)。これらのシステムでの1つの方法は、ソースコードからipsetをインストールすることです。

代わりに、ipsetのソースをWebサイトからダウンロードします。 http://ipset.netfilter.org/install.html

または、xtables-addonsを使用する場合、ソースにipset isが含まれます: http://xtables-addons.sourceforge.net/ =

26
pepoluan

Iptablesでのホワイトリストとブラックリストの使用

#!/bin/bash

WHITELIST=/whitelist.txt
BLACKLIST=/blacklist.txt

#THIS WILL CLEAR ALL EXISTING RULES!
echo 'Clearing all rules'
iptables -F

#
## Whitelist
#

for x in `grep -v ^# $WHITELIST | awk '{print $1}'`; do
        echo "Permitting $x..."
        $IPTABLES -A INPUT -t filter -s $x -j ACCEPT
done

#
## Blacklist
#

for x in `grep -v ^# $BLACKLIST | awk '{print $1}'`; do
        echo "Denying $x..."
        $IPTABLES -A INPUT -t filter -s $x -j DROP
done

ポートを開くスクリプト

#!/bin/bash
ALLOWEDTCP="80 3128 3784"
ALLOWEDUDP="3128 3784"

#
## Permitted Ports
#

for port in $ALLOWEDTCP; do
       echo "Accepting port TCP $port..."
       $IPTABLES -A INPUT -t filter -p tcp --dport $port -j ACCEPT
done

for port in $ALLOWEDUDP; do
        echo "Accepting port UDP $port..."
        $IPTABLES -A INPUT -t filter -p udp --dport $port -j ACCEPT
done

ポートスキャンのブロック

# Attempt to block portscans
# Anyone who tried to portscan us is locked out for an entire day.
iptables -A INPUT   -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP

# Once the day has passed, remove them from the portscan list
iptables -A INPUT   -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove

# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

なりすまし/無効なパケット

# Reject spoofed packets
# These adresses are mostly used for LAN's, so if these would come to a WAN-only server, drop them.
iptables -A INPUT -s 10.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP

#Multicast-adresses.
iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP

# Drop all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP

スマーフ攻撃をブロック

# Stop smurf attacks
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m icmp -j DROP

# Drop excessive RST packets to avoid smurf attacks
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

ICMPのブロック(別名ping)

# Don't allow pings through
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
26
Bart De Vos

ルールにコメントを追加します。

-m comment --comment "Comments help to read output of iptables -nvL"
22
alexm

既知のブロックTCP攻撃をブロック

以下のルールを、できれば-t raw -A PREROUTING

-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP

ブロックされる攻撃はそれぞれ次のとおりです。

  • SYN-FIN攻撃
  • SYN-RST攻撃
  • X-Mas攻撃
  • nmap FINスキャン
  • NULLflags攻撃
  • ALLflags攻撃

(上記の攻撃の名前を自由に編集してください)

17
pepoluan

NATを有効にする

  1. echo 1 > /proc/sys/net/ipv4/ip_forward
  2. /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

ステップ1はカーネルパラメータを設定してIP転送を許可し、ステップ2はインターフェイスeth0でNATを有効にするiptablesルールを設定します。

7

(私のiptables_tricks.txtファイルから、多くの場所から再コンパイル:P)

Iptablesに、ポート22(SSH)の同じIPからの新しい接続間で15秒待機させる:

 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
5
boris quiroz

FireHOL を使用-便利なiptablesラッパー

直接のiptablesコマンドよりもはるかに直感的です。特に他のファイアウォールでの過去の経験を持つ人々のために:

FireHOLは、任意の数のネットワークインターフェイス、任意の数のルート、任意の数のサービスを提供するLinuxホストおよびルーターで、ステートフルiptablesパケットフィルタリングファイアウォールを生成するiptablesファイアウォールジェネレーターです。式)。

4
Ophir Yoktan

再訪したIPセット

IPセットに関する言及はすでにあります。ただし、従来のルールよりもパフォーマンスが向上し、IPセットがCIDR表記ではサブネットとして簡単に表現できない多数の個別のIPアドレスで発生する問題を軽減するという事実に焦点を当てているという点で、一次元的です。

以下で使用される表記

ipsetについては、_ipset restore_で読み取られ、_ipset save_で書き込まれた表記法を使用します。

iptables(および_ip6tables_)ルールにも対応して、_iptables-restore_によって読み取られ、_iptables-save_によって書き込まれた表記法を使用します。これにより、表記が短くなり、潜在的なIPv4のみ(接頭辞_-4_)またはIPv6のみ(接頭辞_-6_)のルールを強調表示できます。

一部の例では、パケットフローを別のチェーンに転送します。チェーンはその時点で存在すると想定されているため、チェーンを作成するための行は生成されません(テーブル名やコマンドの最後にCOMMIT- tedも記載されていません)。

高度なIPセット

IPセットは 他の答え で述べられたものよりもはるかに多くのことができるため、IPセットのドキュメント( ipset(8) )と一緒に必ずお読みください- iptables-extensions(8) ここに、この簡単なエントリに加えて。

たとえば、私は主に3つのセットタイプに焦点を当てます:_hash:ip_、_hash:net_、および_list:set_ですが、それら以外にもあり、それらにはすべて有効な使用例があります。

たとえば、IPアドレスだけでなく、ポート番号も照合できます。

_iptables-save_および_iptables-restore_と同様にIPセットを保存および復元する

IPセット宣言を一括で作成し、_ipset restore_にパイプしてインポートできます。既存のエントリに対するコマンドの復元力を高めたい場合は、_ipset -exist restore_を使用します。

ルールが_default.set_というファイルにある場合は、次のようにします。

_ipset -exist restore < default.set
_

そのようなファイルには、createセットへのエントリと、addエントリへのエントリを含めることができます。しかし、一般的に、コマンドラインからのコマンドのほとんどは、ファイル内に対応するバージョンがあるようです。例(一連のDNSサーバーの作成):

_create dns4 hash:ip family inet
create dns6 hash:ip family inet6
# Google DNS servers
add dns4 8.8.8.8
add dns4 8.8.4.4
add dns6 2001:4860:4860::8888
add dns6 2001:4860:4860::8844
_

ここでは、IPv4用に1セット(_dns4_)とIPv6用に1セット(_dns6_)が作成されます。

IPセットのタイムアウト

IPセットのタイムアウトは、セットごとおよびエントリごとにデフォルトとして設定できます。これは、誰かを一時的にブロックしたいシナリオ(ポートスキャンやSSHサーバーのブルートフォースを試みる場合など)に非常に役立ちます。

これが機能する方法は次のとおりです(IPセットの作成時のデフォルト)。

_create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800
_

以下に、これらの特定のセットと、それらが設定されている理由を説明します。

特定のIPアドレスのタイムアウトを設定する場合は、次のように簡単に言うことができます。

_add ssh_dynblock4 1.2.3.4 timeout 7200
_

(設定された)デフォルトの30分ではなく、IP 1.2.3.4を2時間ブロックする。

しばらくして_ipset save ssh_dynblock4_でそれを見ると、次の行に沿って何かが表示されます。

_create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800
add ssh_dynblock4 1.2.3.4 timeout 6954
_

タイムアウトの警告

  • タイムアウトは、特定のセットの機能です。セットがcreatedタイムアウトサポートなしで作成されなかった場合、エラーが発生します(例:_Kernel error received: Unknown error -1_)。
  • タイムアウトは秒単位で指定されます。たとえば、Bash算術式を使用して、分単位から秒単位で取得します。例:Sudo ipset add ssh_dynblock4 1.2.3.4 timeout $((120*60))

特定のIPセットにエントリが存在するかどうかの確認

スクリプト内で、エントリがすでに存在するかどうかを確認すると便利です。これは、エントリが存在する場合はゼロを返し、それ以外の場合はゼロ以外を返す_ipset test_で実現できます。したがって、通常のチェックはスクリプトで適用できます。

_if ipset test dns4 8.8.8.8; then
  echo "Google DNS is in the set"
fi
_

ただし、多くの場合、_-exist_スイッチをipsetに使用して、既存のエントリについて文句を言わないようにする必要があります。

iptablesルールからのIPセットの入力

私の意見では、これはIPセットのキラー機能の1つです。 IPセットのエントリと照合できるだけでなく、既存のIPセットに新しいエントリを追加することもできます。

たとえば this answer でこの質問に:

_-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
_

... SSH(TCPポート22)への接続試行をレート制限することを意図しています。使用されるモジュールrecentは、最近の接続試行を追跡します。ただし、stateモジュールの代わりに、conntrackモジュールを使用します。

_# Say on your input chain of the filter table you have
   -A INPUT -i eth+ -p tcp --dport ssh -j SSH
# Then inside the SSH chain you can
# 1. create an entry in the recent list on new connections
   -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
# 2. check whether 3 connection attempts were made within 2 minutes
#    and if so add or update an entry in the ssh_dynblock4 IP set
-4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist
-6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist
# 3. last but not least reject the packets if the source IP is in our
#    IP set
-4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT
-6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT
_

この場合、フローをSSHチェーンにリダイレクトしているので、ルールごとに_-p tcp --dport ssh_を繰り返す必要はありません。

繰り返します:

  • _-m set_は、iptablesモジュール(IPセットを処理する)からのスイッチを使用していることをsetに認識させます。
  • _--match-set ssh_dynblock4 src_は、iptablessourcesrc)アドレスを名前付きセット(_ssh_dynblock4_)と照合するように指示します
    • これは_Sudo ipset test ssh_dynblock4 $IP_に対応します(_$IP_にはパケットのソースIPアドレスが含まれます)
  • _-j SET --add-set ssh_dynblock4 src --exist_は、sourcesrc)アドレスをパケットからIPセット_ssh_dynblock4_に追加または更新します。エントリが存在する場合(_--exist_)は単に更新されます。
    • これは_Sudo ipset -exist add ssh_dynblock4 $IP_に対応します(_$IP_にはパケットのソースIPアドレスが含まれます)

代わりにターゲット/宛先アドレスを照合する場合は、dstではなくsrcを使用します。その他のオプションについては、マニュアルを参照してください。

セットのセット

IPセットには他のセットを含めることができます。ここまでの記事をたどれば、セットを組み合わせることが可能かどうか疑問に思うでしょう。そしてもちろんそうです。上記のIPセットの場合、2つのジョイントセット_ssh_dynblock_および_ssh_loggedon_をそれぞれ作成して、IPv4のみのセットとIPv6のみのセットを含めることができます。

_create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800
# Sets of sets
create ssh_loggedon  list:set
create ssh_dynblock  list:set
# Populate the sets of sets
add ssh_loggedon ssh_loggedon4
add ssh_loggedon ssh_loggedon6
add ssh_dynblock ssh_dynblock4
add ssh_dynblock ssh_dynblock6
_

そして、あなたの頭に浮かぶべき次の質問は、これがIPバージョンにとらわれない方法でIPセットを照合して操作することを可能にするかどうかです。

そして、その答えは正解です:YES!(残念ながら、これは私が前回チェックしたときに明示的に文書化されていませんでした)

したがって、前のセクションのルールは、次のように書き直すことができます。

_-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
_

はるかに簡潔です。そして、はい、これは試行錯誤され、魅力のように機能します。

すべてをまとめる:SSHブルートフォース防御

私のサーバーでは、cronジョブとして実行されるスクリプトを使用して、一連のホスト名を取得し、それらをIPアドレスに解決してから、「信頼できるホスト」のIPセットにフィードしています。信頼できるホストは、サーバーへのログインをより多く試行し、他の誰かがいる限り必ずしもブロックされるわけではないという考え方です。

逆に、私は、SSHサーバーへの接続をブロックされている国々を持っています。ただし、信頼できるホストの(潜在的な)例外はあります(つまり、ルールの順序が重要です)。

ただし、それは読者の練習問題として残しておきます。ここで、_ssh_loggedon_セットに含まれているセットを使用して、後続の接続試行を他のパケットと同じように受け渡さず、受け渡せるようにする適切なソリューションを追加したいと思います。

以下のiptablesルールを確認する場合、_ssh_loggedon_のデフォルトのタイムアウトは90分、_ssh_dynblock_のデフォルトのタイムアウトは30分であることに注意してください。

_-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m set --match-set ssh_loggedon src -j ACCEPT
-A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
_

ここまでで、接続するIPアドレスが_ssh_loggedon_サブセットにどのように含まれるかを自問する必要があります。だから読んで...

おまけ:SSHログオン中にログインに使用したIPを追加する

sshrcやその仲間たちを使って実験したことがあれば、その欠点を知っていることでしょう。しかし、PAMが助けになります。 _pam_exec.so_という名前のモジュールを使用すると、SSHログオン中に、ユーザーが許可されていることがわかっている時点でスクリプトを呼び出すことができます。

_/etc/pam.d/sshd_および_pam_env_エントリの下の_pam_selinux_で、次の行を追加します。

_session    optional     pam_exec.so stdout /path/to/your/script
_

スクリプトのバージョン(上記の_/path/to/your/script_)が存在し、実行可能であることを確認してください。

PAMは環境変数を使用して何が行われているのかを伝達するため、次のような簡単なスクリプトを使用できます。

_#!/bin/bash
# When called via pam_exec.so ...
SETNAME=ssh_loggedon
if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then
    [[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4"
    ipset -exist add $SETNAME "$PAM_RHOST"
fi
_

残念ながら、ipsetユーティリティにはnetfilterのスマート機能が組み込まれていないようです。したがって、エントリを追加するときに、IPv4とIPv6のIPセットを区別する必要があります。そうでない場合、ipsetは、IPの代わりに別のsetをセットのセットに追加することを想定しています。そしてもちろん、IPにちなんで名付けられたセットが存在することはまずありません:)

そのため、IPアドレスで_:_をチェックし、そのような場合はセット名に_6_を追加し、そうでない場合は_4_を追加します。

終わり。

4
0xC0000022L

IPTABLESビデオチュートリアル

エピソード1 http://www.youtube.com/watch?v=ldB8kDEtTZA&feature=player_embedded

エピソード2 http://www.youtube.com/watch?v=aDaEXxRHeXY&feature=related

最後のエピソード

http://www.youtube.com/watch?v=JojqHKcSxpo&feature=player_embedded

初心者にとっては良いスタートになります。

4
Registered User

Iptablesの設定に使用できる別のGUIは Firewall Builder です。ルール要素をデータベース内のオブジェクトとして作成し、これらのオブジェクトをルールエディターにドラッグアンドドロップして、目的のファイアウォールポリシーを作成できます。次に、アプリケーションは、ルールの実装に必要なすべてのiptablesコマンドを含むスクリプトファイルを生成します。

一度に1つのiptables構成しか管理できない他のいくつかのiptables GUIソリューションとは異なり、Firewall Builderでは、単一のアプリケーションから多数のiptables構成をすべて管理できます。 Firewall BuilderはLinux、Windows、Mac OS Xで動作し、10年以上使用されており、世界中に何千人ものアクティブユーザーがいます。

完全な開示-私は、ファイアウォールビルダーを開発している会社であるNetCitadelの共同創設者です。

3
Mike H.

ワイルドカードを使用して複数のインターフェース名を一致させる

例:eth0andeth1があり、それらの間のトラフィックを許可しますか?

iptables -A FORWARD -i eth+ -o eth+ -j ACCEPT

LXCによって動的に作成されて名前が付けられたveth<something>インターフェースに一致させるために、これを過去に使用しました。したがって、veth+と一度にすべてを照合できます。

また、_<something>と照合するために、意図的にいくつかのインターフェイスに_+と名前を付けました。

2
0xC0000022L

IPセットを使用して、すべての個別のIPアドレスを発信帯域幅割り当てに制限する

おそらくISPで測定された帯域幅割り当てに対して、帯域幅使用攻撃を反映または回避するために、毎月の帯域幅使用の個々のIP 15GiByteのみを許可するようにサーバーを構成してください。これは次のように実行できます。

まず、IPv4およびIPv6のIPセットを作成します。

ipset create IP_QUOTA_SET_OUT hash:ip timeout 345600 counters
ipset create IP_QUOTA_SET_OUT_INET6 hash:ip timeout 345600 counters family inet6

次に、iptablesルールを追加します。最初の行では、セットにIPがまだない場合は追加されます。セット内のIPに対して転送されたバイト数が指定された量より大きい場合、2行目は一致しません。次に、IPv6についても同じことが行われます。

iptables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT dst -j SET --add-set IP_QUOTA_SET_OUT dst --timeout 345600
iptables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT dst --bytes-gt 16106127360 -j DROP

ip6tables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT_INET6 src -j SET --add-set IP_QUOTA_SET_OUT_INET6 src --timeout 345600
ip6tables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT_INET6 src --bytes-gt 16106127360 -j DROP

これにより、ユーザーがWebサーバーから長期間にわたって大きなファイルを要求したり、サービスからサービスを要求したりするなどの攻撃を防ぐことができます。 INPUTチェーンについても同じことができます。

2
infinmed

uidで発信接続を記録する

iptables -A OUTPUT -m state --state NEW -m tcp -p tcp -m limit --limit 5/m -j LOG --log-uid --log-prefix="outgoing connection: "

ポート/接続転送:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.1.7:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT
2
kofemann

珍しいMSS値をブロックする

iptables -t mangle -A PREROUTING -p tcp \
-m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

DDos保護のSYNPROXYターゲット

このターゲットの目的は、SYNパケットを送信したホストが接続を確立したか、またはSYN接続を開始した後に何もしないかを確認することです。何もしない場合は、最小限の労力でパケットを破棄します。

生パケットの接続追跡テーブルにSynパケットを設定する

iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 --syn -j CT --notrack

Httpサーバーのsynproxyを有効にします。

iptables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate INVALID,UNTRACKED \
-j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

リソース: RHELブログのSYNPROXYターゲット

1
fugitive

Ipsetsとtcpフラグに関するコメントに同意しますが、まだ多くの点が不足しています。

国リストには、ipsetsの代わりにxtables-addons geoip matchを使用します。 geoipデータを定期的に(少なくとも月に1回)更新します。データは、ファイアアンドフォーゲットのipsetリストよりも動的です。

Tcpフラグを使用した接続状態の追跡を検討してください。たとえば、tcp RSTまたはACKは、確立された接続に対してのみ意味があります。 SYNは、新規および関連する接続に対してのみ意味があります。確立された接続のSYNは、SYN + ACKが失われたか、ハッキングの試みが行われたことを意味し、接続の両側が状態について合意していないため、リセットする必要があります。

なし、SYN + RSTおよびFIN + RSTは無効な組み合わせですが、SYN + FINは特にTCP fast-open(TCPオプション34)の下で有効です。特にDNSの場合、SYNパケットは高速-open、フラグメント化しないでください。PSHフラグとURGフラグのあるルールは役に立たないと思います。接続追跡状態とTCP状態)を混同しないでください:SYNパケットへのRST応答は追跡の目的で確立されました。

SYNPROXYは転送されたパケット用で、syncookieのサポートを超えてローカルに配信されたパケットには何も追加しません。

ICMPエラーパケットは、有効な場合、常に関連する状態で、長さが48:576になります。 IPv6の場合、長さ84:1280。他のすべては無視されるべきです。それらの最大サイズは最小MTUでもあるため、決してフラグメント化しないでください。 ICMP要求(ping、タイムスタンプなど)は常に新しく、応答が確立されます。他の状態のICMPパケットをドロップします。

最近のリストを使用し、後続のSYNパケットのみを受け入れるSSHの例のように、SMTPでも同じことが行われ、IPアドレスデータムのみの「グレーリスト」に似ています。

フィルターテーブルでは、入力チェーンと出力チェーンの最初の(確立された状態のパケットを最初に受け入れる場合は2番目の)ルールがループバックインターフェイスのすべてを受け入れる必要があります。自分の内部パケットを信頼する必要があります。できない場合は、ファイアウォールソリューションを超える大きな問題があります。

最後に、ルールの内容をよく理解していない限り、ルールを盲目的にコピーしないでください。多くの類似したルールのリストがそれを行っており、ほとんどの場合、結果は笑えるものです。

0
MR.X