Apa yang Anda minta tidak ada. Inilah sebabnya mengapa Anda tidak puas dengan jawaban yang Anda temukan (beberapa dari mereka, mungkin, menjadi milik saya): semuanya telah menyarankan solusi , bukan solusi asli, baik sederhana atau kompleks.
Biarkan saya jelaskan. Routing di semua OS ditentukan oleh alamat tujuan: Anda mungkin memiliki beberapa rute, tetapi pilihan di antara mereka tidak didasarkan pada aplikasi yang memanggil koneksi, tetapi hanya berdasarkan alamat tujuan. Titik.
Biarkan saya memberi Anda contoh non-sepele. Ketika klien VPN telah membuat koneksi ke servernya, masih mungkin untuk merutekan koneksi ke situs yang diberikan, misalnya example.org, di luar VPN. Tetapi semua aplikasi yang mencoba mencapai alamat khusus itu akan dialihkan ke luar VPN: Anda tidak dapat memiliki beberapa aplikasi yang menuju example.org melalui VPN sementara aplikasi lain lewat di luar VPN.
Situasi menjadi lebih kaya dengan kernel Linux, yang memungkinkan perutean sumber: ini berarti Anda dapat memiliki dua atau lebih tabel perutean, dan pilihan di antara mereka didasarkan pada alamat sumber, bukan alamat tujuan.
Contoh non-sepele: pc saya memiliki dua jalur luar, dengan dua IP publik yang berbeda. Itu dapat dihubungi melalui salah satu antarmuka, dan penting bahwa balasan saya untuk koneksi yang diberikan pergi melalui antarmuka yang sama bahwa koneksi masuk melalui: jika tidak, mereka akan dibuang sebagai tidak relevan ketika mereka mencapai orang yang memulai koneksi. Ini adalah sumber routing.
Cukup adil, bagaimana dengan koneksi yang kita mulai? Beberapa aplikasi memungkinkan Anda menentukan alamat bind, seperti klien openssh :
-b bind_address
Gunakan bind_address pada mesin lokal sebagai alamat sumber koneksi. Hanya berguna pada sistem dengan lebih dari satu alamat.
Bagi mereka, tidak ada masalah dalam memiliki satu instance melalui VPN (katakanlah, tabel routing 1) sementara instance lain akan keluar dari VPN (katakanlah tabel routing 2). Tetapi aplikasi lain, seperti Firefox, tidak hanya terkenal sulit untuk diikat ke alamat ip sumber tertentu (tetapi lihat di sini untuk solusi yang sangat cerdas), tetapi juga kejam dan jahat karena mereka tidak akan memungkinkan Anda untuk memiliki dua salinan sendiri berjalan secara bersamaan, masing-masing terikat ke alamat sumber yang berbeda. Dengan kata lain, meskipun berkat trik yang dirujuk di atas Anda dapat mewajibkan satu contoh untuk mengikat ke alamat sumber pilihan Anda, maka Anda tidak dapat memiliki versi lain mengikat ke alamat sumber lain.
Ini menjelaskan mengapa kami menggunakan solusi: mereka semua didasarkan pada ide yang sama, bahwa mereka bekerja dengan tumpukan jaringan yang terpisah dari sisa pc. Jadi Anda dapat memiliki, dalam mengurangi urutan kompleksitas, VM, buruh pelabuhan, wadah, ruang nama. Di masing-masing dari mereka Anda akan memiliki satu atau lebih tabel routing, tetapi Anda dapat memiliki beberapa contoh masing-masing (VM / buruh pelabuhan / wadah / ruang nama) dan Anda juga dapat mencampurnya secara bebas, masing-masing dari mereka menjalankan aplikasi sendiri seperti Firefox dipisahkan dengan senang hati dari yang lain.
Mungkin Anda masih tertarik dengan salah satu solusinya?
EDIT:
Solusi paling sederhana adalah namespace jaringan. Script di bawah ini menangani semua aspek yang diperlukan dari NNS: memasukkannya ke dalam file (Anda memilih nama Anda, saya biasanya menggunakan newns
, tetapi Anda melakukan apa pun yang Anda inginkan) di /usr/local/bin
, kemudian chmod 755 FILE_NAME
, dan Anda dapat menggunakannya sebagai berikut:
newns NAMESPACE_NAME start
newns NAMESPACE_NAME stop
Ini akan membuka xterm
untuk Anda (itu karena saya suka xterm bekerja, tetapi Anda dapat mengubahnya jika Anda ingin menggunakan yang lain), yang termasuk dalam namespace baru. Dari dalam xterm, Anda dapat, jika ingin, memulai vpn Anda, dan kemudian memulai gim Anda. Anda dapat dengan mudah memeriksa bahwa Anda menggunakan VPN melalui perintah berikut:
wget 216.146.38.70:80 -O - -o /dev/null | cut -d" " -f6 | sed 's/<\/body><\/html>//'
yang mengembalikan Anda IP publik Anda. Setelah mengatur VPN di xterm, Anda dapat memeriksa bahwa IP publik Anda berbeda di windows Anda yang lain. Anda dapat membuka hingga 254 xterms, dengan 254 NNSes berbeda, dan koneksi berbeda.
#!/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
Jika Anda mau, Anda bahkan dapat memulai seluruh desktop di dalam namespace jaringan baru, dengan cara
sudo startx -- :2
maka Anda dapat mencarinya menggunakan Alt+ Ctrl+ Fn, di mana Fn adalah salah satu dari F1, F2, ....-
Saya perlu menambahkan satu peringatan: penanganan DNS di dalam namespace agak buggy, bersabarlah.