iptablesベースのOpenVPNの強制終了スイッチ

オープンWi-Fiネットワークに接続すると、トラフィックを簡単に聞くことができることが知られています。 もちろん、現在ではますます多くのサイトがHTTPSを使用しています。 ただし、これはまだ100%にはほど遠い状態です。 このようなオープンWi-Fiネットワークに接続するとき、トラフィックを保護したいという自然な欲求があります。



この問題の一般的な解決策は、VPNを介した接続です。 この場合、トラフィックは暗号化された形式でVPNサーバーに送信され、そこからインターネットに送られます。



このソリューションには小さな欠点があります。VPN接続はまだ確立されていませんが、コンピューター上のすべてのアプリケーション(開いているブラウザータブを含む)は、VPN接続をバイパスしてインターネットにアクセスできます。



この記事では、これを回避する方法を説明します。



アイデア



この問題をどのように解決しますか?



一般的に、2つの例外を除き、すべてのアプリケーションへのすべてのネットワークアクセスをブロックします。 これはiptablesで行います。



最初のポイントが非常に簡単に解決される場合、2番目のポイントは問題を提起します。 iptablesでは、プロセスの名前に一致するルールを作成できません。



すべてのプロセスについて、iptablesがVPNサーバーのハードコーディングされたIPへのアクセスを許可できます(このIPを介して他の接続が確立されていないことを前提としています)。 ホスト名を介してサーバーに接続することができないため、この解決策は不適切です。 さらに、キャプティブポータルに問題があります。 アクセスポイントで最初にWebページに移動し、そこで[同意する]をクリックする必要がある場合は、手動で例外を登録する必要があります。 したがって、このソリューションは理想とはほど遠いものです。



1つの解決策は、グループの使用に基づいています。 iptablesは、これらのパケットを送信したプロセスのGIDでパケットを照合できます。 このソリューションは非常にシンプルで効果的です。 しかし、あるプロセスが突然GIDを変更したい場合、すぐにインターネットにアクセスできなくなります。



2番目のオプションは、cgroupを使用することです。 特別なcgroupを作成して、インターネットへの無料アクセスを必要とするプロセスを配置できます。そのようなプロセスによって送信されるすべてのパケットには、iptablesで一致するラベルが付けられます。 このアプローチの利点は、プロセスグループを変更する必要がないことです。プロセスグループは他の目的に使用できます。 特定のcgroupをnet_clsサブシステムに割り当てることのみが必要です。 さらに、通常のグループのオプションとは異なり、プロセスを再起動することなく、あるcgroupから別のcgroupに「外出先で」転送できます。 この方法の短所:より複雑なセットアップ、最近リリースされたiptables v1.6.0が必要です(ほとんどのディストリビューションにはまだ追加されていません)。



通常のグループのオプションについて詳しく見ていきます。投稿の最後で、cgroupでこれをどのように行うかを簡単に説明します。



必要条件



OpenVPNベースのVPNがすでにあり、すべてのトラフィックを通過できると想定されています(たとえば、redirect-gateway def1オプションを使用)。



また、CONFIG_NETFILTER_XT_MATCH_OWNERとiptablesを備えたかなり新しいカーネルがあると仮定します。



iptablesのセットアップ



まず、特別なグループを作成する必要があります。 それをkillswitchと呼びます。
groupadd --system killswitch
      
      





次に、iptablesルールを追加します。
 iptables -A OUTPUT -m owner --gid-owner killswitch -j ACCEPT iptables -A OUTPUT -o tun0 -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
      
      



ここで何が起こっていますか?
  1. GID killswitchを使用してプロセスによって送信されたパケットは、ネットワークに渡されます。
  2. tun0インターフェイス上のパケットは無条件でスキップされます。 これは、VPN接続の上に実装されているのと同じネットワークインターフェイスです。 このネットワークインターフェイスに別の名前がある場合(OpenVPN構成のdevオプションを使用すると、tunNではなく固定名を付けることができます)、上記のiptablesルールで変更します。
  3. loインターフェイス上のパケットは同じ方法でスキップされます。 loは、既知の127.0.0.1(localhost)が配置されているループバックインターフェイスです。 一部のアプリケーションはlocalhostを使用してプロセス間で通信するため、ブロックすることは望ましくありません。
  4. 他のすべてのパケットはブロックされます。 この場合、ICMPパケットの「管理上禁止」の送信でブロッキングが発生します(エラーコードは重要な役割を果たしません)。 この場合、プログラムはすぐにエラーを受け取り、タイムアウト前にハングしないため、これは単にパケットをドロップするよりも優れています。


すべてがうまくいけば、この時点でインターネットにアクセスできなくなっているはずです。



インターネットにアクセスできるプログラムを実行するには、sgユーティリティを使用できます(このグループにユーザーを追加する場合は、sudoを使用せずに呼び出すことができます)。 このグループがメイン(有効なGID)になるまで、プロセスはVPNなしではインターネットにアクセスできません。 iptablesは補足GIDをチェックしません!
 sg killswitch 'ping ya.ru'
      
      



あとは、sgを使用して内部でOpenVPNクライアントを実行するだけです。
 sg killswitch 'openvpn config.ovpn'
      
      



それだけです! この時点から、他のすべてのプログラムでインターネットを獲得しているはずです。



ボーナス:キャプティブポータル



インターネットにアクセスするには、最初にブラウザのページに移動して、たとえばモスクワの地下鉄のように「同意する」をクリックする必要がありますか?



この問題は簡単に解決できます。 OpenVPNクライアントが起動するように、他のアプリケーションを実行できます。



そのため、そのような場合には、永久プライベートモードの特別なFirefoxプロファイルがあります。 sg killswitchを介して実行すると、VPNなしでインターネットにアクセスすることもできます。
 sg killswitch 'firefox -P my_special_profile_name -no-remote'
      
      





ボーナス:cgroups



cgroupsベースのソリューションには、iptables v1.6.0およびCONFIG_NETFILTER_XT_MATCH_CGROUPオプション付きのカーネルが必要です。
 cgcreate -g net_cls:killswitch #  cgroup killswitch   net_cls echo 0x00100001 > /sys/fs/cgroup/net_cls/killswitch/net_cls.classid #  ,     (10:1) chmod 666 /sys/fs/cgroup/net_cls/killswitch/tasks #        cgroup iptables -A OUTPUT -m cgroup --cgroup 0x00100001 -j ACCEPT iptables -A OUTPUT -o tun0 -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited cgexec -g net_cls:killswitch ping ya.ru cgexec -g net_cls:killswitch sudo openvpn config.ovpn cgexec -g net_cls:killswitch firefox -P my_special_profile_name -no-remote
      
      



次のコマンドを使用すると、Firefox VPNを使用せずにインターネットアクセスを発行してから、再度アクセスできます。
 pgrep -w firefox | xargs cgclassify -g net_cls:killswitch pgrep -w firefox | xargs sudo cgclassify -g net_cls:/
      
      





ボーナス:xtables-addons条件



自宅または職場でVPNを介して座っている必要は特にありません。 -m condition --condition killswitch



最後のiptablesルールに追加されたxtables- -m condition --condition killswitch



(REJECTを使用)は、 echo <0|1> > /proc/net/nf_condition/killswitch.



介してkillswitchを簡単に切り替え可能にしecho <0|1> > /proc/net/nf_condition/killswitch.







おわりに



この記事では、iptablesを使用してkillswitchを実装するための2つのアプローチ、通常グループとcgroupを検討しました。 両方のオプションは非常に柔軟に機能し、必要に応じて、VPNなしで任意のプロセスがインターネットにアクセスできるようにします。 両方のアプローチはほぼ同等ですが、cgroupsを介した方法は設定が少し難しく、非常に新しいiptablesが必要ですが、プロセス中にアクセスを直接発行および撤回することができます。



All Articles