あなたが求めているものが存在しません。これが、あなたが見つけた答えに不満を抱いている理由です(それらのいくつかは、おそらく私のものです)。それらすべては、単純なものでも複雑なものでも、真の解決策ではなく、回避策を提案しています。
説明させてください。すべてのOSでのルーティングは宛先アドレスによって決定されます。いくつかのルートがある場合がありますが、それらの間の選択は、接続を呼び出すアプリケーションに基づくのではなく、単に宛先アドレスに基づいています。フルストップ。
簡単な例を挙げましょう。VPNクライアントがそのサーバーへの接続を確立した後でも、VPNの外部の特定のサイト(example.orgなど)に接続をルーティングすることが可能です。ただし、その特別なアドレスに到達しようとするすべてのアプリケーションはVPNの外部にルーティングされます。他のアプリケーションがVPNの外部を通過する間、一部のアプリケーションはVPNを介してexample.orgにアクセスできません。
Linuxカーネルでは状況がより豊かになり、ソースルーティングが可能になります。これは、2つ以上のルーティングテーブルを持つことができ、それらの間の選択は宛先アドレスではなくソースアドレスに基づくことを意味します。
重要な例:私のPCには2つの外線があり、2つの異なるパブリックIPがあります。どちらのインターフェースからでも連絡できます。特定の接続への私の返信は、接続が届いたのと同じインターフェースを経由することが重要です。それ以外の場合は、接続を開始した人に到達したときに無関係として破棄されます。これはソースルーティングです。
十分に公平ですが、私たちが開始する接続はどうですか?opensshクライアントのように、一部のアプリではバインドアドレスを指定できます。
-b bind_address
接続のソースアドレスとしてローカルマシンのbind_addressを使用します。複数のアドレスを持つシステムでのみ役立ちます。
それらの場合、1つのインスタンスがVPNを通過する(たとえば、ルーティングテーブル1)一方で、別のインスタンスがVPNの外部に移動する(たとえば、ルーティングテーブル2)ことは問題ありません。しかし、Firefoxのような他のアプリは、特定のソースIPアドレスにバインドするのが非常に難しいだけでなく(非常にスマートな回避策についてはこちらを参照)、また、自分自身の2つのコピーを許可しないという意味で厄介です同時に実行され、それぞれが異なる送信元アドレスにバインドされます。つまり、上記のトリックのおかげで、1つのインスタンスに選択した送信元アドレスにバインドするように強制できますが、別のバージョンのインスタンスを他の送信元アドレスにバインドすることはできません。
これは、私たちが回避策を使用する理由を説明します。それらはすべて同じ考え方に基づいており、他のPCとは別のネットワークスタックで動作するということです。したがって、おおよその複雑さの順序で、VM、Docker、コンテナー、名前空間を持つことができます。それぞれに1つ以上のルーティングテーブルがありますが、それぞれのインスタンス(VM / dockers / containers / namespaces)を複数持つことができ、それらを自由に混ぜることができ、それぞれがFirefoxのような独自のアプリを実行して幸せに分離されています他のものから。
多分あなたはまだ回避策の1つに興味がありますか?
編集:
最も簡単な回避策は、ネットワーク名前空間です。以下のスクリプトは、NNSの必要なすべての側面を処理します。それをファイルに入れます(名前を選択します。通常はを使用しnewns
ますが、好きなことを行います)/usr/local/bin
。次にchmod 755 FILE_NAME
、次のように使用できます。
newns NAMESPACE_NAME start
newns NAMESPACE_NAME stop
xterm
新しいネームスペースに属するが開きます(これはxtermが機能するのが好きですが、他のものを使用したい場合は変更できます)。xterm内から、必要に応じてvpnを開始してから、ゲームを開始できます。次のコマンドを使用して、VPNを使用していることを簡単に確認できます。
wget 216.146.38.70:80 -O - -o /dev/null | cut -d" " -f6 | sed 's/<\/body><\/html>//'
パブリックIPを返します。xtermでVPNをセットアップした後、他のウィンドウでパブリックIPが異なることを確認できます。最大254個のxtermを開き、254個の異なるNNSと異なる接続を使用できます。
#!/bin/bash
#
# This script will setup an internal network 10.173.N.0/24; if this causes
# any conflict, change the statement below.
export IP_BASE=10.173
# It will open an xterm window in the new network namespace; if anything
# else is required, change the statement below.
export XTERM=/usr/bin/xterm
# The script will temporarily activate ip forwarding for you. If you
# do not wish to retain this feature, you will have to issue, at the
# end of this session, the command
# echo 0 > /proc/sys/net/ipv4/ip_forward
# yourself.
###############################################################################
WHEREIS=/usr/bin/whereis
# First of all, check that the script is run by root:
[ "root" != "$USER" ] && exec sudo $0 "$@"
if [ $# != 2 ]; then
echo "Usage $0 name action"
echo "where name is the network namespace name,"
echo " and action is one of start| stop| reload."
exit 1
fi
# Do we have all it takes?
IERROR1=0
IERROR2=0
IERROR3=0
export IP=$($WHEREIS -b ip | /usr/bin/awk '{print $2}')
if [ $? != 0 ]; then
echo "please install the iproute2 package"
IERROR1=1
fi
export IPTABLES=$($WHEREIS -b iptables | /usr/bin/awk '{print $2}')
if [ $? != 0 ]; then
echo "please install the iptables package"
IERROR2=1
fi
XTERM1=$($WHEREIS -b $XTERM | /usr/bin/awk '{print $2}')
if [ $? != 0 ]; then
echo "please install the $XTERM package"
IERROR3=1
fi
if [ IERROR1 == 1 -o IERROR2 == 1 -o IERROR3 == 1 ]; then
exit 1
fi
prelim() {
# Perform some preliminary setup. First, clear the proposed
# namespace name of blank characters; then create a directory
# for logging info, and a pid file in it; then determine
# how many running namespaces already exist, for the purpose
# of creating a unique network between the bridge interface (to
# be built later) and the new namespace interface. Lastly,
# enable IPv4 forwarding.
VAR=$1
export NNSNAME=${VAR//[[:space:]]}
export OUTDIR=/var/log/newns/$NNSNAME
if [ ! -d $OUTDIR ]; then
/bin/mkdir -p $OUTDIR
fi
export PID=$OUTDIR/pid$NNSNAME
# Find a free subnet
ICOUNTER=0
while true; do
let ICOUNTER=ICOUNTER+1
ip addr show | grep IP_BASE.$ICOUNTER.1 2>&1 1> /dev/null
if [ ! $? == 0 -a $ICOUNTER -lt 255 ]; then
export Nns=$ICOUNTER
break
elif [ ! $? == 0 -a $ICOUNTER -gt 254 ]; then
echo "Too many open network namespaces"
exit 1
fi
done
if [ $Nns == 1 ]; then
echo 1 > /proc/sys/net/ipv4/ip_forward
fi
}
start_nns() {
# Check whether a namespace with the same name already exists.
$IP netns list | /bin/grep $1 2> /dev/null
if [ $? == 0 ]; then
echo "Network namespace $1 already exists,"
echo "please choose another name"
exit 1
fi
# Here we take care of DNS
/bin/mkdir -p /etc/netns/$1
echo "nameserver 8.8.8.8" > /etc/netns/$1/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/netns/$1/resolv.conf
# The following creates the new namespace, the veth interfaces, and
# the bridge between veth1 and a new virtual interface, tap0.
# It also assigns an IP address to the bridge, and brings everything up
$IP netns add $1
$IP link add veth-a$1 type veth peer name veth-b$1
$IP link set veth-a$1 up
$IP tuntap add tap$1 mode tap user root
$IP link set tap$1 up
$IP link add br$1 type bridge
$IP link set tap$1 master br$1
$IP link set veth-a$1 master br$1
$IP addr add $IP_BASE.$Nns.1/24 dev br$1
$IP link set br$1 up
# We need to enable NAT on the default namespace
$IPTABLES -t nat -A POSTROUTING -j MASQUERADE
# This assigns the other end of the tunnel, veth2, to the new
# namespace, gives it an IP address in the same net as the bridge above,
# brings up this and the (essential) lo interface, sets up the
# routing table by assigning the bridge interface in the default namespace
# as the default gateway, creates a new terminal in the new namespace and
# stores its pid for the purpose of tearing it cleanly, later.
$IP link set veth-b$1 netns $1
$IP netns exec $1 $IP addr add $IP_BASE.$Nns.2/24 dev veth-b$1
$IP netns exec $1 $IP link set veth-b$1 up
$IP netns exec $1 $IP link set dev lo up
$IP netns exec $1 $IP route add default via $IP_BASE.$Nns.1
$IP netns exec $1 su -c $XTERM $SUDO_USER &
$IP netns exec $1 echo "$!" > $PID
}
stop_nns() {
# Check that the namespace to be torn down really exists
$IP netns list | /bin/grep $1 2>&1 1> /dev/null
if [ ! $? == 0 ]; then
echo "Network namespace $1 does not exist,"
echo "please choose another name"
exit 1
fi
# This kills the terminal in the separate namespace,
# removes the file and the directory where it is stored, and tears down
# all virtual interfaces (veth1, tap0, the bridge, veth2 is automatically
# torn down when veth1 is), and the NAT rule of iptables.
/bin/kill -TERM $(cat $PID) 2> /dev/null 1> /dev/null
/bin/rm $PID
/bin/rmdir $OUTDIR
$IP link set br$1 down
$IP link del br$1
$IP netns del $1
$IP link set veth-a$1 down
$IP link del veth-a$1
$IP link set tap$1 down
$IP link del tap$1
$IPTABLES -t nat -D POSTROUTING -j MASQUERADE
/bin/rm /etc/netns/$1/resolv.conf
/bin/rmdir /etc/netns/$1
}
case $2 in
start)
prelim "$1"
start_nns $NNSNAME
;;
stop)
prelim "$1"
stop_nns $NNSNAME
;;
reload)
prelim "$1"
stop_nns $NNSNAME
prelim "$1"
start_nns $NNSNAME
;;
*)
# This removes the absolute path from the command name
NAME1=$0
NAMESHORT=${NAME1##*/}
echo "Usage:" $NAMESHORT "name action,"
echo "where name is the name of the network namespace,"
echo "and action is one of start|stop|reload"
;;
esac
必要に応じて、新しいネットワーク名前空間内でデスクトップ全体を起動することもできます。
sudo startx -- :2
次にAlt+ Ctrl+ を使用して検索できますFn。FnはF1、F2、...のいずれかです。
注意点を1つ追加する必要があります。名前空間内のDNS処理は少しバグが多いので、しばらくお待ちください。