web-dev-qa-db-ja.com

ホスト名または発信元IPに基づく動的ポート転送

私は私のドメインを超えていくつかのものを理解しようとしているプログラマーです:

私が1台のマシンを持っていて、クライアントがそれにtcp(httpではない!)接続を行うとします。接続するホスト名に基づいて、クライアントを独自のポートにリダイレクトしたい。たとえば、client1はclient1.myserver.comに接続し、ポート1234に接続します。client2.myserver.com-> 1235、client3.myserver.com-> 1236など。

ホストyが実際に物理マシンのポートzを指すように、ポートxを動的に制御したい。

この情報をグーグルで調べていると、ファイアウォール、プロキシ、リバースプロキシへの参照が表示されます。実際にどのソフトウェアが必要ですか?既存のソフトウェアはそのような変更をオンデマンドで許可しますか(1日を必要とするファイアウォールの変更があると聞きました)?

私がそのような層を自分で書きたい場合は(少しアプリケーション固有かもしれないので)、Javaまたはnode.jsで行うことができます(つまり、より高レベルのAPIを使用して行うことができます)または、IPパケットの分解を開始する必要がありますか?)すべてのホスト名が同じマシンに解決されるため、クライアントが接続しているホスト名を知るにはどうすればよいですか?

どんな読書資料へのポインターも同様に感謝します。

7
user23398

IPレベルでは、ホスト名などはありません。ホスト名は、IPアドレスをアプリケーションレベルで抽象化したものであり、インターネットまたはトランスポート層では意味を持ちません。

HTTP共有ホスティングでは、このトリックは[〜#〜] http [〜#〜]の会話を処理するプロセスで抽象化されます。これはafter = TCP会話が開始されます。このため、SSL会話はHTTPアドレスの前に行われるため、SSLサーバーの実行には長い間専用IPアドレスが必要でした(これは、新しいTLSリリースで修正されています。 HOSTNAMEがSSLネゴシエーションの一部として含まれるようになりました)。

共有ホスティングHTTPインスタンスの場合、プロトコルはおおよそ次の順序でネゴシエートされます。

TCP -> SSL -> HTTP

以前のプロトコルが完了するまで、各プロトコルを開始できません。最近まで、チェーンの最後のステップでのみホスト名が認識されていました。そのため、ホスト名とIPの多対1の関連付けを処理するのはWebサーバーソフトウェアにかかっていました。

動的ポート転送の場合、これはアプリケーションプロトコルがホスト名を何らかの方法で認識している場合にのみ実行できます。一部のデバイス(ソフトウェアまたはハードウェア)は、クライアントとの最初のTCP=接続と、それが何であれ)アプリケーションプロトコルの最初のステップを処理し、何に基づいて最終的な宛先に接続を転送します。受け取った。

必要な正確な手順は、アプリケーションプロトコル自体によって異なります。 HTTPなどの一部には、クライアントが通信することを期待しているホスト名を示すHOSTNAMEヘッダーが含まれています。一部のMicrosoftプロトコルのように、DNSベースのSRVレコードを利用して、正確なIP およびポートの組み合わせを特定するものもあります。独自のアプリケーションプロトコルを最初から設計しているように思えるので、HTTPのリードに従い、最初のプロトコルネゴシエーションステップにHOSTNAMEヘッダーを含めることをお勧めします。

11
sysadmin1138

DNSのSRVレコードを使用すると、これを最も簡単に実現できます。

http://en.wikipedia.org/wiki/SRV_record

2
Chris Thorpe

何をしようとしているか、その理由をより明確に説明できますか? 「なぜ」が大いに役立ちます。クライアントは何ですか?プロトコルとは何ですか?

プロトコルとデータストリームに基づいてこれを行う多くの方法があります。

Pf、iptables、またはebtablesインジェクションを検討してください。例については、「sshブラックリスト」を参照してください。一般的なリダイレクトについては、LVS、HAproxy、その他のロードバランサーを確認してください。

古いトリックは「ウェイクアップ」システムです。これは、SSHまたは他の暗号化されたプロトコルに最適であり、ソースドメインを特定するためのCPU負荷が高くなります。

  • 開いている単一のポートにSSH接続(端末サポートは不要)
  • userXとして(できればキーを使用して)システムにログインします。これにより、ポートXXXXXでサーバーの別のインスタンスを起動し、クライアントに新しいポート番号で応答するスクリプトが実行されます。
  • 「ポートXXXXXが開いています」メッセージがクライアントに転送され、最初のSSHセッションが閉じられます
  • クライアントまたはクライアントアプリは、現在開いているポートXXXXXを使用して再接続します
  • クライアントがポートXXXXXで代替インスタンスを切断すると、ポートXXXXXが閉じられます。

キー/ユーザー、逆引き、メッセージパッシングなどに基づいて特定のポートを割り当てることができます。一部のインスタンスは、pf/iptablesファイアウォールインジェクションを使用して、インスタンスを実行したままにして開閉します。ファイアウォールルールを使用してこれを拡張してサービスの起動をトリガーし、指定されたポートが特定のタイプのパケットでpingされるまで、初期SSH(または他のサービス)を実行しないものもあります。ファイアウォールとの動的な相互作用を少なくするために、「最近一致した」カスタムファイアウォールルールを使用して、迷惑パケットをブロックし、サーバーインスタンスを停止/開始します。

このアイデアは、コード化またはスクリプト化できる任意のプロトコルとサービスで機能します。

TCP/IPネットワーキングの資料を読む:W.リチャードスティーブンスが作成または推奨したもの。 http://www.kohala.com/start/

SSHトンネルを開発中の一時的停止として使用することを割引しないでください。これらは、コードなしで必要なすべてを実現できます。あなたのアプリは何ですか?安全な通信ではないでしょうか?スクリプトキディハッカーをどのようにブラックリストに登録しますか?それはあなたが書いてデバッグしなければならないより多くです。とにかくコードを区分化する必要があるので、トランスポート、ポート転送、暗号化、使用状況ログ、ブラックリストなどとしてSSHを使用して他のすべてを開発します。次に、他のすべてが完了したら、SSHを置き換える独自のネットワークプロトコルメカニズムを記述します。ゲートウェイSSHサーバー上のユーザーがトンネルを使用するための端末アクセスは必要ありません。

1
joe