実際、インターネットの切断はすぐには検出されませんでした。 この日、私は郵便や友人との通信を積極的に使用しました。 メールは問題なく動作し、jabber.ruサーバーでXMPPを介して高速メッセージを実行しましたが、インターネットの基本的な楽しみは利用できず、利用可能なすべての条件下で、アイデアはすぐに生まれました。
VPNはどのように機能しますか?
VPNトンネルの原理を理解するには、もちろん「同じ検索エンジン」を使用するためにインターネットにお金を払わなければなりませんでした。 基本的に、トンネルは「仮想ネットワークドライバー」 -TUNおよびTAPを使用して構築されることが判明しました。 TAPはイーサネットデバイスをエミュレートし、OSIモデルのリンク層で動作し、イーサネットフレームで動作します。 TUN(ネットワークトンネル)は、OSIモデルのネットワークレベルで動作し、IPパケットで動作します。 TAPはネットワークブリッジの作成に使用され、TUNはルーティングに使用されます。 それがいかに素晴らしいかをよりよく理解するために、OSIモデルに存在するレベルを思い出させてください:
OSIデバイスモデル
ネットワークレベルをエミュレートすることで、上記のすべてのレベル、つまりトランスポート、セッション、プレゼンテーションレベル、アプリケーションレベルにパフォーマンスを提供できることがわかりました。 最後の2つのレベルは、HTTP、FTP、SSH、SMB、Skype、BitTorrentなど数百ものプロトコルです。 さらに、他のレベルの作業とプロトコルを提供します。SSL、TLS。 PPTP、L2TP; TCP、UDPなど。 つまり 仮想ネットワークはほぼ本格的なネットワークになり、クライアントアプリケーションから直接データを取得してインターフェイスにデータを送信できます。
トゥルーしないでください
このミニプロジェクトは広く使われたり配布されたりするふりをしていないので、私にとって便利なツールキット、NodeJS、node-tuntap、node-xmppを用意しました。 通常の場合、Linuxでは、TUNおよびTAPインターフェースの操作は、デバイスファイル/ dev / net / tunおよび/ dev / net / tapを介して行われます。
問題について事前に
node-tuntapのコンパイルされた部分は不安定で、Segfaultでしばしばクラッシュします。 誰かがデバッガーを実行し、モジュロを見て、問題が何であるかを理解していればいいでしょう。 Githubモジュール: github.com/binarysec/node-tuntap
行こう!
ネットワークでは、tunインターフェイスを使用することにしました。 これを使用する方が簡単です。パケット送信のシーケンスと送信先を監視する必要はありません。 また、このインターフェイスでは、IPアドレス、ゲートウェイアドレス、およびサブネットマスクを事前に設定できます。
インターフェイスの初期化と接続は次のように実行されます。
var tuntap = require('node-tuntap'); try { var tt = tuntap({ type: 'tun', name: 'tun2', mtu: 1500, addr: '192.168.123.1', dest: '192.168.123.2', mask: '255.255.255.192', ethtype_comp: 'none', persist: false, up: true, running: true, }); } catch(e) { console.log('Tuntap creation error: ', e); process.exit(0); }
(もちろん、スーパーユーザーから)このコードを実行した後、システムに新しいネットワークインターフェイスを取得します(スクリーンショットでは、tun2と呼ばれています)。
まったくない! 数行のコードとデバイス全体!
node-tuntapモジュールの便利さは、Streamオブジェクトのインスタンスとしてネットワークインターフェースを操作できることです。したがって、単純なtt.write()でインターフェースにデータを書き込み、tt.on( 'data')イベントでストリームからデータを受信できます。
Xmpp
ネットワークをテストするには、ethernet @ jabber.ruおよびethernet@xmpp.ruという2つの追加のジャバーアカウントを登録する必要がありました。 パケット交換は、XMPPメッセージを介して行われます。 メッセージはテキストであり、インターフェイスから取得するデータはバイナリであるため(さらに、NodeJSではバッファーとして表示されます)、データはBase64でエンコードされ、到着時にバッファーにデコードされます。
バージョン6より前のNodeJSでは、次の方法でこれを行うことができました。
new Buffer(data).toString('base64') // , new Buffer(message, 'base64') //
最後のステップ:ネットワークインターフェイスからデータを受信し、リストから連絡先に送信します。これを条件付きでgatewayContactと呼びます。
xmpp-clientを使用してjabberサーバーに接続します。
var Client = require('xmpp-client').Client; var c = new Client({ jid: login, // , ethernet@xmpp.ru/jabber.ru password: password // }, function() { console.log("I'm connected"); // this.addListener('message', function(from, message){ console.log('Message from ' + from + ': '+message); }); });
コードの両方のブロックを結合することは残っており、次のようになります。
/** Ethernet over XMPP */ var login = 'ethernet@jabber.ru'; // var password = ' '; //, var gatewayContact = 'ethernet@xmpp.ru'; // , - var idAdress = '192.168.123.3'; // IP (, ) var interfaceId = 'tun2'; // //****************************************************** var tuntap = require('node-tuntap'); try { var tt = tuntap({ type: 'tun', name: interfaceId, mtu: 1500, addr: idAdress, dest: '192.168.123.2', // , mask: '255.255.255.192', ethtype_comp: 'none', persist: false, up: true, running: true, }); } catch(e) { console.log('Tuntap creation error: ', e); process.exit(0); } var Client = require('xmpp-client').Client; var c = new Client({ jid: login, password: password }, function() { console.log("I'm connected"); tt.on('data', function(data){ console.log('>>> Send packet'); // c.message(gatewayContact, new Buffer(data).toString('base64')); //, }); this.addListener('message', function(from, message){ if(from.indexOf(gatewayContact) !== -1){ // console.log('<<< Recived packet'); tt.write(new Buffer(message, 'base64')); // , } }); });
利益!
テスト中
- 仮想マシンの1つは192.168.123.3、2番目の192.168.123.1はアドレスです
- 仮想マシン間には、ルーターの背後にある通常のネットワークと、通常のインターネットがあります。 これはテスト結果に影響を与えないと考えています。
- スクリーンショットは複数のテイクで作成されました
まず、pingをテストします。
見て、うまくいく!
現実に近いものはどうですか? HTTPプロトコルを使用してみましょう。
Lighttpdをインストールして実行します。
テスト:
ほほほ
より複雑な:
起動!
速度について少し
habrロゴの平均ダウンロード速度は957バイト/秒でした。 このような速度でインターネットにアクセスすることは、控えめに言っても快適ではありませんが、目標は達成されたと思います。
窓
お気づきかもしれませんが、すべての開発とテストはLinux Ubuntuで行われました。 選択にはいくつかの要因があります。
- カーネルに組み込まれたTUN / TAPドライバー
- Linuxでは、TUN / TAPドライバーを操作するのが簡単であり、NodeJS用の既製のモジュールが既にありました。
- インターネットがVPNを介して機能するようにルーティングを構成する方が簡単です
それにもかかわらず、Windowsの問題を解決することはそれほど難しくありません。 TUN / TAPドライバーの実装はいくつかありますが、最も人気のあるものはOpenVPNプロジェクト用に書かれており、アクセス可能で理解しやすいドキュメントがあります。 OpenVPNドライバーのサポートは、同じnode-tuntapモジュールに追加するといいでしょう。
おわりに
もちろん、XMPPを介したVPNのこの実装はかなり遅いです。 テストのために、ホストマシンを介してSocketIOで動作する実装を作成しました。この場合、速度は正常でした。 それにもかかわらず、私はあなたが考えることなくとることができる行動の責任を思い出し、記事のすべての資料は情報提供のみを目的として提示されています。
UPD
npmおよびgithubにプロジェクトを追加しました
https://www.npmjs.com/package/pppoverxmpp
https://github.com/lailune/PPPoverXMPP