ユーザーごとにVPNを個別に使用するには:

ユーザーごとにVPNを個別に使用するには:

マルチユーザー設定(Ubuntu)があります(他のTTYに同時にログインしているユーザー)。

アカウントを使用して NordVPN に接続すると、nordvpn connectすべてのユーザーがその VPN を介してインターネットに接続できるようになります。

どうすればユーザーのネットワークを切断できますか?つまり、VPNに接続するときは、現在のユーザーだけが影響を受け、そのユーザーへのすべての接続はVPNを使用する必要があります。


  • nordvpnopenvpn直接接続で動作するラッパーなので、openvpn純粋なopenvpnソリューションも役立ちます。
  • .rootを介したユーザーアクセスsudo
  • スクリプトソリューションに満足しています。

答え1

ユーザーごとにVPNを個別に使用するには:

ユーザーが別のユーザースペースを使用する状況:

デフォルトでは、ユーザースペースはネットワークを分離します(ネットワーク)、したがってnordvpn connect他のユーザースペースには影響しませんが、これはLinux上のユーザーシステムの基本機能ではないため、各ユーザーのネットワークを分離するには異なるユーザースペースを設定する必要があります。さらに、ネットワークインターフェースは単一の名前空間にのみ存在できます。インターフェイスのブリッジまたは veth は、ユーザ空間間でトラフィックを転送するために使用されます。

ユーザーが同じユーザースペースを使用している場合:

Linuxユーザーシステムは同じネットワークシステムに残ります。あるユーザーが Wi-Fi に接続すると、ネットワーク カードがルート レベルに設定され、既定の設定でネットワークを使用するすべてのユーザーと共有されるため、他のユーザーがその接続の利点を享受できます。

VPN接続は新しい仮想インターフェイス(tunまたはtap)を介して行われ、デフォルトのネットワークインターフェイス(wifiまたはeth0)に接続されます。トンネルを作成しますが、これはすべての接続がVPNインターフェイスを介してトンネリングされるという意味ではありません。一般的なVPN接続が機能するには、まず仮想インターフェイスを使用して接続を初期化し、路線VPNインターフェイスを介してすべての接続を強制するために追加され、それを呼び出します。ルーティング

この情報がわかったら、VPN接続を開始せずにソリューションを起動します。ルーティング次に、各ユーザーに対して個別にルーティングを設定します。 VPNを必要としないユーザーは変更する必要はなく、VPNを使用する必要があるユーザーの場合は、iptables / ip-routeを介して特別なパスを追加する必要があります。つまり、VPNインターフェイスは設定されていますが、デフォルトインターフェイスにはなりません(デフォルトのVPNルーティングルールがプッシュされないため)。

VPN デフォルト:[Connect Command] > [Create-Tun/Tap] > [Tun/Tap 接続] > [Tun/Tap をプライマリインターフェイスのパスに設定]

ムラウティング VPN:[Connect Command] > [Create-Tun/Tap] > [Connect Tun/Tap]

カスタムルーティングを含むVPN:[Connect Command] > [Create-Tun/Tap] > [Connect Tun/Tap]それから[カスタムパス]を手動または自動で追加

「ルーティング」ステップを使用せずにVPNに接続し、カスタムパスをプッシュ/設定します。これは、iptables / ip-routeまたはVPN conf設定ファイルを使用して実行できます。

デフォルトゲートウェイ/パスをプッシュせずにopenvpnを設定するには:

VPN設定ファイルを編集してroute-nopullディレクティブを追加します。 (nordvpnコマンドを使用してopenvpn confファイルにアクセスできる場合は、必要に応じて編集できます。そうしないと、openvpnまたはネットワーク管理者を使用してVPNに接続する必要があります)

特定のLinuxユーザーには特定のインターフェースを使用してください。

このガイドあなたが達成したいのと同じことを達成しています。そうでなければその答え詳細な選択肢を提示してください。

答え2

部分的な回答(詳細が必要です):

「一般」インターネット接続とNordVPNインターネット接続を区別する1つの方法は、ネットワークネームスペースを作成し、nordvpnこのネームスペースから開始し、このネームスペースでこのVPNを使用する必要があるすべてのプロセスを開始することです。

詳細は使用方法によって異なります。

  • NordVPNを常に起動するユーザーがいる場合は、ログイン時にネットワークネームスペースを作成し、そのネットワークネームスペースからそのユーザーのすべてのプロセスを開始できます。したがって、ユーザーは「通常の」インターネット接続を使用できません。

  • 誰もが「一般」インターネット接続とNordVPN接続を使用したい複数のユーザーを持っている場合は、その名前空間を作成し、ここでNordVPNを実行し、ユーザーに他のアプリケーションを実行できる端末を提供するスクリプトを作成できます。あるいは、Webブラウザなどのアプリケーションもこの名前空間で実行されている可能性があります。このスクリプトはコマンドを置き換えますconnect

要件によっては、これを行う方法がさらにある場合があります。したがって、質問を編集し、要件/状況を説明してください。

名前空間を作成するにはroot権限が必要です。つまり、スクリプトをsetuid-rootに設定する必要があり(スクリプトにバグがある場合はセキュリティ上の問題になる可能性があります)、ユーザーsudoアクセスを許可する必要があるかもしれません。

答え3

この問題は、既存の全体的な設定、プロバイダの自己構成変更の可能性、サポートされている実際のVPNの種類、やや複雑な設定が必要かどうかに応じて、さまざまな方法で解決できると思います。 。

また、NordVPN サービス関連ソリューションの場合、サポートを依頼することもできます。これnordvpn は必ずしもOpenVPNを使用するわけではなく、IPSecまたはPPTP / L2TPを使用することを好むかもしれません。

ただし、NordVPN サービスと完全に互換性のある汎用 OpenVPN ソリューションと呼ぶことにおそらく最善のアプローチは、ポリシー ルーティングを少し変更して使用することです。

しかし、まずネームスペースに対するあなたの関心を見て、これらのネームスペースをどのように使用できるかについて私の考えを共有したいと思います。

もちろん、名前空間を使用すると、ユーザー間のネットワークを実際に分離することができます。その主な利点は、OpenVPNだけでなく、あらゆる種類のVPNの汎用ソリューションになることです。

ただし、多くのLinuxディストリビューションでは、これを設定するために必要なツールをインストールしないことがよくあります。問題の問題は、単にunshareorip netns exec コマンドを使用して解決されないようです。これは、そのプロセスだけがそのプロセスで新しい名前空間を表示できるためです。コマンドは、ユーザーの既存のセッション全体で実行されるのではなく、セッションで実行されます。

また、必要なツールをインストールして設定どおりにシステムを設定しても、同じ物理ネットワークデバイスを使用し、UNIXの場合は共有しながら、各ユーザーを自分のネットワークネームスペースに分割するようにシステムを慎重に設定する必要があります。 localhostで実行されるドメインソケットとサービス。ブリッジ(またはmacvlan)、サブネット設定、アドレス割り当て、NAT、およびその他の複雑な操作。これは可能かもしれませんが、単純ではなく、元の問題よりはるかに複雑だと思います。


したがって、ルーティング戦略アプローチに戻って私が知っている限り、最も単純な実行可能なソリューションである基本的なソリューションは、おそらく最も一般的なユースケースに十分であるか、より複雑なバリエーションを試みる前の開始点で十分です。別々のUIDを使用して、各ユーザートンネルのルーティングテーブルをユーザーのUIDベースのルーティングポリシーで照会します。

次の主な機能があります。

  • (かなり)標準バージョンのOpenVPNが必要です(つまり、プロバイダはあまりカスタマイズされていません)。
  • iptables ユーザーのUID番号に基づいて関連トラフィックにタグを付けるには、コンパニオンルールが必要です。
  • 既存のファイアウォールまたはルーティングルールと組み合わせて使用​​する場合は、慎重な統合が必要になる場合があります。
  • ただし、sudoUID 0で実行されるため、ユーザーが実行するプロセスやsetuidコマンドまたはrootとして実行されるアプリケーションは認識されません。これらの状況の大部分は、一般的なデスクトップシナリオには当てはまりませんが、発生する可能性が高く、期待どおりに処理されません(つまり、トラフィックの対応する部分はVPNに入りません)。

2つのヘルパースクリプトを使用してすべてを処理できます。使用するもの渡すOpenVPN、その他の使用走る openvpnそれ自体。

標準のOpenVPNはこのipコマンドを使用してtun / tapデバイスを設定し、VPNプロバイダがプッシュしたパスをインストールします。問題は、基本的にipコマンドがシステム全体で使用されるため、すべてのユーザーを含むデフォルトのルーティングテーブルで実行されることです。

ただし、OpenVPNでは、適用する必要がある設定に対して異なるコマンドを指定できるため、さまざまip なパステーブルで機能するラッパーを提供できます。

これらの(仮称myip.sh)ラッパースクリプトは次のとおりです。

#!/bin/bash -

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"

real_ip_cmd=/sbin/ip

if [ $real_uid -ne 0 ] && [[ "$1" = ro* ]] ; then
    ! [ $2 ] && exec $real_ip_cmd "$1" list table $real_uid
    [[ "$2" =~ ^([adcfls]|rep).*$ ]] && exec $real_ip_cmd "$1" "$2" table $real_uid "${@:3}"
fi
exec $real_ip_cmd "$@"

最初の2行は、OpenVPNが実行されている実際のUIDを取得するために使用されます。このUIDをテーブルIDとして使用します。これにより、各ユーザーはVPNを起動したときに独自のルーティングテーブルを持つことになります。

このif-then-fiブロックは、route設定への呼び出しをキャプチャし(短縮されたが明確なキーワードを受け入れるipコマンド機能を模倣する)、openvpnに渡されたすべてのコマンドの前に、ユーザーtableの実際のUIDと同じIDを渡すオプションを追加します。他のすべてのipコマンド(コマンド以外のコマンドroute)は、影響を受けずに渡されます。

別のスクリプトは、openvpnユーザー生成トラフィックが異なるテーブルに従ってルーティングされるように、設定とともにコマンドをラップします。このラッパースクリプトの要旨は、プロバイダーの独自の構成ファイルに含めることができるため、よりシームレスな統合が可能です。これは、非対話型(起動時など)でVPNを設定したい場合に役立ちます。ただし、このラッパースクリプトを使用すると、構成ファイルを操作する必要がないため、このバージョンを表示することにしました。

したがって、単一のラッパースクリプトは次のようになります。

#!/bin/bash

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"
[ $real_uid -eq 0 ] && { echo "will not run for UID 0" >&2 ; exit 1; }

remove_tagging() {
        iptables -t mangle -D OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
        ip rule del fwmark $real_uid
        ip route flush table $real_uid
} 2>/dev/null

trap 'remove_tagging' EXIT

source <(ip route | sed "s/^/ip route add table ${real_uid} /")

(
ip -o monitor | grep -qm 1 '^[0-9]\+: tun[0-9]\+[[:blank:]]\+inet '
ip rule add fwmark $real_uid lookup $real_uid
iptables -t mangle -A OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
) &

openvpn --iproute myip.sh --config tunnel-config.ovpn

最初の3行はユーザーの実際のUIDを検索しようとし、取得できない場合は続行しないでください。

その後、スクリプトの終了時に実行される関数があります。この関数は、次のサブシェルによって行われた設定を削除します。

ただし、まず、現在のデフォルトのルーティングテーブル全体をユーザー用の他のテーブルにコピーします。

次にサブシェルを実行し、tunXOpenVPNがデバイスを設定するのを待ち、ルーティングルールとiptables同伴ルールを追加して、その時点からユーザーが生成したトラフィックを表示します。ユーザー名とパスワードを要求する必要がある場合は、フォアグラウンドで実行するにはOpenVPNが必要なため、バックグラウンドで実行します。

コマンドsource、サブシェル(パイプなしip -o monitor )、および機能は、remove_taggingVPN設定ファイルに(それぞれ)およびオプションとして含めることができる部分です。これにより、このラッパースクリプトが完全に削除されます。uproute-uproute-pre-down

最後に、実際のコマンドを実行し、ネットワークを設定するコマンドとしてopenvpn 独自のスクリプトを使用するように指示します。myip.sh


ipいくつかの変更が可能な方法は、代わりにルーティングルールでオプションで使用できるiproute2パッケージ(コマンド提供)の最新バージョンを使用することですuidrangefwmark

したがって、このバリアントはiptables コマンドを削除し、コマンドをコマンドip rule fwmark ..に置き換えますip rule uidrange ${real_uid}-${real_uid} lookup $real_uid(そのコマンドも同じですip rule del ..)。


特定のコマンド実行をサポートするもう1つの変形は、sudoUIDの代わりにユーザーグループ(GID)へのポリシールーティングに基づいていることです。これには追加の基本要件があります。

  • Ubuntuを含む多くのLinuxディストリビューションで一般的に使用されているユーザーの存在に対する一意のGID
  • sudo元のGID番号を保存するには、追加オプション(-g <user> -u rootまたは同等の設定)を使用して実行してください。sudoers

ただし、このクラスの外で実行されているユーザーのUID 0プロセスはまだ認識されていませんsudo


「UID 0プロセス」の問題を実際に解決するにはcgroupを使用できますが、もちろんここには他の要件があります。

  • iptables Ubuntu 14.04などのシステムでは、まだ利用できないiptables固有の特定の「cgroup」モジュールを使用して関連トラフィックを表示するためのコンパニオンルール
  • すでに存在する既存のcgroup設定と競合する可能性がある

cgroupを使用すると、簡単なスクリプトでnet-class-id設定をうまく処理できます。pam_exec.so

#!/bin/bash -e

uid=$(id -ru "${PAM_USER}")
mkdir -p /sys/fs/cgroup/net_cls/user/${uid} && echo $uid > /sys/fs/cgroup/net_cls/user/${uid}/net_cls.classid
echo $$ > /sys/fs/cgroup/net_cls/user/${uid}/cgroup.procs

次に、必要な設定ファイルに次の行を追加します/etc/pam.d

session optional    pam_exec.so /root/set-net-cls-id.sh

上記の行は、対話型サービス(コンソールログイン、デスクトップ環境など)を介して開始されたすべてのセッションを/etc/pam.d/common-session 処理するために既存のファイルに含めることができます。ssh

この設定では、iptables ラッパースクリプトで使用されるコマンドは次のようになります。

iptables -t mangle -A OUTPUT -m cgroup --cgroup $real_uid -j MARK --set-mark $real_uid

その削除コマンドはで-D置き換えられます-A

cgroupソリューションの可能なバリエーションは、を使用せずにcgroupを直接処理する機能をsystemd使用できるように統合することです。systemdpam_exec

ノートただし、このcgroup設定はUbuntu 14.04では正しく機能しません。これはユーザーセッションごとにcgroupを設定するために使用されるため、このソリューションで設定した設定を上書きするためです。むしろ、cat /proc/self/cgroup出力を解析して名前を簡単に取得できるセッションごとに動的に生成されたcgroupのclassid値を設定する必要があります。

関連情報