質問: linux:ドメイン名に基づくルーティング ubuntu 16.04では、ブラウザに入力されたドメイン名に基づいて、直接インターネットeth0または私のvpn tun0を介してトラフィックをルーティングしたいと思います。ローカルサイトである理由は、速度が遅いか、場所によって異なります。カーネルルーティングテーブルはipベースであり、ドメイン名は通常ソフトウェア層で解決されることを理解していますが、linuxはスクリプトフレンドリーなプラットフォームであるため、回避策を期待しています。ただし、そのようなスクリプトの書き方はわかりません。これまでのところ、dig example.com +short @8.8.8.8コマンドはドメインに関連付けられたipを一覧表示し、sudo route add -net 8.8.8.8 netmask 255.255.255.255 gw 192.168.2.1コマンドは特定のipのvpnをバイパスすることがわかりました(192.168.2.1は私のデフォルトeth0)。誰かがドメイン名を含むファイルを読み取り、システムの起動時にルートルールを入力するスクリプトをテンプレート化するのに十分親切でしょうか。マスクされたサブドメインを許可するためのボーナスポイント*.example.com。この狂気にもっと簡単な方法があれば、それを解決策として受け入れます。注:ipを/etc/network/interfacesにハードコーディングすることは非常に簡単ですが、管理が難しくなります。私はまた、自分の国のすべての既知のipをこのファイルにハードコーディングしようとしましたが、起動時間の遅延とともに非常に失敗しました。
回答: 宛先ドメインに基づくルーティングは不可能ではありません。適切なツールを使用すれば、それほど難しくはありません。特別なクライアント側の構成をほとんどまたはまったく必要としないいくつかの方法を紹介します。これらはすべて、openvpnを使用して接続していることを前提としています。これは他のvpnでも実現できるはずですが、vpnを立ち上げた後、さらに手動で構成する必要がある場合があります。例として、非vpn経由でルーティングするドメインには、「example.com」、「us1.example.com」、「us2.example.com」、「geoblocked.com」のドメインを使用しますインターフェース。すべてのコマンドはrootとして実行する必要があります。方法1-openvpnルーティングしているipアドレスに変化しない静的ipがあることが確かな場合にのみ、これをお勧めします。長所: 非常にシンプル 短所: ipが変化しないのドメインに対してのみ信頼できる すべてのドメインとサブドメインの明示的なエントリが必要 方法:openvpn構成に次の行を追加します。route example.com 255.255.255.255 net_gateway route us1.example.com 255.255.255.255 net_gateway route us2.example.com 255.255.255.255 net_gateway route geoblocked.com 255.255.255.255 net_gateway openvpnを再起動します。それだけですが、これらのipアドレスが変更された場合は、vpnを再起動する必要があります。[〜#〜]注[〜#〜]:一部のソースでは、allow-pull-fqdnも指定する必要があると述べていますが、そうではないようです私の経験ではそうです。 ymmv。方法2-ポリシーベースのルーティング ポリシーベースのルーティング は、特定の基準に基づいてルーティングする機能です。通常は送信元アドレスまたはプロトコルですが、この場合はルーティング前に宛先ドメイン名を検査し、マーク付きパケット(「fwmark」)を使用します。したがって、最初に行う必要があるのは、vpnルーティングパケット用に別のテーブルを作成して、vpnを通過するパケットにマークを付け、マークされたパケットを非vpnインターフェースに渡すことです。 (これは1つのアプローチであり、これにアプローチする方法は他にもたくさんあります。たとえば、vpnにメインテーブルを介して通常どおりルーティングを行わせたり、vpn以外のトラフィック用に別のテーブルを作成したりします。)最近のシステムはおそらくデフォルトのカーネルにそれらを持っていますが、カーネルは十分に新しいものであり、適切なモジュールを備えている必要があります。名前「vpn_table」(ルーティングテーブル名)、数字「201」(ルーティングテーブルid)と「3」(fwmark)は任意に選択されます。(ルートとして)新しいルーティングテーブルを作成します。echo 201 vpn_table >> /etc/iproute2/rt_tables openvpnを構成します。次のスクリプトをどこかに作成し(私は "/ etc/openvpn/client/setup-routing"と呼びます)、実行可能にします。#!/bin/bash ip route add 0.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table ip route add 128.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table sysctl -w net.ipv4.conf.$dev.rp_filter=2 # you can optionally leave the next two lines out but run the `ip rule add` # command at each boot instead ip rule del fwmark 3 table vpn_table &>/dev/null # this might fail but that's ok ip rule add fwmark 3 table vpn_table 上記のスクリプトの変数は、openvpnによって環境変数として入力されます。また、これにより、「vpn_table」ルーティングテーブルのvpnゲートウェイを経由するallアドレスへのルーティングが設定されます。 vpn設定でより複雑なルーティングが必要な場合は、openvpnのドキュメントを参照して、適宜調整してください。openvpn構成に以下を追加します。## policy routing route-noexec script-security 2 route-up /etc/openvpn/client/setup-routing 「route-noexec」行は、openvpnがサーバーからルートをフェッチすることを許可しますが、実際にルートを生成することを防ぎます。代わりに、ルートアップスクリプトが呼び出されます。ユーザー定義のスクリプトを呼び出すには、「script-security 2」が必要です。これが、マークされたパケットをルーティングするために必要なすべての設定ですが、実際にパケットをマークする方法を設定する必要があります。 2つのオプションは、ipsetでdnsmasqを使用するか、squidプロキシを設定することです。方法2a-ipsetとdnsmasqを使用したポリシーベースのルーティングこれをすでにdnsmasqベースのルーターで実行している場合、またはクライアントがプロキシ構成をサポートしていない場合は、この方法をお勧めします。これは、ドメイン名が検索されるたびにルーティングテーブルを更新するキャッシュdnsと実質的に同じです。長所: サブドメインを処理します プロキシにアクセスできないデバイスで動作します(プロキシは存在しますか?) 短所: リファラーフィールドを処理しません(方法2bを参照) 複雑なipsetおよびiptables構成が必要 vpn接続システムをルーターとして設定する必要があります(専用インターフェースが必要) 私はスケーラブルなipsetがどれほどかわかりません(私のユースケースはcctld全体です) これは、dnsmasqがすでに構成および設定されており、専用インターフェース「eth1」に接続されたクライアントのゲートウェイおよびdnsサーバーとして機能していることを前提としています。ipsetを作成します。ipset create skip_vpn_ipset iphash iptablesにipsetパケットをマークするように指示します(n.b.、これは実行する必要がありますipsetリストを作成した後後):# mark all packets coming in on eth1 - change this to the interface dnsmasq listens on iptables -a prerouting -i eth1 -t mangle -j mark --set-mark 3 # remove mark on any addresses that match our ipset iptables -a prerouting -t mangle -m set --match-set skip_vpn_ipset dst -j mark --set-mark 0/3 [〜#〜]注[〜#〜]:上記のコマンド(ipsetおよびiptables)は、起動ごとに実行します。あるいは、ご使用のosがiptableルールとipsetsを保存/復元するためのいくつかのオプションを提供する場合があります。note2:逆! --match-setが文書化されていますが、これを実行すると、すべてのパケットが表示されなくなりました。以下をdnsmasq.confに追加します。ipset=/example.com/geoblocked.com/skip_vpn_ipset 当然、ルーティングしたいドメイン名を問わず、その行も調整します。これにより、[〜#〜] all [〜#〜]サブドメインもipsetに追加されるため、明示的に指定する必要はありません。 tldを使用しても機能します。dnsmasqを再起動し、vpn接続されたシステムをゲートウェイとdnsの両方として使用するようにクライアントを設定します(dhcpサーバーとして設定されている場合は、暗黙的に表示されます)。方法2b-ポリシーベースのルーティング squidを使用 これは私のお気に入りの方法で、ps4や接続に使用する他のデバイスでうまく機能します。長所: サブドメインを処理します リファラーフィールドを処理します 既存のルーターを交換する必要はありません クライアント(ブラウザ)はオプションでそれを使用できるかどうか 短所: クライアントはプロキシ接続をサポートする必要があります これは、squid設定が機能していて、squid構成の基本的な知識があることを前提としています。次の行をsquid.confに追加します。# redirect example domains acl domain_to_remote_proxy dstdomain .example.com acl ref_to_remote_proxy referer_regex [^.]*\.example.com.* # redirect geoblocked domain acl domain_to_remote_proxy dstdomain .geoblocked.com acl ref_to_remote_proxy referer_regex [^.]*\.geoblocked.com.* # mark packets that we want routed through the vpn tcp_outgoing_mark 0x03 !ref_to_remote_proxy !domain_to_remote_proxy ドメインごとに2行あり、サブドメインが一致することに注意してください。 1行目は宛先ドメインをチェックし、2行目は「referer」ヘッダーと一致します。ブラウザは、画像、css、javascriptなどのwebページ上のコンテンツをフェッチするときにリファラーを送信するので便利です。つまり、サイトによって要求されたコンテンツは、別のドメイン(example-cdn.comなど)でホストされている場合でも、非vpnアドレスを経由してルーティングされます。クライアントで、通常のように接続を設定しますが、このシステムのプロキシサーバーとポートを使用するようにプロキシ設定を設定します。ほとんどのデバイス(ゲームコンソールを含む)では、システム全体の構成が可能です。 pcでは、ほとんどのブラウザは、システム設定とは関係なくプロキシを使用するように構成できます。最後の注意-実際の使用例は、特定のドメインをvpn経由でルーティングし、それ以外のすべてを非vpn経由でルーティングすることです。方法は上記と同様ですが、逆になっています。