DNSサーバーを介してIPv4データをトンネリングし、ファイアウォールの制限を回避して、ペネトレーションテスト用の隠密なネットワークアクセスを提供します。
これは、DNSサーバーを介してIPv4データをトンネリングできるソフトウェアです。インターネットアクセスがファイアウォールで制限されているが、DNSクエリは許可されている様々な状況で使用できます。
iodineをコンパイルするにはmesonが必要です。
buildディレクトリ内でコンパイルするには、以下のコマンドを実行します:
meson setup build
cd build
ninja
テストをビルドして実行するにはcheckライブラリが必要です。ビルドディレクトリ内でninja testを実行して開始します。
自分のLAN内で試してみましょう!以下の簡単な手順に従ってください:
./iodined -f 10.0.0.1 test.com。
すでに10.0.0.0ネットワークを使用している場合は、172.16.0.0のような別の内部ネットを使用してください。./iodine -f -r 192.168.0.1 test.com。
192.168.0.1をサーバーのIPアドレスに置き換えてください。10.0.0.2を、サーバーは10.0.0.1を持ちます。実際にリレーするネームサーバーを介して使用するには、以下を参照してください。
注意:サーバーとクライアントはまったく同じプロトコルを話す必要があります。ほとんどの場合、これは同じiodineバージョンを実行することを意味します。残念ながら、後方および前方プロトコル互換性の実装は通常実現可能ではありません。
このトンネルを使用するには、実際のドメイン(mydomain.comなど)の制御と、iodinedを実行するためのパブリックIPアドレスを持つサーバーが必要です。このサーバーがすでにDNSプログラムを実行している場合は、そのリスニングポートを変更し、iodinedの-bオプションを使用してiodinedにDNSリクエストを転送させます。(この手順は本番環境では推奨されません。iodinedのDNS転送は完全に透過的ではなく、例えばゾーン転送が機能しないためです。)
あるいは、DNSサーバーからサブドメインをiodinedに転送することもできます。その場合、iodinedは別のポート(-p)で実行する必要があります。
次に、サブドメイン(例えばt1.mydomain.com)をiodinedサーバーに委任します。
ドメインにBINDを使用している場合は、ゾーンファイルに以下のような2行を追加します:
t1 IN NS t1ns.mydomain.com. ; ドットに注意!
t1ns IN A 10.15.213.99
NS行は、t1サブドメインのクエリをt1nsサーバーにルーティングするために必要なすべてです。データトラフィックにできるだけ多くのスペースを確保するために、サブドメインには短い名前を使用します。NS行の最後はiodinedサーバーの名前です。これは任意の名前で、どこを指してもかまいませんが、この場合は同じゾーンファイルに簡単に保持できます。名前(IPアドレスではない)である必要があり、その名前自体にAレコード(CNAMEではない)が必要です。
iodinedサーバーが動的IPを持っている場合は、動的DNSプロバイダーを使用してください。単にNS行をそこに向け、A行を省略します:
t1 IN NS myname.mydyndnsprovider.com. ; ドットに注意!
その後、ネームサーバープログラムをリロードまたは再起動します。これで、t1.mydomain.comで終わるドメインのDNSクエリはすべてiodinedサーバーに送信されます。
最後に、サーバー上でiodinedを起動します。最初の引数はトンネル内のIPアドレスで、まだ使用していない任意の範囲(例えば192.168.99.1)から指定できます。2番目の引数は割り当てられたドメイン(この場合はt1.mydomain.com)です。-fオプションを使用すると、iodinedがフォアグラウンドで実行され続け、テスト時に役立ちます。iodinedは仮想インターフェース(「tunデバイス」)を開き、UDPポート53でDNSクエリのリッスンも開始します。コマンドライン(-P pass)またはサーバー起動後にパスワードを入力します。これでクライアントの準備が整いました。
予期しない環境からiodineトンネルを使用する可能性がある場合は、-cオプションを付けてiodinedを起動してください。
この例の状況での結果のコマンドライン:
./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
セットアップはすべて完了しているので、iodineを起動するだけです。1つまたは2つの引数を取り、最初はローカルリレーDNSサーバー(オプション)、2番目は使用したドメイン(t1.mydomain.com)です。最初の引数を指定しない場合は、システムの現在のDNS設定が参照されます。
任意のコンピューターへのDNSクエリが許可されている場合は、iodinedサーバーのアドレスを最初の引数として直接指定できます(例ではt1ns.mydomain.comまたは10.15.213.99)。その場合、任意のコンピューターのDNSポート(53 UDP)への_あらゆる_トラフィックが許可されることもあります。Iodineはこれを検出し、可能であればraw UDPトンネリングに切り替えます。いずれの場合もDNSトンネリングを強制するには、-rオプションを使用します(特に自分のネットワーク内でテストする場合に便利です)。
クライアントのトンネルインターフェースには、サーバーに近いIP(この場合は192.168.99.2または.3など)と適切なMTUが割り当てられます。サーバーと同じパスワードをコマンドラインオプションとして、またはクライアント起動後に入力します。-fオプションを使用すると、iodineクライアントがフォアグラウンドで実行され続けます。
この例の状況での結果のコマンドライン。raw UDPトンネリングが可能であってもDNSトンネリングを強制するために-rを追加:
./iodine -f -P secretpassword t1.mydomain.com
どちらの側からも、トンネルの反対側のIPアドレスにpingできるはずです。この場合、iodineクライアントからping 192.168.99.1、iodineサーバーから192.168.99.2です。
トンネル内のデータはIPv4のみです。
サーバーはデフォルトで受信リクエストに対してIPv4とIPv6の両方をリッスンします。-4または-6オプションを使用して、1つのプロトコルのみでリッスンします。rawモードはログインに使用されたものと同じプロトコルで試行されます。
クライアントはIPv4またはIPv6ネームサーバーを使用してiodinedに接続できます。リレーネームサーバーは必要に応じてプロトコル間を自動的に変換します。-4または-6オプションを使用して、クライアントがDNSクエリに特定のIPバージョンを使用するように強制します。
サーバーがIPv6でリッスンしていて到達可能な場合は、DNS設定にAAAAレコードを追加します。上記の例を拡張すると次のようになります:
t1 IN NS t1ns.mydomain.com. ; ドットに注意!
t1ns IN A 10.15.213.99
t1ns IN AAAA 2001:db8::1001:99
すべてのトラフィックをDNSトンネル経由でルーティングすることが可能です。これを行うには、まずiodineが使用するネームサーバーへのホストルートを、デフォルトゲートウェイをゲートウェイとして有線/無線インターフェース経由で追加します。次に、デフォルトゲートウェイをDNSトンネル内のiodinedサーバーのIPアドレスに置き換え、サーバーをNATを実行するように設定します。
ただし、トンネルされたデータトラフィックはまったく暗号化されておらず、外部の当事者によって比較的簡単に読み取られ、変更される可能性があることに注意してください。最大限のセキュリティのために、DNSトンネル経由でVPNを実行する(=二重トンネリング)か、ポート転送を伴うセキュアシェル(SSH)アクセスを使用してください。後者は、サーバー上でWebプロキシ(例えばPrivoxy)を実行する場合、Webブラウジングにも使用できます。
iodinedサーバーは、トンネルドメインのサブドメインに送信されたNSリクエストに応答します。iodinedサブドメインがt1.mydomain.comの場合、foo123.t1.mydomain.comにNSリクエストを送信して、委任が機能するか確認します。
digはこれに適したツールです:
% dig -t NS foo123.t1.mydomain.com
ns.io.citronna.de.
また、iodinedサーバーは、サポートされているリクエストタイプのいずれかについて、'z'で始まるリクエストに応答します。例えば:
dig -t TXT z456.t1.mydomain.com
dig -t SRV z456.t1.mydomain.com
dig -t CNAME z456.t1.mydomain.com
これらのすべての場合で、応答は文字化けしたテキストのように見えるはずです。
Mac OS X 10.6以降では、iodineはOSに組み込まれたネイティブutunデバイスをサポートしています - -d utunXを使用してください。
DNS応答フラグメントサイズは通常、最大帯域幅を得るために自動プローブされます。特定の値を強制する(そして処理を高速化する)には、-mオプションを使用します。
DNSホスト名は通常、最大長である255文字まで使用されます。完全長のクエリにかなり不安定に応答するDNSリレーが見つかっており、繰り返し試行するとフラグメントサイズの自動プローブで大きく変動する(そしてほとんどが非常に悪い)結果が得られます。このような場合は、-Mスイッチを使用してDNSホスト名の長さを例えば200文字に減らすと、これらのDNSリレーがはるかに安定します。これは、応答にクエリの完全なコピーを2つ詰め込み、下流データ用のスペースをほとんど残さない一部の「非最適化」DNSリレー(EDNS0もサポートしていない)でも役立ちます。-Mスイッチは、上流帯域幅の一部を下流帯域幅と引き換えにすることができます。プロトコルはパケット(最大1200バイト)をわずか16フラグメントに分割でき、フラグメントあたり少なくとも75の実データバイトが必要なため、最小-M値は約100であることに注意してください。
上流データはBase32でgzipエンコードされて送信されます。リレーサーバーがドメイン名に大文字小文字の混在と+をサポートしている場合はBase64、代わりに_がサポートされている場合はBase64u、高バイト値文字がサポートされている場合はBase128です。
この上流エンコーディングは自動検出されます。DNSプロトコルでは1パケットにつき1クエリが許可され、1クエリは最大256文字です。各ドメイン名部分は最大63文字です。したがって、最大の上流スループットを可能にするために、ドメイン名とサブドメインはできるだけ短くする必要があります。
いくつかのDNSリクエストタイプがサポートされており、NULLとPRIVATEタイプが最大の下流帯域幅を提供すると予想されます。PRIVATEタイプはプライベート使用範囲の値65399を使用します。他の利用可能なタイプはTXT、SRV、MX、CNAME、A(CNAMEを返す)で、帯域幅の降順です。
通常、「最良の」リクエストタイプが自動検出されて使用されます。ただし、DNSリレーが例えばNULLとTXTに制限を課す場合があり、SRVまたはMXが実際に最良の選択となることがあります。これは自動検出されませんが、-Tオプションを使用して強制できます。
特に自動検出されたリクエストタイプが200バイト未満の下流フラグメントサイズを提供する場合は、様々な代替案を試すことをお勧めします。
SRV、MX、A(CNAMEを返す)クエリは、「スマートな」キャッシュネームサーバーによる実際のIPアドレスを取得するための追加のルックアップを引き起こす可能性/発生させる可能性があり、速度が低下するか完全に失敗する可能性があることに注意してください。
非NULL/PRIVATEクエリのDNS応答は、上流データと同じコーデックセットでエンコードできます。これも通常は自動検出されますが、完全に網羅的なテストは行われないため、より高度なコーデックを選択する際に一部の問題が見逃される可能性があります。その場合、フラグメントサイズの自動プローブで失敗/破損が発生します。特に、ホスト名を返す応答(SRV、MX、CNAME、A)を、そのホスト名が約180文字を超える場合にのみ小文字に変更するDNSリレーがいくつか見つかっています。これらのおよび類似のケースでは、-Oオプションを使用して他の下流コーデックを試してください。Base32は常に機能するはずです。
現在の通常の動作では、サーバーは次のDNSリクエストが来るまでDNSリクエストに応答_しない_、いわゆる「lazy」モードです。このようにして、サーバーは新しい下流データを送信する必要があるときに常にDNSリクエストを手元に持つことができます。これにより(インタラクティブな)パフォーマンスとレイテンシが大幅に改善され、静止時のpingリクエストをデフォルトで4秒間隔に、場合によってはそれよりもはるかに遅くすることができます。実際、pingの主な目的は、前のpingへの応答を強制し、DNSサーバーのタイムアウト(通常RFC1035あたり少なくとも5〜10秒)を防ぐことです。一部のDNSサーバーはよりせっかちで、トンネルデータトラフィックがない期間にSERVFAILエラー(タイムアウト)を返します。これらの場合でもすべてのデータは通過するはずですが、iodineはエラーメッセージの数を減らすためにping間隔を1秒(-I1)に短縮します。これはdnsadvantage.com(ultradns)のような非常にせっかちなDNSリレー(1秒以下でタイムアウトする)には役立たないかもしれません。それでもデータは通過し、SERVFAILエラーは無視できます。
間にDNSサーバーがないローカルネットワークで実行している場合は、-I 50を試してください(iodineとiodinedは60秒間の沈黙後に接続を閉じます)。速度低下に気づく唯一の時は、DNS応答パケットが失われた時です。その場合、iodinedサーバーはデータを再送信するために新しいpingを待たなければなりません。上流トラフィック(キー入力、ping)を生成することでこれを高速化できます。これが頻繁に発生する場合は、ネットワークのボトルネックを確認するか、-I1で実行してください。
lazyモードでの遅延応答により、一部の「キャリアグレード」商用DNSリレーが同じDNSクエリをiodinedサーバーに繰り返し再送信します。DNSリレーが実際に並列サーバーのプールとして実装されている場合、重複リクエストが複数のソースから到着することさえあります。この効果はiodinedサーバーのネットワークトラフィックでのみ確認でき、クライアントの接続には影響しません。Iodinedはこれらの重複に気づき、(その時が来たら)同じ応答を元のクエリと最新の重複の両方に送信します。その後、完全な応答はしばらくの間キャッシュされます。さらに遅れてサーバーに到着する遅延重複には、iodineクライアントが無視する応答が返されます(そこに到達した場合)。
問題がある場合は、tcpdumpやethereal/wiresharkなどのネットワーク監視ツールでトラフィックを検査し、リレーDNSサーバーが応答をキャッシュしていないことを確認してください。キャッシュされたエラーメッセージは、サーバーより先にクライアントを起動したことを意味する可能性があります。サーバーの-D(および-DD)オプションは、受信および送信されたクエリも表示できます。
特定のインターフェースのポート53が、それを使用しないアプリケーションによって占有されている場合は、iodinedで-pを使用して代替ポート(-p 5353など)を指定し、例えばiptables(Linuxの場合)を使用してトラフィックを転送します:
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
(Tom Schouten氏からの提供)