Apa yang Anda minta tidak ada. Inilah mengapa Anda tidak puas dengan jawaban yang Anda temukan (beberapa di antaranya, mungkin, milik saya):semuanya menyarankan solusi , bukan solusi asli, baik sederhana maupun rumit.
Mari saya jelaskan. Perutean di semua OS ditentukan oleh alamat tujuan:Anda mungkin memiliki beberapa rute, tetapi pilihan di antara mereka tidak didasarkan pada aplikasi yang meminta koneksi, tetapi hanya pada alamat tujuan. Berhenti penuh.
Biarkan saya memberi Anda contoh non-sepele. Ketika klien VPN telah membuat koneksi ke servernya, masih mungkin untuk merutekan koneksi ke situs tertentu, misalnya example.org, di luar VPN. Tetapi semua aplikasi yang mencoba menjangkau alamat khusus itu akan dialihkan ke luar VPN:Anda tidak dapat membuat beberapa aplikasi masuk ke 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 keduanya 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 ke koneksi tertentu melalui antarmuka yang sama dengan koneksi yang masuk:jika tidak, mereka akan dibuang karena tidak relevan ketika mencapai orang yang memulai koneksi. Ini adalah perutean sumber.
Cukup adil, bagaimana dengan koneksi yang kita mulai? Beberapa aplikasi memungkinkan Anda menentukan alamat pengikatan, 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 untuk 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 jahat dan jahat karena mereka tidak memungkinkan Anda menjalankan dua salinan dirinya secara bersamaan, masing-masing terikat ke alamat sumber yang berbeda. Dengan kata lain, meskipun berkat trik yang dirujuk di atas Anda dapat mewajibkan satu instance untuk mengikat ke alamat sumber pilihan Anda, Anda tidak dapat memiliki versi lain yang mengikat ke alamat sumber lain.
Ini menjelaskan mengapa kami menggunakan solusi:semuanya didasarkan pada ide yang sama, bahwa mereka bekerja dengan tumpukan jaringan terpisah dari komputer lainnya. Jadi Anda dapat memiliki, dalam urutan perkiraan kompleksitas yang menurun, VM, buruh pelabuhan, wadah, ruang nama. Di masing-masingnya Anda akan memiliki satu atau lebih tabel perutean, tetapi Anda dapat memiliki beberapa instance dari masing-masing (VM/dockers/containers/namespaces) dan Anda juga dapat menggabungkannya dengan bebas, masing-masing menjalankan aplikasinya sendiri seperti Firefox dengan senang hati dipisahkan dari yang lain.
Mungkin Anda masih tertarik dengan salah satu solusinya?
EDIT:
Solusi paling sederhana adalah ruang nama jaringan. Skrip di bawah ini menangani semua aspek yang diperlukan dari NNS:masukkan ke dalam file (Anda memilih nama Anda, saya biasanya menggunakan newns
, tetapi Anda melakukan apa pun yang Anda suka) di /usr/local/bin
, lalu 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 berfungsi, tetapi Anda dapat mengubahnya jika Anda ingin menggunakan yang lain), yang termasuk dalam namespace baru. Dari dalam xterm Anda dapat, jika mau, memulai vpn Anda, dan kemudian memulai permainan Anda. Anda dapat dengan mudah memeriksa apakah 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 IP publik Anda. Setelah menyiapkan VPN di xterm, Anda dapat memeriksa apakah IP publik Anda berbeda di jendela lain. Anda dapat membuka hingga 254 xterms, dengan 254 NNS yang berbeda, dan koneksi yang 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 "[email protected]"
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 mau, Anda bahkan dapat memulai seluruh desktop di dalam ruang nama jaringan baru, melalui
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 ruang nama agak bermasalah, bersabarlah.