DTLS に基づいた非常にシンプルな IP トンネル。
強力な暗号化が必要ない場合は、より軽量な uun? の使用を検討できます。
go install github.com/taoso/dtun/cmd/dtun
# 服务端
dtun -key foo
# 客户端
dtun -connect addr:port -key foo
以下に、考慮すべきいくつかの要素の簡単なリストを示します。
安定した信頼性の高いトランスポート層のデータ暗号化を実現するのは簡単ではないため、私は常に基盤となるプロトコルとして TLS を使用してきました。
TLS は TCP を使用しており、暗号化されたデータも大部分が TCP データです。このように、上位層のデータ パケットを送信するには、内部および外部の TCP 接続の確認が必要です。この種の TCP over TCP の実装上の問題は小さくありません。詳細については、参考資料 http://sites.inka.de/~bigred/devel/tcp-tcp.html を参照してください。
したがって、UDP 送信を使用するのが最適です。当然、暗号化にはDTLSが使用されます。現在、DTLS は 1.3 をサポートしておらず、Go 言語も正式にサポートしていません。このサードパーティ実装のみを使用できます https://github.com/pion/dtls
TLS であっても DTLS であっても、通常は証明書を作成する必要があります。このプロセスは現在無料ですが、設定は依然として複雑です。さらに、証明書は暗号化の問題を解決するだけであり、認証の問題は解決しません。通常、クライアントのみがサーバー証明書を検証します。サーバーにクライアント証明書を検証させることもできますが、これは面倒です。
さらに、DTLS はコネクションレス型であり、TCP 接続のように接続を作成するときにのみ認証を行うことはできません。
したがって、DTLS ハンドシェイク中に両端の認証を同時に完了することが最善です。そこで、Pre-Shared Key (PSK) モードを選択します。 -key
使用して両端のマスター キーを指定するだけで、二重端認証が完了します。クライアントが PSK を知らない場合、DTLS セッションを確立できません。
さらに、PSK はヒント パラメーターを指定する必要もあります。単純に PSK の名前と考えてください。 DTLS が接続されていないため、クライアントがオフラインになったかどうかを判断するのは困難です。各クライアントに一意のヒント パラメータを持たせることにしました。サーバーはヒント用に tun デバイスを割り当てます。クライアントが切断されて再接続された場合、複数の tun デバイスは作成されません。ただし、同じ hinit のクライアントは同時にログインできないという副作用があります。
macos をサポートするには、tun デバイスはポイントツーポイント モードにのみ設定できます。透過的なルーティングと転送を実行したい場合は、下の図を見てください。
pc <-----------> router <====== dtun ======> pc2 <---------> www
10.0.0.2/16 10.0.0.1/16 10.1.0.1/16 10.1.0.2/16
pc から送信されたパケットがルーターを介して pc2 に転送され、その後外部ネットワークに転送されることを期待します。通常、NAT はルーターで 1 回実行され、次に PC2 で 1 回実行されます。この利点は、pc2 がルーターに対する PC のネットワーク構成を知る必要がないことです。しかし、欠点も明らかであり、2 つの点があります。一般にルーターの性能は高くないため、NAT はできるだけ避けたほうがよいでしょう。
したがって、私の計画は、PCが配置されているネットワークセグメント10.0.0.0/16をPC2に直接プッシュし、PC2にルートを追加することです。
ip route add 10.0.0.0/16 via 10.1.0.1
このようにして、ルーターはパケットを PC から PC2 にそのまま転送することができ、PC2 上で NAT を 1 回実行するだけで済みます。
場合によっては、ルーティング ホワイトリストを指定する必要があります。ホワイトリスト内のネットワーク セグメントのデフォルト ルートを使用し、その他のルートはトンネル経由で転送します。
まずホワイトリスト ルートをルーターに追加し、ネクスト ホップをルーターのデフォルト ルートに設定します。 次に、ルーターのデフォルト ルートをとるように、pc2 のパブリック IP を指定します (キー!)。 最後に追加された
ip route add 0.0.0.0/1 via 10.1.0.2
ip route add 128.0.0.0/1 via 10.1.0.2
ここでの0.0.0.0/1
と128.0.0.1/1
ネットワーク セグメント全体をカバーするだけで、その効果はデフォルトと同等ですが、デフォルト ルートは上書きされません。トンネルが異常終了した場合、関連するルートはすべて自動的に削除されるため、非常に安定しています。
これをスクリプトとして作成し、 -up
パラメーターを使用して実行できます。私のスクリプトは次のとおりです。
#! /bin/sh
# curl -S https://cdn.jsdelivr.net/gh/misakaio/chnroutes2@master/chnroutes.txt|grep -v '#'|xargs -I % ip route add % via $DEFAULT_GW 2>/dev/null
VPN_IP= $( ping your-server-name -c 1 | grep from | cut -d ' ' -f4 | cut -d: -f1 )
DEFAULT_GW= $( ip route | grep default | cut -d ' ' -f3 )
ip route add $VPN_IP /32 via $DEFAULT_GW
ip route add 0.0.0.0/1 via $PEER_IP
ip route add 128.0.0.0/1 via $PEER_IP