UbuntuVPSでIptablesのみを使用してポートノッキングを構成する方法
ステータス:非推奨
この記事では、サポートされなくなったバージョンのUbuntuについて説明します。 現在Ubuntu12.04を実行しているサーバーを運用している場合は、サポートされているバージョンのUbuntuにアップグレードまたは移行することを強くお勧めします。
理由:
Ubuntu 12.04は2017年4月28日に保守終了(EOL)に達しました and no longer receives security patches or updates. This guide is no longer maintained.
代わりに参照してください:このガイドは参照として役立つ場合がありますが、他のUbuntuリリースでは機能しない場合があります。 可能な場合は、使用しているUbuntuのバージョン用に作成されたガイドを使用することを強くお勧めします。 ページ上部の検索機能を使用して、より新しいバージョンを見つけることができます。
序章
インターネットに接続されているサーバーは、悪意のあるユーザー、スクリプト、および自動ボットによるあらゆる種類の攻撃と調査にさらされています。 サービスやリソースへの正当なアクセスに影響を与えることなく、サーバーを攻撃から保護することは、バランスをとる行為である場合があります。
特定の種類のサービスは、パブリックインターネットに表示されて消費できるようになっています。 この例は、Webサーバーです。 他のタイプのサービスは通常、システム管理者または選択した数の個人によってのみ使用され、公開リソースとなることを意図したものではありません。
ポートノッキングとして知られる概念は、後者の説明に適合するプロセスをシールドする方法です。 ポートノッキングは、特定の所定のネットワークアクティビティのシーケンスが発生するまで、ファイアウォールの背後にあるプロセスに関連付けられたポートをカバーすることによって機能します。 この時点で、ポートノッキングサービスはファイアウォールを再構成して、保護されたアプリケーションへのアクセスを許可します。
前回の記事では、特別に設計されたポートノッキングサービスを介してポートノッキングを有効にする方法について説明しました。 この記事では、ポートノッキングを構成する別の方法について説明します。
この方法は、ファイアウォールルールを変更するために外部アプリケーションに依存しません。 代わりに、iptables
ファイアウォールは、「最近」と呼ばれる状態追跡モジュールを利用して、ファイアウォールルール自体の中でこれらすべてを実行できます。
これはUbuntu12.04ドロップレットで構成しますが、どの種類のLinuxサーバーでも同様の方法で動作する必要があります。
ノート: このチュートリアルでは、IPv4セキュリティについて説明します。 Linuxでは、IPv6のセキュリティはIPv4とは別に維持されます。 たとえば、「iptables」はIPv4アドレスのファイアウォールルールのみを維持しますが、「ip6tables」と呼ばれるIPv6の対応物があり、IPv6ネットワークアドレスのファイアウォールルールを維持するために使用できます。
VPSがIPv6用に構成されている場合は、IPv4とIPv6の両方のネットワークインターフェイスを適切なツールで保護することを忘れないでください。 IPv6ツールの詳細については、次のガイドを参照してください。LinuxVPSでIPv6を使用するようにツールを構成する方法
Iptablesポートノッキングの概要
実際の構成に入る前に、最近のモジュールがどのように機能し、ポートノッキングシステムを作成する方法について説明します。
Iptablesは、-m
フラグを使用してモジュールをロードできます。 最近のモジュールは接続状態を追跡できます。 これを使用して、接続しているユーザーが以前に必要だった各ポートにアクセスしたかどうかに基づいて、一連のチェーンを介してポート接続の試行を行うことができます。
この例では、eth0
インターフェイスで表されるSSHデーモンをインターネットからブロックします。 一連のポートが順番に「ノックオン」されると、一時的にコンピューターからのSSH接続を許可するように、ファイアウォールを動的に再構成します。
このチュートリアルで使用するシーケンスは次のとおりです。
- 1111
- 2222
- 3333
これらの値は、実際の構成では使用しないでください。
ユーザーが正しく認証し、iptablesにSSHデーモンをIPアドレスに公開させるには、シーケンス以外のトラフィックを送信せずに、これらの各ポートを順番にヒットする必要があります。 これを実装すれば、ポートノッキングシステムを正常に作成できます。
Iptables構成戦略
上記の設計を実装するために、いくつかの異なるチェーンを使用します。
まず、ポートノッキングの影響を受けたくないトラフィックをすべて受け入れます。 これには、Webサーバーなどのパブリックリソースのほか、確立された接続とローカルインターフェイスからの接続が含まれます。
その直後に、以前のルールで処理されなかったすべての着信トラフィックを新しいチェーンにリダイレクトし、そこでルールの大部分を配置します。 これは、新しいチェーンにトラフィックを集中させるかバイパスするだけで、機能を有効または無効にする非常に簡単な方法を提供するため、大規模な自己完結型のルールセットを実装する場合は常に良い考えです。
このチェーンをKNOCKINGと呼びます。
他のチェーンも使用します。 最近のモジュールでは、さまざまなタイプのトラフィックを分類し、接続が以前に設定されたカテゴリと一致するかどうかを確認できます。
この戦略を使用して、最初のノックターゲットにパケットを送信したIPアドレスにフラグを立てます。 その最初のフラグをチェックし、2番目のパケットが2番目のノックターゲットに送信されているかどうかをチェックするルールがあります。 そうである場合は、これまでに2つの回答が得られたことを示す別のフラグを設定します。 2番目のパケットが2番目のターゲットと一致しない場合、そのパケットはドロップされ、フラグがリセットされます。
追加のチェーンは、適切なフラグをチェックし、正しいパスを続行する場合にそれを渡すという同じ戦略を使用して機能します。 最終的に、最後のパケットが順番に要求されると、SSHデーモンは、正常にノックされたIPアドレスに対してのみ短時間公開されます。 その後、自動的に再び非表示になります。
したがって、基本的に、ポートノッキングルールをサービスを開始するための異なるゲートと考えると、3つのノックに対して3つのゲートがあります。 これは、要求しているIPアドレスが4異なる位置にある可能性があることを意味します。
-
初期状態:これは、最初のノックターゲットにパケットを正常に送信するまで、すべてのIPアドレスが存在する状態です。 これは最近のモジュールでは設定されず、フラグが設定されていないクライアントを参照する方法にすぎません。
-
auth1状態:最初のノックターゲットを正常にノックしたアドレスには、「auth1」のフラグが付けられます。 ここから、このホストからの次のパケットは、アドレスを初期状態に戻すか、「auth2」状態に移行するかを決定します。
-
auth2 state :この状態でフラグが立てられたアドレスは、最初と2番目のターゲットを順番に正常にノックしました。 このホストからの次のパケットは、ホストが初期状態に戻されるか、「auth3」状態に設定されるかを決定します。
-
auth3 state :「auth3」としてフラグが立てられたアドレスは、割り当てられた時間内に3つのポートすべてを順番に正常にノックしました。 「auth3」のフラグが立てられたアドレスが(提供されているウィンドウで)今すぐサービスにアクセスしようとすると、接続が受け入れられます。 他のトラフィックを受信すると、アドレスは初期状態に戻されます。
最近のモジュールによって設定されたフラグであるこれらの状態に加えて、各ゲート、または決定ポイントがチェーンとして実装されます。 チェーンは次のように要約できます。
-
GATE1 :初期状態のアドレスに「auth1」のフラグを付けるかどうかを決定します。
-
GATE2 :「auth1」状態のアドレスを「auth2」に処理するか、「初期」状態にリセットするかを決定します。
-
GATE3 :SSH接続を許可するために「auth2」状態のアドレスに「auth3」のフラグを付けるか、「初期」状態にリセットするかを決定します。
-
PASSED :このチェーンは、正常にノックされたクライアントのSSHデーモンのポートを一時的に開くために使用されます。 SSHデーモン宛てではないこのチェーン内のクライアントからのトラフィックはすべてドロップされ、状態が再び「初期」にリセットされます。
ご覧のとおり、ここには多くの決定ポイントがあります。 KNOCKING チェーンとそのサブチェーンのすべての種類のトラフィック(成功したノッククライアントからのSSHデーモンのトラフィックを除く)は、正しいポートに一致したかどうかに関係なく、ドロップする必要があります。 内部フラグは、成功した試行を追跡する唯一のものであり、このロジックはクライアントに公開されません。
これは、ポートノッキングの実装が有効であるために必要です。 接続しようとしている人は、プロセスのどの段階にあるのか、またはそのようなメカニズムが導入されている場合でも、フィードバックを受け取らないようにする必要があります。
通常のファイアウォールフレームワークを構成する
まず、接続の基本的なフレームワークを設定します。 上で説明した戦略は、すべての着信接続を処理するINPUTチェーンに適用されます。
まず、既存のファイアウォールルールをフラッシュして、クリーンな状態から始めることができるようにします。 ルールをフラッシュする前に、現在の接続を維持するために、空のテーブルのデフォルトポリシーが「ACCEPT」であることを再確認することをお勧めします。
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
これにより、制限を開始できる完全に開いたファイアウォールから開始することが保証されます。
ただし、制限を開始する前に、使用するチェーンを追加します。
sudo iptables -N KNOCKING
sudo iptables -N GATE1
sudo iptables -N GATE2
sudo iptables -N GATE3
sudo iptables -N PASSED
この時点で、8つの異なるチェーンが必要です。 このコンテキストでは関係のないOUTPUTチェーンとFORWARDチェーンを除いて、これらすべてを使用します。
まず、ポートノッキングで処理したくないトラフィックをINPUTチェーンに追加する必要があります。 現在のすべての接続を受け入れることから始めることができます。これにより、現在のSSH接続は影響を受けません。
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
また、サービスは相互に通信する必要があることが多いため、ローカルマシンからのすべての接続を受け入れる必要があります。
sudo iptables -A INPUT -i lo -j ACCEPT
Webサーバーのように、外部およびパブリックにアクセス可能なサービスを維持する必要がある場合は、次の形式を使用してこのタイプの接続を許可するルールを追加します。
sudo iptables -A INPUT -p protocol --dport port -j ACCEPT
この例では、デフォルトのポート80でWebサーバーが実行されていると想定し、次のトラフィックを許可します。
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
基本的な許可された接続が構成されたので、上記のルールで処理されなかったすべてのトラフィックをKNOCKINGチェーンに転送して、実際のノッキングロジックを実行できます。
sudo iptables -A INPUT -j KNOCKING
ファーストゲートを構成する
「ゲート」の構成が完了したら、それらすべてをKNOCKINGチェーンにフックして、ロジックテストを介してトラフィックを誘導します。 ただし、その前に、個々の論理ユニットを開発する必要があります。
最初のノッキングテストを定義することから始めます。 クライアントが接続するとき、クライアントが最初のターゲットにパケットを送信しているかどうかを確認する必要があります。 そうである場合は、最初のテストに合格したことをクライアントに報告し、接続を切断します。 そうでない場合は、接続を切断するだけです。
まず、正しいポート試行でフラグを設定します。
sudo iptables -A GATE1 -p tcp --dport 1111 -m recent --name AUTH1 --set -j DROP
この行は多くのことを行います。 まず、GATE1チェーンにルールを追加します。 このルールは、使用されているプロトコルが「tcp」であり、アクセスしようとしているポートが「1111」である場合に一致します。これは、最初のノックターゲットです。
これが当てはまる場合、最近のモジュール(-m recent
で呼び出されます)は、AUTH1という名前で(--name AUTH1 --set
ルールを使用して)要求元のIPアドレスにフラグを立てます。 これは、2番目のノックが一致するかどうかを確認するために使用するフラグです。 フラグが設定された後、パケットはドロップされるため、クライアントは何かが起こったかどうかを知ることができません。
次に、他のすべてのパケットをドロップします。これは、このチェーンに送信される情報がのみであり、この時点で一致する最初のパケットを探しているためです。
sudo iptables -A GATE1 -j DROP
これで、最初のポートがカバーされました。 ルールは、正しいポートが要求された場合にアドレスに一致してフラグを立てるか、アクションが実行されずにパケットが単にドロップされるかのいずれかです。
セカンドゲートを設定する
2番目のゲートは、最初のゲートとほぼ同じ方法で構成されます。 ただし、は少し複雑です。
まず、トラフィックをこのチェーンに送信するロジックは、メインのKNOCKINGチェーンに存在します。 このチェーンは、最初のゲートによって設定されたフラグが一致するかどうかをチェックする必要はありません。これは、すでに発生しているためです。
ただし、処理を開始する前に、はフラグを削除する必要があります。 フラグが削除されなかった場合は、アドレスに異なる名前のフラグが付けられ、ポートを3回スキャンするだけでアドレスが正常にノックされる可能性があります。 これは間違いなく私たちが望んでいることではありません。
予備的なルールで最近のモジュールを再び使用しますが、今回は名前をクリアするためだけです。
sudo iptables -A GATE2 -m recent --name AUTH1 --remove
これは処理ルールであるため、決定やジャンプは行いません。 現在のフラグ(このチェーンへのトラフィックを許可するフラグ)を削除して、次のルールに送信するだけです。
アドレスがこのチェーンの最初のルールを通過したため、フラグのないクリーンな状態になっています。 この時点で、この接続の試行が次のポートターゲットに正しく一致するかどうかを確認します。
sudo iptables -A GATE2 -p tcp --dport 2222 -m recent --name AUTH2 --set -j DROP
これは、最初のゲートとほとんど同じ方法で処理されます。 AUTH2フラグを設定するだけで、正しいポートがノックオンされた場合に、要求元のアドレスが2番目のテストに合格したことを示します。 フラグが設定され、パケットは再びドロップされ、クライアントに進行状況が示されなくなります。
次のルールは、最初は少し奇妙に思えるかもしれません。
sudo iptables -A GATE2 -j GATE1
この時点でパケットをドロップするだけでよいと思うかもしれません。 ただし、これは1つの特定のケースで厄介な状況につながる可能性があります。
ここに「すべてドロップ」ルールがあり、この時点で送信されたパケットが最初のノックターゲットと一致する場合、ノックシーケンスの開始として登録されません。
たとえば、クライアントが誤って最初のポートに2回ヒットした場合、ファイアウォールは次のようなシーケンスを認識するため、正しく登録されません。
- 最初のポートヒット。 ファイアウォールは最初のテストに合格したことを示します。 次に2番目のポートをチェックします。
- 最初のポートヒット。 2番目のポートルールと一致しません。 シーケンスがリセットされます。 次に最初のポートをチェックします。
- 2番目のポートがヒットしました。 最初のポートルールと一致しません。 シーケンスがリセットされます。 次に最初のポートをチェックします。
- 3番目のポートがヒットしました。 最初のポートルールと一致しません。 シーケンスがリセットされます。 次に最初のポートをチェックします。
ご覧のとおり、1番目、2番目、3番目のシーケンスは完了していますが、ファイアウォールはどのルールをチェックする必要があるかについて混乱しています。 このシナリオでは、クライアントは、間違いがあった場合にチェーンをリセットするためだけに、実際のシーケンスを開始する前にダミーの要求を送信する必要があります。
この状況を回避するために、この時点でパケットをドロップして処理するだけではなく、します。 代わりに、すでに構成したGATE1チェーンを活用します。 上で示したように、2番目のノックターゲットと一致しなかったトラフィックを最初のゲートに再度送信するだけです。
sudo iptables -A GATE2 -j GATE1
これにより、シーケンス内のクライアントの位置が2つの方法のいずれかでリセットされます。 要求が最初のポートに対するものである場合、シーケンスは成功した最初のノックとして再開されます。 最初のポートでない場合は、通常どおりドロップされます。 これにより、上記の状況を回避できます。
サードゲートを構成する
2番目のゲートから学んだことを使用して、まったく同じ方法で3番目のゲートを実装できます。
まず、アドレスに与えられたすべてのフラグをクリアして、チェーンを実行すると、以前の古いフラグなしで正しい状態が設定されるようにします。
sudo iptables -A GATE3 -m recent --name AUTH2 --remove
次に、接続の試行が3番目のノックターゲットと一致するかどうかをテストします。 含まれている場合は、AUTH3フラグを設定します。これは、クライアントが必要なすべてのノックを正常に完了したことを示します。 いつものように、後でパケットをドロップします。
sudo iptables -A GATE3 -p tcp --dport 3333 -m recent --name AUTH3 --set -j DROP
ここから、3番目のノックターゲットと一致しなかったトラフィックをもう一度最初のゲートに送り返し、シーケンスを再開するために最初のノックが成功したと見なされるかどうかを確認します。
sudo iptables -A GATE3 -j GATE1
この時点で、正しいノッキングシーケンスを完了したクライアントには、AUTH3のフラグを付ける必要があります。これにより、PASSEDチェーンでクライアントのサービスを簡単に開くことができます。
パスチェーンを構成する
このチェーンは、正しいシーケンスを正常にノックしたクライアントに対してSSHデーモンを30秒間開くために使用されます。
これは他の人と同じように始めます。 SSHデーモンは、クライアントから送信された次のパケットがSSHデーモンを要求している場合にのみ使用できます。 これにより、ノッキングをランダムに乗り越えようとしている人々は、各試行の間にSSH接続を試行するように強制されます。
まず、通常のフラグのリセットを行います。
sudo iptables -A PASSED -m recent --name AUTH3 --remove
次に、このチェーンに参加したユーザーからのSSH接続を受け入れます。
sudo iptables -A PASSED -p tcp --dport 22 -j ACCEPT
ここでも、一致しないすべてのトラフィックを最初のチェーンに送り返して、最初のポートノックターゲットと一致するかどうかを確認します。
sudo iptables -A PASSED -j GATE1
これで、すべてのサブチェーンが構成されましたが、トラフィックをこれらの個々のチェーンに渡す一般的なKNOCKINGチェーンが構成されました。
ノッキングチェーンを構成する
すべてのサブチェーンが構成されたので、それらを一般的なKNOCKINGチェーンにフックして、トラフィックを渡す方法のロジックを作成できます。
まず、すべてのノックを正常に完了したクライアントからのトラフィックをPASSEDチェーンに直接渡します。
ただし、いくつかのオプションがあります。 成功したクライアントにデーモンに接続するための30秒のウィンドウのみを与える時間制限を実装できます。 その後、ルールは正常に一致しなくなります。
sudo iptables -A KNOCKING -m recent --rcheck --seconds 30 --name AUTH3 -j PASSED
次に、他の各フラグを最も制限の厳しいものから最も制限の少ないものまでテストします。 前のノックが期限切れになる前に、10秒の制限時間を追加することもできます。 これには、クライアントがノックの次の段階を10秒以内に完了し、さらに30秒以内にSSHデーモンに接続する必要があります。
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH2 -j GATE3
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH1 -j GATE2
ここで、これまで一致しなかったすべてのトラフィックを通常どおりGATE1に送り返します。 これにより、最初のノックの試みがキャッチされます。
sudo iptables -A KNOCKING -j GATE1
これは基本的に、GATE1ロジックをKNOCKINGチェーンの最後に暗黙的に追加することにより、KNOCKINGチェーンのデフォルトのドロップポリシーを設定します。
この時点で、すべてのノッキングチェーンが配置されています。 ロジックを区分化するために、いくつかの追加の構造を追加しました。 KNOCKINGチェーン構造全体とそのサブチェーンは、通常の入力チェーンに接続されています。
この時点で、ポートノッキングメカニズムが構成されています。 それをテストする時が来ました。
ポートノッキングをテストする
ポートノッキング構成に必要なTCPパケットを生成するために使用できるユーティリティがいくつかあります。 nmap
コマンドは、ほとんどのシステムにデフォルトで存在するため、使用します。
NmapはデフォルトでTCPパケットを使用します。 ただし、これらのパケットがノッキングに干渉しないように、デフォルトの動作のホスト検出部分にドロップするように指示する必要があります。 さらに、次のノックに進むことができるように、接続が1秒後にタイムアウトするようにします。
これらの要件がある場合、1回のノックは次のようになります。 例として最初のノックターゲットを使用します。
nmap -Pn --host_timeout 201 --max-retries 0 -p 1111 your_server
したがって、ノックシーケンス全体を次のコマンドで表すことができます。
nmap -Pn --host_timeout 201 --max-retries 0 -p 1111 your_server nmap -Pn --host_timeout 201 --max-retries 0 -p 2222 your_server nmap -Pn --host_timeout 201 --max-retries 0 -p 3333 your_server
その後、SSHクライアントに接続するのに30秒かかります。
これを少し自動化するために、いくつかの非常に基本的なbashスクリプトを利用できます。 「for」ループを使用してポートシーケンスを反復処理し、SSHクライアントに渡すことができます。
111122223333のxの場合; do nmap -Pn --host_timeout 201 --max-retries 0 -p $ x your_server && sleep 1; 完了&& sshuser @ your_server
これにより、最初のポートがノックされ、2番目のポートがノックされ、次のポートがノックされ、シーケンスが完了するまで続きます。 次に、サーバーのSSHデーモンへの接続を試みます。
これをファイルに入れて、少しクリーンアップすることができます。 これをknock_client
と呼びます。 テキストエディタで作成します。
nanoknock_client
#!/ bin / bah
Ports =“ 1111 2222 3333” host =“ your_server ”
$portsのxの場合donmap-Pn –host_timeout 201 –max-retries 0 -p $ x $ host sleep 1 done ssh user @ $ {host}